// Nick Wagner
// Piper Pinchback
// Angela Kmiec

// Approach 1:

// a ComparisonChecker1 object is used to compare the output of the 
// student's program to that of the instructor's program

import OutputFormatter1;

public class ComparisonChecker1 {

    int userNumber, authorityNumber;
    int testLevel = -1;
    boolean comparisonResults;
    String userResults;
    String authorityResults;
    OutputFormatter1 out;

/////////////////
// Constructor //
/////////////////

// ComparisonChecker1 needs an OutputFormatter object and an integer 
// telling it what level of correctness to check for.  0 corresponds
// to exactly matching outputs, 1 corresponds to outputs that match by 
// line, and 2 corresponds to outputs that match when whitespace is 
// disregarded entirely

    public ComparisonChecker1(OutputFormatter1 here, int correctnessLevel){
        out = here;
	testLevel = correctnessLevel;
    }

// if no testLevel is specified, 0 is used
    public ComparisonChecker1(OutputFormatter1 here){
        out = here;
	testLevel = 0;
    }

/////////////
// methods //
/////////////

// setUserResults  
public void setUserResults(String user, int testNumber) {
       userResults = user;
       userNumber = testNumber;
       if (authorityNumber == userNumber) 
          this.compare();
}


// setAuthorityResults
public void setAuthorityResults(String authority, int testNumber) {
       authorityResults = authority;
       authorityNumber = testNumber;
       if (authorityNumber == userNumber) 
          this.compare();
}

private void setComparisonResults(boolean results){
      	 comparisonResults = results;
}
private void compare(){

	if (userResults.compareTo(authorityResults)==0){
		this.passed();

	}

	else if (testLevel==1) {
		compareLevel1();
	}			 

	else if (testLevel==2) {
		compareLevel2();
	}
	
	else {
		throw new IndexOutOfBoundsException 
                         ("testLevel must be between 0 and 2 inclusive");
	}
	
} // compare()

public void compareLevel1(){

                int u = 0; // index of the user results
		int a = 0; // index of the authority results
		int ulength = userResults.length();// length of user results
		int alength = authorityResults.length();//length of authority results
		boolean done = false;// terminates while loop when necessary

	while (!done){
		a = skipWhite(authorityResults, a);
		u = skipWhite(userResults, u);			
		
		if ((u == ulength) && (a == alength)){
			this.passed();
			done = true;
		} 
		
		else if((u == ulength) || (a == alength)){
			this.failed();
			done=true;
		}

		else if(userResults.charAt(u) == authorityResults.charAt(a)){
			a++;
			u++;
		}

		else {
			this.failed();
			done=true;
		}
	} // while 
} // compareLevel1
	
public void compareLevel2(){

		int u = 0;
		int a = 0;
		int ulength = userResults.length();
		int alength = authorityResults.length();
		boolean done = false;

	while (!done) {
		a = skipWhiteAndReturns(authorityResults, a);
		u = skipWhiteAndReturns(userResults, u);			
		
		if ((u == ulength) && (a == alength)){
			this.passed();
			done = true;
		} 
		
		else if((u == ulength) || (a == alength)){
			this.failed();
			done=true;
		}

		else if(userResults.charAt(u) == authorityResults.charAt(a)){
			a++;
			u++;
		}

		else {
			this.failed();
			done=true;
		}
	} // while
} // compareLevel2

private int skipWhite(String result, int i){
	while(i < result.length() && 
	     (result.charAt(i) == " ".charAt(0) ||
              result.charAt(i) == "\t".charAt(0))) {
		i++;
		}
	return i;
}

private int skipWhiteAndReturns(String result, int i){
	while((i < result.length()) && 
	     (result.charAt(i) == " ".charAt(0) ||
              result.charAt(i) == "\t".charAt(0) ||
              result.charAt(i) == "\n".charAt(0) ||
              result.charAt(i) == "\r".charAt(0))) {
		i++;
		}
	return i;
}
	
private void passed(){
          setComparisonResults(true); 
          out.getComp(comparisonResults, userResults, authorityResults);
}
private void failed(){
          setComparisonResults(false);
          out.getComp(comparisonResults, userResults, authorityResults);
}
}

