
/*

	This Applet is written by Jan Struyf
	URL: http://ace.ulyssis.student.kuleuven.ac.be/~jeans
	EMail: jan.struyf@student.kuleuven.ac.be
	Post:	Jan Struyf, Hoogstraat 47, 3360 Bierbeek, BELGIUM

	You can do anything with it, if you leave this comment field unmodified.
	If you want to place this Applet on your homepage (in case your that stupid)
	please add a link like this one:
	
	<A HREF="http://ace.ulyssis.student.kuleuven.ac.be/~jeans/">The Authors Homepage</A>
	
*/

import java.awt.*;
import java.applet.Applet;
import java.util.Vector;

public class ExtendedDemoApplet extends Applet {
    Button kbt, pbt;
    TextField fldstr, kstr, pstr;
    List mlist, clist;
	
    public void newEntry(Panel a, TextField t, String s) {
	  Panel p = new Panel();
	  p.setLayout(new BorderLayout());
	  Label l = new Label(s);
	  p.add("West",l);
	  p.add("Center",t);
	  a.add(p);
    }

    public int fromString(String intvl, int def) {
		int betw, len, ctr;
		char ch;
		betw = 0;
		len = intvl.length();
		for (ctr = 0; ctr < len; ctr++) {
			betw *= 10;
			ch = intvl.charAt(ctr);
			if (ch < '0' || ch > '9') return def;
			betw += (int)(ch-'0');
		}
		return betw;
    }

    public int[] parseString(String vl) {
		int[] res;
		int ctr, num = 0, prev, till;
		String intvl;
		for (ctr = 0; ctr < vl.length(); ctr++) 
			if (vl.charAt(ctr) == ',') num++;
		res = new int[num+1];
		num = 0; prev = 0;
		for (ctr = 0; ctr < vl.length(); ctr++) {
			if (vl.charAt(ctr) == ',') {
				while (prev < vl.length() && vl.charAt(prev) == ' ') prev++;
				till = ctr;
				while (till > 0 && vl.charAt(till) == ' ') till--;
				intvl = vl.substring(prev,till);
				res[num++] = fromString(intvl,0);
				prev = ctr+1;
			}
		}
		while (prev < vl.length() && vl.charAt(prev) == ' ') prev++;
		intvl = vl.substring(prev,vl.length());
		res[num] = fromString(intvl,0);
		return res;	
    }

    public void init() {
		setLayout(new BorderLayout());

	//Create lines
		Panel p3 = new Panel();		
		p3.setLayout(new GridLayout(3,0));
		p3.add(new Label("p:"));
		p3.add(new Label("k:"));
		p3.add(new Label("p(x):"));
	//Create behind lines
		Panel p1 = new Panel();		
		p1.setLayout(new GridLayout(3,0));

		fldstr = new TextField("3");
		p1.add(fldstr);

		Panel p2 = new Panel();
		p2.setLayout(new BorderLayout());
		kstr = new TextField("2");
		p2.add("Center",kstr);
		kbt = new Button("Calculate");
		p2.add("East",kbt);
		p1.add(p2);

		Panel p4 = new Panel();
		p4.setLayout(new BorderLayout());
		pstr = new TextField("");
		p4.add("Center",pstr);
		pbt = new Button("Calculate");
		p4.add("East",pbt);
		p1.add(p4);


		Panel p5 = new Panel();
		p5.setLayout(new BorderLayout());
		p5.add("West",p3);
		p5.add("Center",p1);
		
		Panel p7 = new Panel();
		p7.setLayout(new GridLayout(2,0));

		Panel p6 = new Panel();
		p6.setLayout(new BorderLayout());
		Label l1 = new Label("Powers of Alfa");
		p6.add("North",l1);
		mlist = new List();
		p6.add("Center",mlist);
		p7.add(p6);

		Panel p8 = new Panel();
		p8.setLayout(new BorderLayout());
		Label l2 = new Label("Cyclotomics");
		p8.add("North",l2);
		clist = new List();
		p8.add("Center",clist);
		p7.add(p8);

		setLayout(new BorderLayout());
		add("North",p5);
		add("Center",p7);		

      	validate();
    }

