// FixedWindow.java

// Written by Julian Devlin, 8/97, for the text book
// "Introduction to Probability," by Charles M. Grinstead & J. Laurie Snell

import java.applet.Applet;
import java.awt.*;

public class FixedWindow
	extends java.awt.Frame
{
	Panel dispArea;
	Panel controls;		// Panel for user controls
	Panel pPanel;
	
	TextField[][] P;
	Matrix pMat, wMat, xMat, zMat, cMat;
	float[][] rls;
	float[][] cls;
	Matrix rows, columns1, columns2;
	Label pLab, wLab;
	
	Button go;
	
	GridBagLayout gbl, pgbl, dgbl;
	GridBagConstraints cc, pcc, dcc;
	
	int size;
	
	Color labC;
	
	public FixedWindow(int s) {
		super("FixedVector");
		size = s;	
	}
		
	// Initialize applet
	public void init()
	{	
		go = new Button("Go");
		
		rls = new float[size][1];
		for (int i = 0; i < size; i++) {
			rls[i][0] = i + 1;	
		}
		
		cls = new float[1][size];
		for (int i = 0; i < size; i++) {
			cls[0][i] = i + 1;	
		}
		
		if (size == 5) {
			P = new TextField[5][5];
			P[0][0] = new TextField("0", 4);
			P[0][1] = new TextField("1", 4);
			P[0][2] = new TextField("0", 4);
			P[0][3] = new TextField("0", 4);
			P[0][4] = new TextField("0", 4);
			P[1][0] = new TextField(".25", 4);
			P[1][1] = new TextField("0", 4);
			P[1][2] = new TextField(".75", 4);
			P[1][3] = new TextField("0", 4);
			P[1][4] = new TextField("0", 4);
			P[2][0] = new TextField("0", 4);
			P[2][1] = new TextField(".5", 4);
			P[2][2] = new TextField("0", 4);
			P[2][3] = new TextField(".5", 4);
			P[2][4] = new TextField("0", 4);
			P[3][0] = new TextField("0", 4);
			P[3][1] = new TextField("0", 4);
			P[3][2] = new TextField(".75", 4);
			P[3][3] = new TextField("0", 4);
			P[3][4] = new TextField(".25", 4);
			P[4][0] = new TextField("0", 4);
			P[4][1] = new TextField("0", 4);
			P[4][2] = new TextField("0", 4);
			P[4][3] = new TextField("1", 4);
			P[4][4] = new TextField("0", 4);
		}
		else {
			P = new TextField[size][size];
			for (int i = 0; i < size; i++) {
				for (int j = 0; j < size; j++) {
					P[i][j] = new TextField("0", 4);
				}
			}
		}
		
		
		pLab = new Label("P = ");
		pLab.setAlignment(Label.RIGHT);
		wLab = new Label("w = ");
		wLab.setAlignment(Label.RIGHT);
		
		labC = new Color(100, 0, 0);
		
		rows = new Matrix(rls);
		rows.setColor(labC);
		columns1 = new Matrix(cls);
		columns1.setColor(labC);
		columns2 = new Matrix(cls);
		columns2.setColor(labC);
		
		dispArea = new Panel();				// Set up window
		controls = new Panel();
		pPanel = new Panel();
		setLayout(new BorderLayout(5, 5));
		
		add("South", controls);
		add("Center", dispArea);
		
		pgbl = new GridBagLayout();
		pcc = new GridBagConstraints();
		pPanel.setLayout(pgbl);
		for (int r = 0; r < size; r++) {
			for (int c = 0; c < size; c++) {
				pcc.gridx = c;
				pcc.gridy = r;
				pgbl.setConstraints(P[r][c], pcc);
				pPanel.add(P[r][c]);
			}	
		}
		
		dgbl = new GridBagLayout();
		dcc = new GridBagConstraints();
		dispArea.setLayout(dgbl);
		dcc.fill = GridBagConstraints.BOTH;
		dcc.gridx = 0;
		dcc.gridy = size / 2;
		dcc.gridwidth = 2;
		dcc.gridheight = 1;
		dgbl.setConstraints(pLab, dcc);
		dispArea.add(pLab);
		
		dcc.gridx = 2;
		dcc.gridy = 1;
		dcc.gridwidth = 1;
		dcc.gridheight = size;
		dgbl.setConstraints(rows, dcc);
		dispArea.add(rows);
		
		dcc.gridx = 3;
		dcc.gridy = 0;
		dcc.gridwidth = size;
		dcc.gridheight = 1;
		dgbl.setConstraints(columns1, dcc);
		dispArea.add(columns1);
		
		dcc.gridx = 3;
		dcc.gridy = 1;
		dcc.gridwidth = size;
		dcc.gridheight = size;
		dgbl.setConstraints(pPanel, dcc);
		dispArea.add(pPanel);
		
		dcc.gridx = 0;
		dcc.gridy = size + 2;
		dcc.gridwidth = 2;	
		dcc.gridheight = 1;
		dgbl.setConstraints(wLab, dcc);
		dispArea.add(wLab);
		
		dcc.gridx = 3;
		dcc.gridy = 1 + size;
		dcc.gridwidth = size;
		dcc.gridheight = 1;
		dgbl.setConstraints(columns2, dcc);
		dispArea.add(columns2);
		
		pMat = new Matrix(P);
		
		xMat = Matrix.add(Matrix.subtract(Matrix.identity(size), pMat),
			Matrix.con(size, size));
		zMat = xMat.inverse();
		cMat = Matrix.con(1, size);
		wMat = Matrix.multiply(cMat, zMat);
		wMat.round(.0001f);
		
		dcc.gridx = 3;
		dcc.gridy = 2 + size;
		dcc.gridwidth = size;
		dcc.gridheight = 1;
		dgbl.setConstraints(wMat, dcc);
		dispArea.add(wMat);
		
		gbl = new GridBagLayout();
		controls.setLayout(gbl);
		
		cc = new GridBagConstraints();
		
		cc.gridx = 0;
		cc.gridy = 0;
		cc.gridwidth = 2;
		gbl.setConstraints(go, cc);
		controls.add(go);
		
		validate();
	}
	
	// Handle events
	public boolean handleEvent(Event evt)
	{
		String minStr, maxStr;
		if (evt.target instanceof Button)
		{
			if (evt.target == go && evt.id == Event.ACTION_EVENT)	// When button is clicked
			{
        		simulate();
        		return true;					// Generate correct number of tosses
			}
		}
		if (evt.id == Event.WINDOW_DESTROY) {
			hide();
			dispose();	
		}
		return super.handleEvent(evt);	// Handle other events as usual
	}
	
	// Calculate probabilities
    public void simulate()
    {	
    	dispArea.remove(wMat);
    	
    	pMat = new Matrix(P);
		float[][] qArr = pMat.toArray();
		float[][] rArr = wMat.toArray();
		float total;
		for (int r = 0; r < qArr.length; r++) {
			total = 0;
			for (int c = 0; c < qArr[0].length; c++) {
				total += qArr[r][c];
			}	
			for (int c = 0; c < qArr[0].length; c++) {
				qArr[r][c] = round(qArr[r][c] / total, .001f);
			}		
		}
		
		for (int r = 0; r < qArr.length; r++) {
			for (int c = 0; c < qArr[0].length; c++) {
				P[r][c].setText(String.valueOf(qArr[r][c]));
			}	
		}
		
		pMat = new Matrix(qArr);
		
		xMat = Matrix.add(Matrix.subtract(Matrix.identity(size), pMat),
			Matrix.con(size, size));
		zMat = xMat.inverse();
		cMat = Matrix.con(1, size);
		wMat = Matrix.multiply(cMat, zMat);
		wMat.round(.0001f);
		
		dcc.gridx = 3;
		dcc.gridy = 2 + size;
		dcc.gridwidth = size;
		dcc.gridheight = 1;
		dgbl.setConstraints(wMat, dcc);
		dispArea.add(wMat);
    	
   	 	validate();
	}
	
	public float round(float num, float accuracy) {
		return accuracy * Math.round(num / accuracy);
	}
	
}




