import java.awt.*;
import java.applet.*;
public class MathTest extends Applet
{
	public static final int MAXBUTTONS = 20;

	private boolean first_time_right = true;

	private Panel NumberPanel,EquationPanel,StatusPanel;

	private int wrong = 0;
	private int right = 0;

	Operand CurrentOperand;
	Operand	Add, Subtract, Divide, Multiply;

	private String	MessageStr;
	private StringBuffer Message,Stat;

	private Choice OperandChoice;

	private Color CurrentColor = Color.cyan;

	private Label WrongStat;
	private Label RightStat;
	private Label Equation;
	private Label Response;

	GridBagLayout gridbag = new GridBagLayout();

	
	//Number buttons are the push button answers
	private Button[] NumberButton = new Button[MAXBUTTONS];
	private int ButtonValue[] = {	0,1,2,3,4,5,6,7,8,9,
					10,11,12,13,14,15,16,17,18,19};

	private String[] ButtonLabel = {
		" 0 "," 1 "," 2 "," 3 "," 4 "," 5 "," 6 "," 7 "," 8 "," 9 ",
		"10","11","12","13","14","15","16","17","18","19"};

	private Button NewEquation_button;


	public void init()
	{
		int i;

		GridBagConstraints gb = new GridBagConstraints();
		setFont(new Font("Helvetica",Font.PLAIN,14)); 
		Equation = new Label("Math Test, by SteveO ");
		Response = new Label("Press 'New Equation'");
		RightStat = new Label("Right: 0         ");
		WrongStat = new Label("Wrong: 0          ");
		NewEquation_button = new Button("New Equation");
		NewEquation_button.setBackground(Color.lightGray);
		NewEquation_button.setForeground(Color.black);


		// initialize the push buttons.
		for (i=0;i<MAXBUTTONS;i++)
		{
			NumberButton[i] = InitAnswerButton(NumberButton[i],
						ButtonLabel[i]);
		}



		this.setLayout(gridbag);

		// set up a method for changing the background color.
		
		OperandChoice = new Choice();
		OperandChoice.addItem("Addition");
		OperandChoice.addItem("Subtraction");
		OperandChoice.addItem("Multiplication");
		OperandChoice.addItem("Division");



		// Create a panel for the Equation and response
		EquationPanel = new Panel();
		EquationPanel.setLayout(gridbag);
		
		constrain(EquationPanel,Equation,0,0,1,1);
		constrain(EquationPanel,Response,1,0,1,1);

		// Create a panel for status like right count 

		StatusPanel = new Panel();
		StatusPanel.setLayout(gridbag);
		
		constrain(StatusPanel,RightStat,0,0,1,1);
		constrain(StatusPanel,WrongStat,1,0,1,1);
		constrain(StatusPanel,OperandChoice,2,0,1,1);
		

		// Create a panel for the number buttons
		NumberPanel = new Panel();
		NumberPanel.setLayout(gridbag);

		constrain(NumberPanel,NewEquation_button,0,0,12,1);

		for (i=0;i<MAXBUTTONS;i++)
		{
			constrain(NumberPanel,NumberButton[i],i%10,(i/10)+1,
				1,1,GridBagConstraints.RELATIVE,
				GridBagConstraints.RELATIVE);
		}


	      
		this.setBackground(CurrentColor);

		//Now constrain the frickin panel
		constrain(this, NumberPanel,0,3,10,1,
					GridBagConstraints.HORIZONTAL,
					GridBagConstraints.SOUTH,1.0,1.0,1,1,10,3);

		constrain(this, EquationPanel,0,2,3,1,
					GridBagConstraints.HORIZONTAL,
					GridBagConstraints.CENTER,1.0,1.0,1,1,10,3);

		constrain(this, StatusPanel,0,1,3,1,
					GridBagConstraints.HORIZONTAL,
					GridBagConstraints.NORTH,1.0,1.0,1,1,10,3);

		Add = new Operand('+');
		Subtract = new Operand('-');
		Divide = new Operand('/');
		Multiply = new Operand('*');

		CurrentOperand = Add;
		
		Message = new StringBuffer("a + b =");
	}

