/*

Scott Marshall
MSc Project

Ex01
Checks student input for correct answers

*/

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.Vector;


public class Ex01_Checker
{

	//instance variables
	private Ex01_Table table;	
	private Ex01_Random random;	
	
	private int ansM;			//hold student answer for M, (output from gate 1)
	private int ansN;			//hold student answer for N, (output from gate 2)
	private int ansO;			//hold student answer for O, (output from gate 3)
	
	private int ans1;			//holds correct answer for gate 1
	private	int ans2;			//holds correct answer for gate 2
	private	int ans3;			//holds correct answer for gate 3
	private int cols;			//keeps track of which truth table column is an input for which gate
	private boolean correct;	//records whether all student inputs are correct.
	private Vector wrongLines;	//holds the number of lines containing errors
	
	public Ex01_Checker(Ex01_Table t,Ex01_Random r){
		table = t;
		random = r;
		//correct = false;
		wrongLines = new Vector();
	}


	/*
	calcAnswer will check the input answer for a single line.
	calcTable calculates the correct answer for the line, and stores the result in the ans1, ans2 and ans3 variables
	The student answers are read from the table and stored in ansM,ansN,ansO variables.
	The results for the line are displayed.
	The numbers of the lines containing errors are converted to string and added to the wrongLines vector.
	*/
	public void calcAnswer(int row){
		calcTable(row);

		ansM = new Integer(table.getCellValue(row,cols)).intValue();
		ansN = new Integer(table.getCellValue(row,cols+1)).intValue();		
		ansO = new Integer(table.getCellValue(row,cols+2)).intValue();	
		Integer iRow = new Integer(row+1);
		
	//	if (ansM == ans1 && ansN == ans2 && ansO ==ans3) 
	//		table.setTxtArea("Line " + (row+1) + ". Correct  = " + ans1 + " " + ans2 + " " + ans3);

		if (ansM != ans1 && ansN != ans2 && ansO != ans3) {
			table.setTxtArea("Error at Line " + (row+1) + ". Correct = " + ans1 + " " + ans2 + " " + ans3);				
			wrongLines.add(iRow.toString());
		}
	}
	
	
	//revealAnswer will display the correct answer for a single row.
	public void revealAnswer(int row){
		calcTable(row);
		table.setTxtArea("Line " + (row+1) + ". Correct Answer is  = " + ans1 + " " + ans2 + " " + ans3);
	}
	
