/*
A basic extension of the com.sun.java.swing.JApplet class
*/

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import com.symantec.itools.swing.models.StringTableModel;
import java.util.Vector;
import com.sun.java.swing.JLabel;
import com.sun.java.swing.JTextField;
import com.sun.java.swing.JScrollPane;
import com.sun.java.swing.JButton;
import symantec.itools.util.Timer;
import com.sun.java.swing.JPanel;
import com.sun.java.swing.JTable;

public class JApplet1 extends JApplet
{
	public void init()
	{
		// Take out this line if you don't use symantec.itools.net.RelativeURL or symantec.itools.awt.util.StatusScroller
//		symantec.itools.lang.Context.setApplet(this);
		
		// This line prevents the "Swing: checked access to system event queue" message seen in some browsers.
		getRootPane().putClientProperty("defeatSystemEventQueueCheck", Boolean.TRUE);
		
		// This code is automatically generated by Visual Cafe when you add
		// components to the visual environment. It instantiates and initializes
		// the components. To modify the code, only use code syntax that matches
		// what Visual Cafe can generate, or Visual Cafe may be unable to back
		// parse your Java file into its visual environment.
		//{{INIT_CONTROLS
		getContentPane().setLayout(null);
		setSize(575,551);
		JScrollPane1.setOpaque(true);
		getContentPane().add(JScrollPane1);
		JScrollPane1.setBounds(140,15,400,450);
		JTable1.setModel(stringTableModel1);
		JScrollPane1.getViewport().add(JTable1);
		JTable1.setBounds(0,0,397,447);
		//$$ stringTableModel1.move(12,432);
		JPanel1.setLayout(new GridLayout(12,1,0,0));
		getContentPane().add(JPanel1);
		JPanel1.setBounds(12,12,120,468);
		JButton1.setText("Do!");
		JButton1.setActionCommand("Do!");
		JPanel1.add(JButton1);
		JButton1.setBounds(0,0,120,39);
		JPanel2.setLayout(new BorderLayout(0,0));
		JPanel1.add(JPanel2);
		JPanel2.setBounds(0,39,120,39);
		JLabel1.setText("Term 1");
		JPanel2.add(BorderLayout.NORTH,JLabel1);
		JLabel1.setBounds(0,0,120,15);
		JPanel2.add(BorderLayout.CENTER,JTextField1);
		JTextField1.setBounds(0,15,120,24);
		JPanel3.setLayout(new BorderLayout(0,0));
		JPanel1.add(JPanel3);
		JPanel3.setBounds(0,78,120,39);
		JLabel2.setText("Term 2");
		JPanel3.add(BorderLayout.NORTH, JLabel2);
		JLabel2.setBounds(0,0,120,15);
		JPanel3.add(BorderLayout.CENTER,JTextField2);
		JTextField2.setBounds(0,15,120,24);
		JPanel4.setLayout(new BorderLayout(0,0));
		JPanel1.add(JPanel4);
		JPanel4.setBounds(0,117,120,39);
		JLabel3.setText("Term 3");
		JPanel4.add(BorderLayout.NORTH, JLabel3);
		JLabel3.setBounds(0,0,120,15);
		JPanel4.add(BorderLayout.CENTER, JTextField3);
		JTextField3.setBounds(0,15,120,24);
		JPanel5.setLayout(new BorderLayout(0,0));
		JPanel1.add(JPanel5);
		JPanel5.setBounds(0,156,120,39);
		JLabel4.setText("Term 4");
		JPanel5.add(BorderLayout.NORTH, JLabel4);
		JLabel4.setBounds(0,0,120,15);
		JPanel5.add(BorderLayout.CENTER, JTextField4);
		JTextField4.setBounds(0,15,120,24);
		JPanel6.setLayout(new BorderLayout(0,0));
		JPanel1.add(JPanel6);
		JPanel6.setBounds(0,195,120,39);
		JLabel5.setText("Term 5");
		JPanel6.add(BorderLayout.NORTH, JLabel5);
		JLabel5.setBounds(0,0,120,15);
		JPanel6.add(BorderLayout.CENTER, JTextField5);
		JTextField5.setBounds(0,15,120,24);
		JPanel7.setLayout(new BorderLayout(0,0));
		JPanel1.add(JPanel7);
		JPanel7.setBounds(0,234,120,39);
		JLabel6.setText("Result");
		JPanel7.add(BorderLayout.NORTH, JLabel6);
		JLabel6.setBounds(0,0,120,15);
		JPanel7.add(BorderLayout.CENTER, JTextField6);
		JTextField6.setBounds(0,15,120,24);
		JButton2.setText("Clear Table");
		JButton2.setActionCommand("Do!");
		JPanel1.add(JButton2);
		JButton2.setBounds(0,273,120,39);
		JProgressBar1.setMaximum(1000);
		getContentPane().add(JProgressBar1);
		JProgressBar1.setBounds(12,516,528,16);
		JLabel7.setText("jlabel");
		getContentPane().add(JLabel7);
		JLabel7.setBounds(12,492,252,24);
		//}}
	
		//{{REGISTER_LISTENERS
		SymAction lSymAction = new SymAction();
		JButton1.addActionListener(lSymAction);
		JButton2.addActionListener(lSymAction);
		//}}
	}