	public Button InitAnswerButton(Button ButtonName,String Title)
	{
		ButtonName = new Button(Title);
		ButtonName.setBackground(Color.lightGray);
		ButtonName.setForeground(Color.black);
		return ButtonName;
	}
	public void TestAnswer(int answer)
	{
		if(CurrentOperand.Execute(CurrentOperand.a,CurrentOperand.b) == answer)
		{
			
			if(first_time_right)   
				right++;
			Response.setText("Correctamundo");
			first_time_right = false;
			Stat = new StringBuffer();
			Stat.append("Right: ");
			Stat.append(right);

			MessageStr = Stat.toString();

			RightStat.setText(MessageStr);
			play(getCodeBase(),"audio/joy.au");
		}
		else
		{
			wrong++;
			Response.setText("Wrong Bucko");
			Stat = new StringBuffer();
			Stat.append("Wrong: ");
			Stat.append(wrong);

			MessageStr = Stat.toString();

			WrongStat.setText(MessageStr);
		}
	}
	public boolean action(Event event, Object arg)
	{
	
		if (event.target == NewEquation_button) // New equation
		{	
			Graphics g = this.getGraphics();
		 	Rectangle r = this.bounds();
			g.setColor(this.getBackground());
			g.fillRect(r.x,r.y,r.width,r.height);
			g.setColor(Color.black);
			Response.setText("             ");
			first_time_right = true; //allow only one right 
						// answer per equation
			CurrentOperand.GetTerms();

			Message = new StringBuffer();
			Message.append(CurrentOperand.a);
			Message.append(" ");
			Message.append(CurrentOperand.symbol());
			Message.append(" ");
			Message.append(CurrentOperand.b);
			Message.append(" = ");


			MessageStr = Message.toString();

			Equation.setText(MessageStr);
			return true;
		}

		else if(event.target == OperandChoice)
		{

			if(arg.equals("Addition"))
			{
				CurrentOperand = Add;
			}
			if(arg.equals("Subtraction"))
			{
				CurrentOperand = Subtract;
			}
			if(arg.equals("Multiplication"))
			{
				CurrentOperand = Multiply;
			}
			if(arg.equals("Division"))
			{
				CurrentOperand = Divide;
			}

			return true;
		} 

		else if (event.target == NumberButton[0])
		{	
			TestAnswer(0);
			return true;
		}
		else if (event.target == NumberButton[1])
		{	
			TestAnswer(1);
			return true;
		}
		else if (event.target == NumberButton[2])
		{	
			TestAnswer(2);
			return true;
		}
		else if (event.target == NumberButton[3])
		{	
			TestAnswer(3);
			return true;
		}
		else if (event.target == NumberButton[4])
		{	
			TestAnswer(4);
			return true;
		}
		else if (event.target == NumberButton[5])
		{	
			TestAnswer(5);
			return true;
		}
		else if (event.target == NumberButton[6])
		{	
			TestAnswer(6);
			return true;
		}
		else if (event.target == NumberButton[7])
		{	
			TestAnswer(7);
			return true;
		}
		else if (event.target == NumberButton[8])
		{	
			TestAnswer(8);
			return true;
		}
		else if (event.target == NumberButton[9])
		{	
			TestAnswer(9);
			return true;
		}
		else if (event.target == NumberButton[10])
		{	
			TestAnswer(10);
			return true;
		}
		else if (event.target == NumberButton[11])
		{	
			TestAnswer(11);
			return true;
		}
		else if (event.target == NumberButton[12])
		{	
			TestAnswer(12);
			return true;
		}
		else if (event.target == NumberButton[13])
		{	
			TestAnswer(13);
			return true;
		}
		else if (event.target == NumberButton[14])
		{	
			TestAnswer(14);
			return true;
		}
		else if (event.target == NumberButton[15])
		{	
			TestAnswer(15);
			return true;
		}
		else if (event.target == NumberButton[16])
		{	
			TestAnswer(16);
			return true;
		}
		else if (event.target == NumberButton[17])
		{	
			TestAnswer(17);
			return true;
		}
		else if (event.target == NumberButton[18])
		{	
			TestAnswer(18);
			return true;
		}
		else if (event.target == NumberButton[19])
		{	
			TestAnswer(19);
			return true;
		}

		else
		{
			return super.action(event,arg);
		}
	}
	public void constrain(Container container, Component component,
			      int grid_x, int grid_y, int grid_width, 
			      int grid_height, int fill,int anchor,
				  double weight_x, double weight_y, int top,
				  int left, int bottom, int right)
	{
		GridBagConstraints c = new GridBagConstraints();
		c.gridx = grid_x; c.gridy = grid_y;
		c.gridwidth = grid_width; c.gridheight = grid_height;
		c.fill = fill; c.anchor = anchor;
		c.weightx= weight_x; c.weighty = weight_y;
		if(top+bottom+left+right>0)
				c.insets = new Insets(top,left,bottom,right);

		((GridBagLayout)container.getLayout()).setConstraints(component,c);
		container.add(component);
	}


// This is the one we use for the answer buttons
	public void constrain(Container container, Component component,
			      int grid_x, int grid_y, int grid_width, 
			      int grid_height,double Xweight, 
				double Yweight)
	{
		constrain(container, component, grid_x, grid_y,
			  grid_width, grid_height, GridBagConstraints.RELATIVE,
			  GridBagConstraints.NORTH,Xweight,Yweight,0,0,0,0);

	}
	public void constrain(Container container, Component component,
			      int grid_x, int grid_y, int grid_width, 
			      int grid_height)
	{
		constrain(container, component, grid_x, grid_y,
			  grid_width, grid_height, GridBagConstraints.NONE,
			  GridBagConstraints.NORTHWEST,0.0,0.0,0,0,0,0);

	}
	public void constrain(Container container, Component component,
			      int grid_x, int grid_y, int grid_width, 
			      int grid_height, int top, int left,
				  int bottom, int right)
	{
		constrain(container, component, grid_x, grid_y,
			  grid_width, grid_height, GridBagConstraints.NONE,
			  GridBagConstraints.NORTHWEST,0.0,0.0,top,left,bottom,right);

	}
}