    public String spaceString(int len) {
		char[] str = new char[len];
		for (int ctr = 0; ctr < len; ctr++) str[ctr] = ' ';
		return new String(str);
    }

    public void addthem(ExtendedGaloisField field) throws GaloisException {
		String d1, mres;
		int ctr;
		for (ctr = 0; ctr < field.getCardinality(); ctr++) {
			mres = "";

			field.setDisplayMode(GaloisField.ALFAPOWER);
			d1 = field.valueString(ctr);
			mres += d1 + "  =  " /*+ spaceString(20-d1.length())*/;

			field.setDisplayMode(GaloisField.POLYNOMIAL);	
			d1 = field.valueString(ctr);
			mres += d1 + "  =  ";

			field.setDisplayMode(GaloisField.POLYCOEFS);	
			d1 = field.valueString(ctr);
			mres += d1;


			mlist.addItem(mres);
		}		
		Vector res = field.getBase().getAllCyclotomics(field.getCardinality()-1);
		for (ctr = 0; ctr < res.size(); ctr++) {
			int[] mycyclo = (int[])res.elementAt(ctr);
			String mystr = "{";
			for (int tel = 0; tel < mycyclo.length; tel++) {
				if (tel != 0) mystr += ", " + mycyclo[tel];
				else mystr += String.valueOf(mycyclo[tel]);
			}
			mystr += "}";
			if (mycyclo.length > 0) {
				GaloisPolynomial minpoly = field.getMinimalPolynomial(mycyclo[0]+1,'x');
				mystr += "    " +minpoly;
			}
			clist.addItem(mystr);
		}
    }

    public boolean action(Event e, Object arg) {
	  int num;
        Object target = e.target;
	  String tomany;
	  ExtendedGaloisField extfld = null;
	  GaloisField field;
	  GaloisPolynomial px;

	  if (target == kbt) {
		num = fromString(fldstr.getText(),2);
		if (num <= 1) num = 2;

		try {

		field = new GaloisField(num);

		int k = fromString(kstr.getText(),1);
		if (k < 1) k = 2;

		mlist.delItems(0,mlist.countItems()-1);
		clist.delItems(0,clist.countItems()-1);
		
			if (k == 1) {
				pstr.setText("/");
			} else {
				if (Math.pow(num,k) > 1000) {
					tomany = "More than 1000 elements in GF("+num+"^"+k+")";
					mlist.addItem(tomany);
					clist.addItem(tomany);
				} else {
					extfld = new ExtendedGaloisField(field,'a',k); 
					px = extfld.getModuloPoly();
					pstr.setText(px.toString());		
					addthem(extfld);
				}
			}
		} catch (GaloisException ex) {
			mlist.addItem(ex.toString());
			clist.addItem(ex.toString());
		}	
		return true;
	  }
	  if (target == pbt) {
		num = fromString(fldstr.getText(),2);
		if (num <= 1) num = 2;

		try {

		field = new GaloisField(num);

		mlist.delItems(0,mlist.countItems()-1);
		clist.delItems(0,clist.countItems()-1);

			px = new GaloisPolynomial(pstr.getText(),'a',field);
			if (Math.pow(num,px.degree()) > 1000) {
				tomany = "More than 1000 elements in GF("+num+"^"+px.degree()+")";
				mlist.addItem(tomany);
				clist.addItem(tomany);
			} else {
				extfld = new ExtendedGaloisField(px); 
				kstr.setText(String.valueOf(px.degree()));		
				addthem(extfld);
			}
		} catch (GaloisException ex) {			
			mlist.addItem(ex.toString());
			clist.addItem(ex.toString());
		}	

		return true;
	  }
        return false;
    }

}
