// VariationList.java

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

// Something does not work at all

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

public class VariationList
	extends java.applet.Applet
{
	TextArea disp;		// Area to display HT
	
	Panel dispArea;
	Panel controls;		// Panel for user controls
	
	Label numl1, numl2, numl3;			// Controls
	TextField num1, num2, num3;
	Button go;
	
	GridBagLayout gbl;
	GridBagConstraints cc;
		
	// Initialize applet
	public void init()
	{	
		numl1 = new Label("No. of cards =");			// Create controls
		num1 = new TextField("10", 4);
		numl2 = new Label("Min shuffles =");			// Create controls
		num2 = new TextField("1", 4);
		numl3 = new Label("Max shuffles =");			// Create controls
		num3 = new TextField("5", 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 = 1;
		cc.gridy = 0;
		gbl.setConstraints(numl1, cc);
		controls.add(numl1);
		
		cc.gridx = 2;
		gbl.setConstraints(num1, cc);
		controls.add(num1);
		
		cc.gridx = 0;
		cc.gridy = 1;
		gbl.setConstraints(numl2, cc);
		controls.add(numl2);
		
		cc.gridx = 1;
		gbl.setConstraints(num2, cc);
		controls.add(num2);
		
		cc.gridx = 2;
		gbl.setConstraints(numl3, cc);
		controls.add(numl3);
		
		cc.gridx = 3;
		gbl.setConstraints(num3, cc);
		controls.add(num3);
	
		cc.gridx = 0;
		cc.gridy = 2;
		cc.gridwidth = 4;
		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(Integer.valueOf(num1.getText()).intValue(),
        			Integer.valueOf(num2.getText()).intValue(),
        			Integer.valueOf(num3.getText()).intValue());
        		return true;					// Generate correct number of tosses
			}
		}
		return super.handleEvent(evt);	// Handle other events as usual
	}
	
	public double a(int n, int a) {
		if (a == 1)
			return 1;
		else {
			double total = (int) Math.pow((double) a,(double) n);
			for (int r = 1; r <= (a - 1); r++) {
				total -= (Combinatorics.choose(n + a - r, n) * a(n, r));
			}
			return total;	
		}	
	}
	
	public double dist(int n, int s) {
		double sum = 0;
		for (int r = 1; r <= n; r++) {
			sum += (.5 * a(n, r) * Math.abs(Combinatorics.choose((int) Math.pow(2, 
				s) + n - r, n) / Math.pow(2, n * s) )); // - 1f / (float) Combinatorics.fact(n)));	
		}
		return sum;
	}
	
	// Calculate probabilities
    public void simulate(int num, int min, int max)
    {	
    	disp.appendText("s            Variation distance\n\n");
    	for (int i = min; i <= max; i++) {
    		disp.appendText(String.valueOf(i) + "          " 
    			+ dist(num, i) + "\n");
	    }
    }

}