	/*
	Each random.getRandomN() gets the type of gate at Gates 1, 2 and 3. 
	Each gate uses a switch to determine the type of gate, gets the relevent inputs to each gate
	as a string, concatenates the two input string and uses the concatenated string as an input
	argument to the	correct truth table	for each gate. 
	The result is stored as an int in the ans1,2,3 variables for later comparison.	
	*/		
	private void calcTable(int row){
		//initialised here with  default values.
		String inputOne;
		String inputTwo;
		String inputThree;
		String inputFour;
		String inputFive;
		String inputSix;
		Integer temp1;
		Integer temp2;
		String gateOneInput;
		String gateTwoInput;	
		String gateThreeInput;
				
		cols = 1;	//tracks columns to be read for input. Begins at 1 to avoid the label line
	
		//gate 1
		switch (random.getRandom1()) {
			case 0: inputOne = table.getCellValue(row,cols); inputTwo = table.getCellValue(row,cols+1); cols+=2; gateOneInput = inputOne+inputTwo ; ans1 = chkAndTable(gateOneInput); break;//And
			case 1:	inputOne = table.getCellValue(row,cols); inputTwo = table.getCellValue(row,cols+1); cols+=2; gateOneInput = inputOne+inputTwo ; ans1 = chkOrTable(gateOneInput);break;//Or
			case 2: inputOne = table.getCellValue(row,cols); cols++;  ans1 = chkInvTable(inputOne);break;//Inverter
			case 3:	inputOne = table.getCellValue(row,cols); inputTwo = table.getCellValue(row,cols+1); cols+=2; gateOneInput = inputOne+inputTwo ; ans1 = chkNAndTable(gateOneInput);break;//Nand
			case 4: inputOne = table.getCellValue(row,cols); inputTwo = table.getCellValue(row,cols+1); cols+=2; gateOneInput = inputOne+inputTwo ; ans1 = chkXOrTable(gateOneInput);break;//Xor			
		}		

		//gate 2
		switch (random.getRandom2()) {
			case 0: inputThree = table.getCellValue(row,cols); inputFour = table.getCellValue(row,cols+1); cols+=2; gateTwoInput = inputThree+inputFour ; ans2 = chkAndTable(gateTwoInput); break;//And
			case 1:	inputThree = table.getCellValue(row,cols); inputFour = table.getCellValue(row,cols+1); cols+=2; gateTwoInput = inputThree+inputFour ; ans2 = chkOrTable(gateTwoInput);break;//Or
			case 2: inputThree = table.getCellValue(row,cols); cols++;  ans2 = chkInvTable(inputThree);break;//Inverter
			case 3:	inputThree = table.getCellValue(row,cols); inputFour = table.getCellValue(row,cols+1); cols+=2; gateTwoInput = inputThree+inputFour ; ans2 = chkNAndTable(gateTwoInput);break;//Nand
			case 4: inputThree = table.getCellValue(row,cols); inputFour = table.getCellValue(row,cols+1); cols+=2; gateTwoInput = inputThree+inputFour ; ans2 = chkXOrTable(gateTwoInput);break;//Xor			

		}		

		//gate 3
		switch (random.getRandom3()) {
			case 0: temp1 = new Integer(ans1); inputFive = temp1.toString(); temp2 = new Integer(ans2); inputSix = temp2.toString(); gateThreeInput = inputFive+inputSix ; ans3 = chkAndTable(gateThreeInput);break;//And
			case 1:	temp1 = new Integer(ans1); inputFive = temp1.toString(); temp2 = new Integer(ans2); inputSix = temp2.toString(); gateThreeInput = inputFive+inputSix ; ans3 = chkOrTable(gateThreeInput);break;//Or
			case 2: temp1 = new Integer(ans1); inputFive = temp1.toString(); temp2 = new Integer(ans2); inputSix = temp2.toString(); gateThreeInput = inputFive+inputSix ; ans3 = chkXOrTable(gateThreeInput);break;//Xor - deliberate breaking of randomness
			case 3:	temp1 = new Integer(ans1); inputFive = temp1.toString(); temp2 = new Integer(ans2); inputSix = temp2.toString(); gateThreeInput = inputFive+inputSix ; ans3 = chkNAndTable(gateThreeInput);break;//Nand
			case 4: temp1 = new Integer(ans1); inputFive = temp1.toString(); temp2 = new Integer(ans2); inputSix = temp2.toString(); gateThreeInput = inputFive+inputSix ; ans3 = chkXOrTable(gateThreeInput);break;//Xor			
		}		

	}

	//Truth table - And gate
	private int chkAndTable(String input){
		int ans = -1;
		if(input.equals("00"))
			ans = 0;
		if(input.equals("01"))
			ans = 0;
		if(input.equals("10"))
			ans = 0;
		if(input.equals("11"))
			ans = 1;
		return ans;	
	}
	
	//Truth table - Or gate	
	private int chkOrTable(String input){
		int ans = -1;
		if(input.equals("00"))
			ans = 0;
		if(input.equals("01"))
			ans = 1;
		if(input.equals("10"))
			ans = 1;
		if(input.equals("11"))
			ans = 1;
		return ans;	
	}
	
	//Truth table - Inv gate
	private int chkInvTable(String input){
		int ans = -1;
		if(input.equals("0"))
			ans = 1;
		if(input.equals("1"))
			ans = 0;
		return ans;	
	}


	//Truth table - NAnd gate
	private int chkNAndTable(String input){
		int ans = -1;	
		if(input.equals("00"))
			ans = 1;
		if(input.equals("01"))
			ans = 1;
		if(input.equals("10"))
			ans = 1;
		if(input.equals("11"))
			ans = 0;
		return ans;	
	}
	
	//Truth table - XOr gate
	private int chkXOrTable(String input){
		int ans = -1;
		if(input.equals("00"))
			ans = 0;
		if(input.equals("01"))
			ans = 1;
		if(input.equals("10"))
			ans = 1;
		if(input.equals("11"))
			ans = 0;
		return ans;	
	}

	
	public boolean allCorrect() {
		if (wrongLines.size()==0)
			correct = true;
		else
			correct = false;	
		return correct;
	}
	
	//wrongLines contains the rows with errors. Method returns the vector as a string
	//to allow table to construct the error message
	public String wrongLines(){
		return wrongLines.toString();
	}
	
	//clears contents of vector prior to next checking run
	public void clearVector(){
		wrongLines.clear();
	}
	
	
	
}