// Bayes.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 Bayes
	extends java.applet.Applet
{
	TextArea disp;		// Area to display HT
	
	Panel dispArea;
	Panel controls;		// Panel for user controls
	
	Label d1l, d2l, d3l, d1l2, d2l2, d3l2, ppl, pml, mpl, mml, prior, cond;		// Controls
	TextField d1, d2, d3, pp1, pm1, mp1, mm1, pp2, pm2, mp2, mm2,
		pp3, pm3, mp3, mm3;
	Button go;
	
	GridBagLayout gbl;
	GridBagConstraints cc;
		
	// Initialize applet
	public void init()
	{	
		prior = new Label("Prior probabilities");
		cond = new Label("Conditional probabilities");
		d1l = new Label("d1");
		d2l = new Label("d2");
		d3l = new Label("d3");
		d1l2 = new Label("d1");
		d2l2 = new Label("d2");
		d3l2 = new Label("d3");
		ppl = new Label("++");
		pml = new Label("+-");
		mpl = new Label("-+");
		mml = new Label("--");
		
		d1 = new TextField("3215", 4);
		d2 = new TextField("2125", 4);
		d3 = new TextField("4660", 4);
		pp1 = new TextField("2110", 4);
		pm1 = new TextField("301", 4);
		mp1 = new TextField("704", 4);
		mm1 = new TextField("100", 4);
		pp2 = new TextField("396", 4);
		pm2 = new TextField("132", 4);
		mp2 = new TextField("1187", 4);
		mm2 = new TextField("410", 4);
		pp3 = new TextField("510", 4);
		pm3 = new TextField("3568", 4);
		mp3 = new TextField("73", 4);
		mm3 = new TextField("509", 4);
		
		go = new Button("Go");
		
		disp = new TextArea(15, 20);		// Create display area
		
		dispArea = new Panel();				// Set up window
		controls = new Panel();
		setLayout(new BorderLayout(5, 5));
		
		add("South", controls);
		add("Center", dispArea);
		
		dispArea.setLayout(new GridLayout(1, 1));
		dispArea.add(disp);
		
		gbl = new GridBagLayout();
		controls.setLayout(gbl);
		
		cc = new GridBagConstraints();
		
		cc.gridx = 0;
		cc.gridy = 0;
		cc.gridwidth = 5;
		gbl.setConstraints(prior, cc);
		controls.add(prior);
		
		cc.gridx = 1;
		cc.gridy = 1;
		cc.gridwidth = 1;
		gbl.setConstraints(d1l, cc);
		controls.add(d1l);
		
		cc.gridx = 2;
		gbl.setConstraints(d2l, cc);
		controls.add(d2l);
		
		cc.gridx = 3;
		gbl.setConstraints(d3l, cc);
		controls.add(d3l);
		
		cc.gridx = 1;
		cc.gridy = 2;
		gbl.setConstraints(d1, cc);
		controls.add(d1);
		
		cc.gridx = 2;
		gbl.setConstraints(d2, cc);
		controls.add(d2);
		
		cc.gridx = 3;
		gbl.setConstraints(d3, cc);
		controls.add(d3);
		
		cc.gridx = 0;
		cc.gridy = 3;
		cc.gridwidth = 5;
		gbl.setConstraints(cond, cc);
		controls.add(cond);
		
		cc.gridx = 1;
		cc.gridy = 4;
		cc.gridwidth = 1;
		gbl.setConstraints(ppl, cc);
		controls.add(ppl);
		
		cc.gridx = 2;
		gbl.setConstraints(pml, cc);
		controls.add(pml);
		
		cc.gridx = 3;
		gbl.setConstraints(mpl, cc);
		controls.add(mpl);
		
		cc.gridx = 4;
		gbl.setConstraints(mml, cc);
		controls.add(mml);
		
		cc.gridx = 0;
		cc.gridy = 5;
		gbl.setConstraints(d1l2, cc);
		controls.add(d1l2);
		
		cc.gridx = 1;
		gbl.setConstraints(pp1, cc);
		controls.add(pp1);
		
		cc.gridx = 2;
		gbl.setConstraints(pm1, cc);
		controls.add(pm1);
		
		cc.gridx = 3;
		gbl.setConstraints(mp1, cc);
		controls.add(mp1);
		
		cc.gridx = 4;
		gbl.setConstraints(mm1, cc);
		controls.add(mm1);
		
		cc.gridx = 0;
		cc.gridy = 6;
		gbl.setConstraints(d2l2, cc);
		controls.add(d2l2);
		
		cc.gridx = 1;
		gbl.setConstraints(pp2, cc);
		controls.add(pp2);
		
		cc.gridx = 2;
		gbl.setConstraints(pm2, cc);
		controls.add(pm2);
		
		cc.gridx = 3;
		gbl.setConstraints(mp2, cc);
		controls.add(mp2);
		
		cc.gridx = 4;
		gbl.setConstraints(mm2, cc);
		controls.add(mm2);
		
		cc.gridx = 0;
		cc.gridy = 7;
		gbl.setConstraints(d3l2, cc);
		controls.add(d3l2);
		
		cc.gridx = 1;
		gbl.setConstraints(pp3, cc);
		controls.add(pp3);
		
		cc.gridx = 2;
		gbl.setConstraints(pm3, cc);
		controls.add(pm3);
		
		cc.gridx = 3;
		gbl.setConstraints(mp3, cc);
		controls.add(mp3);
		
		cc.gridx = 4;
		gbl.setConstraints(mm3, cc);
		controls.add(mm3);
		
		cc.gridx = 2;
		cc.gridy = 8;
		gbl.setConstraints(go, cc);
		controls.add(go);
		
		validate();
	}
	
	// Handle events
	public boolean handleEvent(Event evt)
	{
		if (evt.target instanceof Button)
		{
			if (evt.target == go && evt.id == Event.ACTION_EVENT)	// When button is clicked
			{
				disp.setText("");			// Reset output window
        		simulate();
        		return true;					// Generate correct number of tosses
			}
		}
		return super.handleEvent(evt);	// Handle other events as usual
	}
	
	public float round(float num, float accuracy) {
		return (float) Math.round((double) (num / accuracy)) * accuracy;	
	}
	
	// Calculate probabilities
    public void simulate()
    {	
    	disp.appendText("Posterior probabilities\n\n");
    	disp.appendText("        d1    d2    d3\n");
    	float[] pp = new float[3];
    	float[] pm = new float[3];
    	float[] mp = new float[3];
    	float[] mm = new float[3];
    	
    	/*	CODE FOR ROUNDING INPUT WHEN USER PRESSES GO - CHANGES RESULTS SLIGHTLY
    	float dt = Float.valueOf(d1.getText()).floatValue() +
    		Float.valueOf(d2.getText()).floatValue() +
    		Float.valueOf(d3.getText()).floatValue();
    	d1.setText(String.valueOf(round(Float.valueOf(d1.getText()).floatValue() /
    		dt, .00001f)));
    	d2.setText(String.valueOf(round(Float.valueOf(d2.getText()).floatValue() /
    		dt, .00001f)));
    	d3.setText(String.valueOf(round(Float.valueOf(d3.getText()).floatValue() /
    		dt, .00001f)));
    	
    	float d1t = Float.valueOf(pp1.getText()).floatValue() +
    		Float.valueOf(pm1.getText()).floatValue() +
    		Float.valueOf(mp1.getText()).floatValue() +
    		Float.valueOf(mm1.getText()).floatValue();
    	pp1.setText(String.valueOf(round(Float.valueOf(pp1.getText()).floatValue() /
    		d1t, .00001f)));
    	pm1.setText(String.valueOf(round(Float.valueOf(pm1.getText()).floatValue() /
    		d1t, .00001f)));
    	mp1.setText(String.valueOf(round(Float.valueOf(mp1.getText()).floatValue() /
    		d1t, .00001f)));
    	mm1.setText(String.valueOf(round(Float.valueOf(mm1.getText()).floatValue() /
    		d1t, .00001f)));
    		
    	float d2t = Float.valueOf(pp2.getText()).floatValue() +
    		Float.valueOf(pm2.getText()).floatValue() +
    		Float.valueOf(mp2.getText()).floatValue() +
    		Float.valueOf(mm2.getText()).floatValue();
    	pp2.setText(String.valueOf(round(Float.valueOf(pp2.getText()).floatValue() /
    		d2t, .00001f)));
    	pm2.setText(String.valueOf(round(Float.valueOf(pm2.getText()).floatValue() /
    		d2t, .00001f)));
    	mp2.setText(String.valueOf(round(Float.valueOf(mp2.getText()).floatValue() /
    		d2t, .00001f)));
    	mm2.setText(String.valueOf(round(Float.valueOf(mm2.getText()).floatValue() /
    		d2t, .00001f)));
    		
    	float d3t = Float.valueOf(pp3.getText()).floatValue() +
    		Float.valueOf(pm3.getText()).floatValue() +
    		Float.valueOf(mp3.getText()).floatValue() +
    		Float.valueOf(mm3.getText()).floatValue();
    	pp3.setText(String.valueOf(round(Float.valueOf(pp3.getText()).floatValue() /
    		d3t, .00001f)));
    	pm3.setText(String.valueOf(round(Float.valueOf(pm3.getText()).floatValue() /
    		d3t, .00001f)));
    	mp3.setText(String.valueOf(round(Float.valueOf(mp3.getText()).floatValue() /
    		d3t, .00001f)));
    	mm3.setText(String.valueOf(round(Float.valueOf(mm3.getText()).floatValue() /
    		d3t, .00001f)));
    	*/
    	
    	float ppt = Float.valueOf(pp1.getText()).floatValue() +
    		Float.valueOf(pp2.getText()).floatValue() +
    		Float.valueOf(pp3.getText()).floatValue();
    	pp[0] = round(Float.valueOf(pp1.getText()).floatValue() / ppt, .001f);
    	pp[1] = round(Float.valueOf(pp2.getText()).floatValue() / ppt, .001f);
    	pp[2] = round(Float.valueOf(pp3.getText()).floatValue() / ppt, .001f);
    	
    	float pmt = Float.valueOf(pm1.getText()).floatValue() +
    		Float.valueOf(pm2.getText()).floatValue() +
    		Float.valueOf(pm3.getText()).floatValue();
    	pm[0] = round(Float.valueOf(pm1.getText()).floatValue() / pmt, .001f);
    	pm[1] = round(Float.valueOf(pm2.getText()).floatValue() / pmt, .001f);
    	pm[2] = round(Float.valueOf(pm3.getText()).floatValue() / pmt, .001f);
    	
    	float mpt = Float.valueOf(mp1.getText()).floatValue() +
    		Float.valueOf(mp2.getText()).floatValue() +
    		Float.valueOf(mp3.getText()).floatValue();
    	mp[0] = round(Float.valueOf(mp1.getText()).floatValue() / mpt, .001f);
    	mp[1] = round(Float.valueOf(mp2.getText()).floatValue() / mpt, .001f);
    	mp[2] = round(Float.valueOf(mp3.getText()).floatValue() / mpt, .001f);
    	
    	float mmt = Float.valueOf(mm1.getText()).floatValue() +
    		Float.valueOf(mm2.getText()).floatValue() +
    		Float.valueOf(mm3.getText()).floatValue();
    	mm[0] = round(Float.valueOf(mm1.getText()).floatValue() / mmt, .001f);
    	mm[1] = round(Float.valueOf(mm2.getText()).floatValue() / mmt, .001f);
    	mm[2] = round(Float.valueOf(mm3.getText()).floatValue() / mmt, .001f);
    	
    	disp.appendText("\n++");
    	for (int i = 0; i < 3; i++) {
    		disp.appendText("  " + String.valueOf(pp[i]));//.substring(1,5));
	    }
	    
	    disp.appendText("\n+-");
    	for (int i = 0; i < 3; i++) {
    		disp.appendText("  " + String.valueOf(pm[i]));//.substring(1,5));
	    }
	    
	    disp.appendText("\n-+");
    	for (int i = 0; i < 3; i++) {
    		disp.appendText("  " + String.valueOf(mp[i]));//.substring(1,5));
	    }
	    
	    disp.appendText("\n--");
    	for (int i = 0; i < 3; i++) {
    		disp.appendText("  " + String.valueOf(mm[i]));//.substring(1,5));
	    }
	    
	    validate();
    }

}