	//{{DECLARE_CONTROLS
	com.sun.java.swing.JScrollPane JScrollPane1 = new com.sun.java.swing.JScrollPane();
	com.sun.java.swing.JTable JTable1 = new com.sun.java.swing.JTable();
	com.symantec.itools.swing.models.StringTableModel stringTableModel1 = new com.symantec.itools.swing.models.StringTableModel();
	com.sun.java.swing.JPanel JPanel1 = new com.sun.java.swing.JPanel();
	com.sun.java.swing.JButton JButton1 = new com.sun.java.swing.JButton();
	com.sun.java.swing.JPanel JPanel2 = new com.sun.java.swing.JPanel();
	com.sun.java.swing.JLabel JLabel1 = new com.sun.java.swing.JLabel();
	com.sun.java.swing.JTextField JTextField1 = new com.sun.java.swing.JTextField();
	com.sun.java.swing.JPanel JPanel3 = new com.sun.java.swing.JPanel();
	com.sun.java.swing.JLabel JLabel2 = new com.sun.java.swing.JLabel();
	com.sun.java.swing.JTextField JTextField2 = new com.sun.java.swing.JTextField();
	com.sun.java.swing.JPanel JPanel4 = new com.sun.java.swing.JPanel();
	com.sun.java.swing.JLabel JLabel3 = new com.sun.java.swing.JLabel();
	com.sun.java.swing.JTextField JTextField3 = new com.sun.java.swing.JTextField();
	com.sun.java.swing.JPanel JPanel5 = new com.sun.java.swing.JPanel();
	com.sun.java.swing.JLabel JLabel4 = new com.sun.java.swing.JLabel();
	com.sun.java.swing.JTextField JTextField4 = new com.sun.java.swing.JTextField();
	com.sun.java.swing.JPanel JPanel6 = new com.sun.java.swing.JPanel();
	com.sun.java.swing.JLabel JLabel5 = new com.sun.java.swing.JLabel();
	com.sun.java.swing.JTextField JTextField5 = new com.sun.java.swing.JTextField();
	com.sun.java.swing.JPanel JPanel7 = new com.sun.java.swing.JPanel();
	com.sun.java.swing.JLabel JLabel6 = new com.sun.java.swing.JLabel();
	com.sun.java.swing.JTextField JTextField6 = new com.sun.java.swing.JTextField();
	com.sun.java.swing.JButton JButton2 = new com.sun.java.swing.JButton();
	javax.swing.JProgressBar JProgressBar1 = new javax.swing.JProgressBar();
	com.sun.java.swing.JLabel JLabel7 = new com.sun.java.swing.JLabel();
	//}}