class Operand
{
	private char moniker; // +, /, -, or *
	public int a,b;

	Operand(char symbol)
	{
		moniker = symbol;
	}

	public void GetTerms()
	{
		int temp;

		a = (int)(10 * java.lang.Math.random());
		b = (int)(10 * java.lang.Math.random());

		switch(moniker)
		{
			case '+':
			return;

			case '-':
				if (a<b)
				{
					temp = a;
					a = b;
					b = temp;
				}
			return;

			case '*':
				while(a*b > 19)
				{
					b = (int)(10 * java.lang.Math.random());
				}
			return;

			case '/':
			
				a = (int)(30 * java.lang.Math.random());
				b = 100;
				while((a < b)||			// no fractions
					  (a/b > 19))		// the answer should be < 19
				{
						b = (int)(10 * java.lang.Math.random());
						if (b == 0) b=1;
				}
				a = (a/b)*b; // no remainders.
			return;
			
		}
		return;

	}
	public int Execute(int TermA, int TermB)
	{
		switch(moniker)
		{
			case '+':
			return TermA+TermB;

			case '-':
			return TermA-TermB;

			case '*':
			return TermA*TermB;

			case '/':
			return TermA/TermB;
		}
		return 777;

	}

	public char symbol()
	{
		return moniker;
	}

}
