//  package Tests;

import java.awt.event.*; // for mouseEvent and InputEvent
import java.beans.*;
import RemoteInterface.*; // for Move
import org.omg.CosNaming.*;
import org.omg.CORBA.*;


/**
  *Player is an abstract class so it cannot be instantiated.
  *PlayerTest defines test cases but no test suites because of this.
  */
public abstract class PlayerTest 
    extends AbstractTest {
    
    protected ORB orb;

	/**
        *PlayerTest constructor
	  *@param logFile The name of the log file to which test results are written
        */
    public PlayerTest(String logFile) {
	super(logFile); // report file
	 
	className = "Player";        // CUT
	fileName =  "Player.java";   // CUT file name
    }

    // Preconditions: called by AbstractTest::testProcess via inheritance
    // Symantics: showTestMenu is to be used together with testDispatch
    // Postconditions: Displays super.showTestMenu and then displays
    //                 tests available in this class
    protected void showTestMenu(){
	super.showTestMenu();
	//Player is an abstract class so no test actions are initiated here
    }
    
    // Preconditions: called by AbstractTest::testProcess via inheritance
    //                called after a user has input "which" test to run
    //                the tests are numbered in showTestMenu.
    // Symantics: testDispatch is to be used with showTestMenu
    // Postconditions: Executes the user selected test
    protected void testDispatch(int which[])
	throws Exception {
	
	switch (which[0]) {	
	default :
	    super.testDispatch(which);
	    break;  
	}
	
    }
 
    //--------------------------------------------------------------
    // The following are test scripts to be used with GameBoard.java
    // tests Scripts return boolean and do not take parameters.
  
    //public boolean functionalSuite();

    //public boolean structuralSuite();
    //public boolean interactionSuite();
    //public boolean baselineSuite();
    //public boolean regressionSuite();
    
    public boolean classInvariant(){
	
	boolean result;
	
	try {
	    int gameStatus = getGameStatus();
	    boolean invariant1 =  ( gameStatus >= -1 && gameStatus <= 2 );
	    
	    boolean invariant2 = (getPlayerNo() == 1) || (getPlayerNo() == 0) ;
	    
	    result = (invariant1 && invariant2);
	    
	} catch (Exception e) {
	    e.printStackTrace();
	    result = false;
	}
	
	return result;
    }

	//Reflective accessors for fileds declared in Player
	protected int getGameStatus(){
		try{
			return ((Integer)(getPrivateField((Player)OUT, "Player", "gameStatus"))).intValue();
		}catch(Exception e){
			e.printStackTrace();
			return -32767;
		}
	}

	protected boolean getToken(){
		try{
			return ((Boolean)(getPrivateField((Player)OUT, "Player", "token"))).booleanValue();
		}catch(Exception e){
			e.printStackTrace();
			return false;
		}
	}

	protected int getPlayerNo(){
		try{
			return ((Integer)(getPrivateField((Player)OUT, "Player", "playerNo"))).intValue();
		}catch(Exception e){
			e.printStackTrace();
			return -32767;
		}
	}

	//Basic constructor test
	//pre: OUT exists but is in intial state
	//post: gameStatus = -1
      protected boolean testCase1(){
		boolean result;

		try {
			int value = getGameStatus();
	    		result = (value == -1);
		}
		catch(Exception e) {
	    		e.printStackTrace();
	    		result = false;
		}

		return result;
      }

	//Test of the logic to conenct a Player to the ORB
	//pre: OUT exists but is in intial state
	//post: OUT is connected to ORB
	protected boolean testCase2(String ORBArgs[]){
		boolean result;

		try {
			TicTacToe game = new TicTacToe();
			game.connect(ORBArgs);
			((Player)OUT).initialize(ORBArgs);
			result = this.queryORB(ORBArgs,"Player1");
		}
		catch(Exception e) {
	    		e.printStackTrace();
	    		result = false;
		}
		return result;
      }

	//Test of the basic accessor for gameStatus
	//pre: OUT exists 
	//post: state of OUT is compared to result of accessor
	protected boolean testCase3(){
		boolean result = false;
		if(this.getGameStatus() == ((Player)OUT).getGameStatus()){
			result = true;
		}
		return result;
      }


	//Test of the basic accessor for token
	//pre: OUT exists 
	//post: state of OUT is compared to result of accessor
	protected boolean testCase4(){
		boolean result = false;
		if(this.getToken() == ((Player)OUT).isYourTurn()){
			result = true;
		}
		return result;
      }


    // -------------------------------------------------------------
    // The following are specialized tests.  Most of these take 
    // a paramater and can be used in a test Script.
    // the individual tests attempt to follow a nameing scheme
    // which is the name of primary method they exercise followed
    // by the postfix - test.
    public boolean setGameStatusTest(int status){
 
	//legal status values are
	// -1=playing, 0=lost, 1=won, 2=draw
	boolean result;

	try {
	    ((Player)OUT).setGameStatus(status);
	    int gameStatus 
		= ((Integer)(getPrivateField(OUT, "GameBoard","gameStatus"))).intValue();
	    result = (gameStatus == status) &&  classInvariant() ;
	} catch (Exception e) {
	    e.printStackTrace();
	    result = false;
	}

	return result;
	
    }

	//--------------------------------------------------

    //--------------------------------------------------
    // The following methods are provided for CORBA-based classes
    // these methods include methods for querying the ORB
    // 
    // Preconditions:An ORB has been used; an object may have been registered
    //with the ORB 
    // Semantics: This method queries the ORB for a specific object
    // Postconditions: It has been determined whether the object is currently registered.
    //                  
    //                 
	public boolean queryORB(String ORBArgs[],String name){
		boolean found = false;
	   
	   boolean goAhead = askTester("Is the ORB Naming Server running?");

	   if(goAhead){
	   try{
		orb = ORB.init(ORBArgs, null);
	    
	    // get the root naming context
	    org.omg.CORBA.Object objRef = 
		orb.resolve_initial_references("NameService");
	    NamingContext ncRef = NamingContextHelper.narrow(objRef);
	    
	    // resolve the Object Reference in Naming
	    NameComponent nc = new NameComponent(name, "");
	    NameComponent path[] = {nc};
      	try {
		    RemotePlayer remoteRef = RemotePlayerHelper.narrow(ncRef.resolve(path)); 
	          found = true;  
		}
		catch (Exception e) {
		    found = false;
		}
	   }
	   catch(Exception e){
		e.printStackTrace();
	   }
	   return found;
	   }
	   else{
		System.out.println("Taking the no namingservice path\n");
		return false;}
	}

}