	class SymAction implements java.awt.event.ActionListener
	{
		public void actionPerformed(java.awt.event.ActionEvent event)
		{
			Object object = event.getSource();
			if (object == JButton1)
			   JButton1_actionPerformed(event);
			else if (object == JButton2)
				JButton2_actionPerformed(event);
			
			
			
		}
	}

	void JButton1_actionPerformed(java.awt.event.ActionEvent event)
	{
	    final SwingWorker worker = new SwingWorker() {
	        public Object construct() {
	            calc();
	            return(null);
	        }
	    };
	}
	
	void calc()
	{
	    ComparableVector values = new ComparableVector(5);
	    if (!JTextField1.getText().equals("")) values.addElement(new Rational(Integer.parseInt(JTextField1.getText())));
	    if (!JTextField2.getText().equals("")) values.addElement(new Rational(Integer.parseInt(JTextField2.getText())));
	    if (!JTextField3.getText().equals("")) values.addElement(new Rational(Integer.parseInt(JTextField3.getText())));
	    if (!JTextField4.getText().equals("")) values.addElement(new Rational(Integer.parseInt(JTextField4.getText())));
	    if (!JTextField5.getText().equals("")) values.addElement(new Rational(Integer.parseInt(JTextField5.getText())));
        values.sort();
	    
	    ComparableVector expressions = null;
	    if (values.size() > 0) try {
	        JLabel7.setText("Calculating Expressions ...");
	        SetBar(values.size());
	        expressions = findAllExpressions(values);
	        JLabel7.setText("Simplifying Expressions ...");
	        simplify(expressions);
	        JLabel7.setText("Sorting Expressions ...");
    	    expressions.sort();
	        JLabel7.setText("Removing Duplicate Expressions ...");
	        expressions.prune();
  	        JLabel7.setText("Building Table ...");
	    } catch (BadOperatorException e) {
	    }

	    int lcv;
	    Expression a;
        Rational goal = null;
	    if (!JTextField6.getText().equals("")) goal = new Rational(Integer.parseInt(JTextField6.getText()));
	    JTable1.setVisible(false);
    	for (lcv=0;lcv<expressions.size();lcv++) {
	        a = (Expression)expressions.elementAt(lcv);
	        if ((goal == null) || (a.getValue().equals(goal)))
    		    stringTableModel1.addRow(a.toString()+","+a.getValue().toString());
        }
	    stringTableModel1.setColumnHeaders("Expressions,Values");
	    JTable1.setVisible(true);
	    JProgressBar1.setValue(JProgressBar1.getMaximum());
        JLabel7.setText("Done.");

	}
	
	void SetBar(int sz) {
	    JProgressBar1.setMinimum(0);
	    if (sz == 0) JProgressBar1.setMaximum(1);
	    else if (sz == 1) JProgressBar1.setMaximum(1);
	    else if (sz == 2) JProgressBar1.setMaximum(6);
	    else if (sz == 3) JProgressBar1.setMaximum(108);
	    else if (sz == 4) JProgressBar1.setMaximum(3240);
	    else if (sz == 5) JProgressBar1.setMaximum(63505);
	    else JProgressBar1.setMaximum(sz);
	    JProgressBar1.setValue(0);
 	    JProgressBar1.setStringPainted(true);
	}
	
	void incBar() {
	    JProgressBar1.setValue(JProgressBar1.getValue()+1);
	}
	
	void simplify(ComparableVector expressions) {
	    Expression a;
	    int lcv;
	    for (lcv=0;lcv<expressions.size();lcv++) {
	        a = (Expression)expressions.elementAt(lcv);
	        a.simplify();
	    }
	}
	
