/*
 * ProteinIIApp.java
 *
 * Created on March 22, 2008, 6:09 PM
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */

/**
 *
 * @author roland
 */
import java.awt.*;
import java.awt.event.*;
import java.applet.*;

public class ProteinIIApp extends Applet
           implements ActionListener {
    /*******************************************
     * Data Members Used in the Applet Display *
     *******************************************/
    private TextField  // To accept user input
            SeqLength,          // To out sequence length
            Sum,                // To output sum of DIVW's
            InstIndex;          // To output II value
			   
	private TextArea Sequence;
			   
                      
    private Button Calculate,	// This button to initiate II calculation
                   Clear;       // Clear the panel to prepare for new input
    
    /*******************************************************
     * Some constants and tables used in the computations. *
     *******************************************************/
    private static final int numAminoAcids = 20;
    private static final double scalingFactor = 10.0;
    private static final double[][] DIVW_val = {
    {1.0, 1.0, 24.68, 24.68, 1.0, 1.0, 1.0, 13.34, 1.0, 1.0, 1.0, 1.0, -14.03,
      1.0, 1.0, -7.49, 1.0, -9.37, -14.03, 13.34}, // row W
     {24.68, 1.0, 33.6, 33.6, 1.0, 1.0, -6.54, 1.0, 1.0, 1.0, 20.26, 20.26,
      33.6, 1.0, 1.0, -6.54, 1.0, 1.0, 1.0, 20.26}, // row C
     {1.0, 1.0,  -1.88, 58.28, 24.68, 1.0, -6.54, 1.0, 1.0, -6.54, 1.0, 44.94,
      -1.88, 1.0, 1.0, 1.0, 44.94, 1.0, 13.34, 1.0}, // row M
     {-1.88, 1.0, 1.0, 1.0, 44.94, -9.37, 1.0, 24.68, 44.94, 1.0, 1.0, -1.88,
      -6.54, 24.68, 1.0, 1.0, 1.0, -9.37, 1.0, 1.0}, // row H
     {-9.37, 1.0, 44.94, 13.34, 13.34, 1.0, 1.0, 1.0, 1.0, -15.91, 24.68, 13.34,
      -7.49, 1.0, -6.54, 1.0, 1.0, -7.49, 24.68, 1.0}, // row Y
     {1.0, 1.0, 1.0, 1.0, 33.6, 1.0, 1.0, 1.0, 1.0, 1.0, 13.34, 20.26, 1.0,
      -14.03, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0}, // row F
     {1.0, -6.54, 1.0, 1.0, -6.54, -6.54, 20.26, 1.0, 1.0, 1.0, 20.26, 20.26, 1.0,
      1.0, 20.26, -6.54, 44.94, 1.0, 1.0, 1.0}, // row Q
     {-9.37, -1.88, 1.0, 1.0, 1.0, -14.03, -6.54, 1.0, 44.94, 1.0, 1.0, -1.88,
      -7.49, 24.68, 1.0, 1.0, 1.0, -14.03, 1.0, 1.0}, // row N
     {1.0, 1.0, 1.0, 13.34, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.88, 1.0, -7.49,
      44.94, -7.49, 1.0, 1.0, 1.0, 20.26}, // row I
     {58.28, 1.0, 1.0, 20.26, -6.54, 1.0, 20.26, 13.34, 1.0, 58.28, 1.0, 20.26,
      1.0, 1.0, 1.0, 1.0, 44.94, -7.49, 1.0, 1.0}, // row R
     {1.0, 1.0, 1.0, 1.0, 1.0, -6.54, 1.0, 1.0, 1.0, -6.54, 1.0, 1.0, -14.03,
      -7.49, 1.0, 1.0, 20.26, 1.0, 1.0, 1.0}, // row D
     {-1.88, -6.54, -6.54, 1.0, 1.0, 20.26, 20.26, 1.0, 1.0, -6.54, -6.54, 20.26,
      1.0, 1.0, 18.38, 20.26, 20.26, 1.0, 20.26, 1.0}, // row P
     {-14.03, 1.0, 1.0, 1.0, 1.0, 13.34, -6.54, -14.03, 1.0, 1.0, 1.0, 1.0, 1.0,
      1.0, 20.26, 1.0, 1.0, -7.49, 1.0, 1.0}, // row T
     {1.0, 1.0, 33.6, 1.0, 1.0, 1.0, 24.68, 1.0, -7.49, 33.6, 1.0, -6.54, 1.0,
      1.0, 1.0, -7.49, 1.0, -7.49, 1.0, -7.49}, // row K
     {-14.03, 44.94, 1.0, -6.54, 1.0, 1.0, 20.26, 1.0, 20.26, 1.0, 20.26, 20.26,
      1.0, 1.0, 33.6,1.0, 20.26, 1.0, 1.0, 1.0}, // row E
     {1.0, 1.0, 1.0, 1.0, -6.54, 1.0, 1.0, 1.0, 1.0, 1.0, -14.03, 20.26, -7.49,
      -1.88, 1.0, 1.0, 1.0, -7.49, 1.0, 1.0}, // row V
     {1.0, 33.6, 1.0, 1.0, 1.0, 1.0, 20.26, 1.0, 1.0, 20.26, 1.0, 44.94, 1.0,
      1.0, 20.26, 1.0, 20.26, 1.0, 1.0, 1.0}, // row S
     {13.34, 1.0, 1.0, 1.0, -7.49, 1.0, 1.0, -7.49, -7.49, 1.0, 1.0, 1.0, -7.49,
      -7.49, -6.54, 1.0, 1.0, 13.34, -7.49, 1.0}, // row G
     {1.0, 44.94, 1.0, -7.49, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -7.49, 20.26, 1.0,
      1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0}, // row A
     {24.68, 1.0, 1.0, 1.0, 1.0, 1.0, 33.6, 1.0, 1.0, 20.26, 1.0, 20.26, 1.0,
      -7.49, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0} /* row L */ };

    private static final char[] aminoLetters =
    {'W', 'C', 'M', 'H', 'Y', 'F', 'Q', 'N', 'I', 'R', 'D', 'P', 'T', 'K',
     'E', 'V', 'S', 'G', 'A', 'L'};
    
    /** Initialization method that will be called after the applet is loaded
     *  into the browser.
     */
    public void init() {
		
		
        setBackground(Color.white);	//Set white background
        setLayout(null);
        resize(575, 270);
        
        Sequence = new TextArea("", 5, 100, 1);
        Sequence.setBounds(165, 55, 400, 80);
		Sequence.setEditable(true);
        add(Sequence);
        SeqLength = new TextField();
        SeqLength.setBounds(165, 145, 165, 25);
        add(SeqLength);
      //  Sum = new TextField();
      //  Sum.setBounds(130, 95, 165, 25);
     //   add(Sum);
        InstIndex = new TextField();
        InstIndex.setBounds(165, 175, 165, 25);
        add(InstIndex);        
        Calculate = new Button("Calculate");
        Calculate.setBounds(165, 215, 100, 45);
        add(Calculate);
        Clear = new Button("Clear");
        Clear.setBounds (290, 215, 100, 45);
        add(Clear);
        
      //  Sequence.addActionListener(this);
        Calculate.addActionListener(this);
        Clear.addActionListener(this);
    }

    /** Method: paint
     * Purpose: Draw the outline of calculator *(this method can auto. draw when develop Applet, but it isn't Applet's method)
     * Parameters: Graphics
     * Returns: None */
    public void paint(Graphics graphic) {
        graphic.setColor(Color.black);
       graphic.drawRoundRect(0, 0, 574, 269, 15, 15);
		// graphic.drawRect(574, 249, 15, 15);
        graphic.setColor(Color.white);
        graphic.fillRoundRect(1, 1, 573, 268, 15, 15);
		//graphic.fillRect(573, 248, 15, 15);
        graphic.setColor(Color.black);
		Font f1 = new Font("Arial", Font.BOLD, 24);
		graphic.setFont(f1);
        graphic.drawString("Protein Instability Index Calculator", 85, 30);
		Font f2 = new Font("Arial", Font.BOLD, 14);
		graphic.setFont(f2);		
		
        graphic.drawString("Amino Acid Sequence", 10, 75);
        graphic.drawString("Sequence Length", 10, 165);
      //  graphic.drawString("Sum of DIVW's", 10, 105);
        graphic.drawString("Instability Index", 10, 195);
    }
    
    /** Method:	actionPerformed
     * Purpose:	Event-handling
     * Parameters: Action event
     * Returns: None */
    public void actionPerformed(ActionEvent event) {
        if (event.getSource() instanceof Button) {
            Button clickedButton = (Button) event.getSource();
            if (clickedButton == Calculate) {
                ComputeII();
            }
            else if (clickedButton == Clear) {
                ClearSequence();
            }
        }
    }
    
    /** Method: ClearSequence
     * Purpose:	Clear Sequence TextField objects
     * Parameters: None
     * Returns:	None */
    private void ClearSequence() {
        Sequence.setText("");
        InstIndex.setText("");
        SeqLength.setText("");
        Sum.setText("");
    }

    private void ComputeII() {
        String aminoSequence = Sequence.getText();
        aminoSequence = parseProtein(aminoSequence);
        int seqLength = aminoSequence.length();
        double DIVWsum = getDIVWsum(aminoSequence, seqLength);
        double II = (scalingFactor * DIVWsum) / (double)(seqLength);
        
        // Print the calculated values.
        printVals(aminoSequence, seqLength, DIVWsum, II);
    }
    
    private int getIndex(char letter) {
        for (int index = 0; index < numAminoAcids; ++index) {
            if (aminoLetters[index] == letter) {
                return index;
            }
        }
        return numAminoAcids;
    }
    
    private String parseProtein(String protein) {
        String returnString = "";
        char currentChar;
        protein = protein.toUpperCase();
        for (int i = 0; i < protein.length(); ++i) {
            currentChar = protein.charAt(i);
            if (getIndex(currentChar) != numAminoAcids) {
                //returnString.append(currentChar);
                returnString += currentChar;
            }
        }
        return returnString;
    }
    
    private double getDIVWsum(String protein, int sLength) {
        int row = 0, col = 0;
        double sum = 0.0;
        protein = protein.toUpperCase();
        for (int current = 0;  current < sLength - 1; ++current) {
            row = getIndex(protein.charAt(current));
            col = getIndex(protein.charAt(current + 1));
            sum += DIVW_val[row][col];
        }
        return sum;
    }
    
    private void printVals(String protein, int sLength, double sum, double instIndex) {
        
		String fs;
		//int perLine = 30, index;
        //String line;
        //print("\nhas length " + sLength);
        //print("\nThe sum of the DIVW's is " + sum +
        //        "\nThe instability index ( II ) for this protein is " + instIndex);
        //println("\n");
	if(sLength != 0){
		
		fs = String.format("%.2f", instIndex);
		
       // InstIndex.setText(String.valueOf(instIndex));
		InstIndex.setText(fs);
        SeqLength.setText(String.valueOf(sLength));
        Sum.setText(String.valueOf(sum));	
	}
		
		if(sLength == 0){
			Sequence.setText("Enter a sequence.");	
			InstIndex.setText("");
		}
    }
}