    ComparableVector findAllExpressions(Vector values) throws BadOperatorException
    {   
        Rational r;
        ComparableVector answer = new ComparableVector();
        if (values.size() == 1) {
            r = (Rational)values.elementAt(0);
            Expression e = new Expression(r);
            answer.addElement(e);
        } else {
            Vector possibleSplits = splitVector(values);
            possibleSplits.removeElementAt(0);
            possibleSplits.removeElementAt(0);
            while (possibleSplits.size() > 0) {
                Vector left = (Vector)possibleSplits.elementAt(0);
                Vector right = (Vector)possibleSplits.elementAt(1);
                possibleSplits.removeElementAt(0);
                possibleSplits.removeElementAt(0);
                Vector subExpressions1 = findAllExpressions(left);
                Vector subExpressions2;
                boolean symmetric = identical(left,right);
                
                if (symmetric)
                    subExpressions2 = (Vector)subExpressions1.clone();
                else
                    subExpressions2 = findAllExpressions(right);
                    
                int lcv; int lcv2;
                for (lcv=0;lcv<subExpressions1.size();lcv++) for (lcv2=0;lcv2<subExpressions2.size();lcv2++) {
                    Expression s1 = (Expression)subExpressions1.elementAt(lcv);
                    Expression s2 = (Expression)subExpressions2.elementAt(lcv2);
                    answer.addElement(new Expression(s1,ArithOperator.ADD,s2));
                    incBar();
                    answer.addElement(new Expression(s1,ArithOperator.SUB,s2));
                    incBar();
                    if (!symmetric) {
                        answer.addElement(new Expression(s2,ArithOperator.SUB,s1));
                        incBar();
                    }
                    answer.addElement(new Expression(s1,ArithOperator.MUL,s2));
                    incBar();
                    answer.addElement(new Expression(s1,ArithOperator.DIV,s2));
                    incBar();
                    if (!symmetric) {
                        answer.addElement(new Expression(s2,ArithOperator.DIV,s1));
                        incBar();
                    }
                }
            }
        }
        return(answer);
    }
    
    Vector splitVector(Vector values) 
    {
        Vector answer = new Vector();
        if (values.size() == 0) {
            answer.addElement(new Vector(5));
            answer.addElement(new Vector(5));
        } else {
            Vector subVector = vecCopy(values);
            subVector.removeElementAt(0);
            Vector subSplit = splitVector(subVector);
            
            while (subSplit.size() > 0) {
                Vector term1 = (Vector)subSplit.elementAt(0);
                Vector term2 = (Vector)subSplit.elementAt(1);
                subSplit.removeElementAt(0);
                subSplit.removeElementAt(0);

                term1.insertElementAt(values.elementAt(0), 0);
                answer.addElement(vecCopy(term1));
                term1.removeElementAt(0);
                answer.addElement(vecCopy(term2));
                if (!identical(term1,term2)) {
                    term2.insertElementAt(values.elementAt(0), 0);
                    answer.addElement(term1);
                    answer.addElement(term2);
                }
            }
        }
        return(answer);
    }
    
    Vector vecCopy(Vector v) {
        Vector answer = new Vector(v.size());
        int lcv;
        for (lcv=0;lcv<v.size();lcv++)
            answer.addElement(v.elementAt(lcv));
        return(answer);
    }
    

	void JButton2_actionPerformed(java.awt.event.ActionEvent event)
	{
		while (stringTableModel1.size() > 0)
		    stringTableModel1.removeRow(0);
	    stringTableModel1.setColumnHeaders("Expressions,Values");
	}
	
	boolean identical(Vector a, Vector b) {
	    if (a.size() != b.size())
	        return(false);
	    else {
	        int lcv;
	        boolean answer = true;
	        for (lcv=0;answer && (lcv < a.size());lcv++)
	            if (!a.elementAt(lcv).equals(b.elementAt(lcv)))
	                answer = false;
            return answer;
	    }
	}
		
}
