//  package Java.TicTacToe.Game;

import RemoteInterface.*;

import org.omg.CosNaming.*;
import org.omg.CORBA.*;

// Player is a Corba Servant Class for the Game Framework
public abstract class Player 
    extends _RemotePlayerImplBase{

    abstract public void yourMove(int[] state);
    abstract public void wonGame(int[] state);
    abstract public void lostGame(int[] state);
    abstract public void tieGame(int[] state);
 //     abstract public int[] getCurrentState();  // don't really need here - jlr
    abstract public void resetGame();
        
    private boolean token;
    protected ORB orb;
    public RemoteGame remoteGame = null;  // Do we really  this public? - jlr
    protected int playerNo;
    protected int gameStatus; //is the game a win=1, loss=0, tie=2, or in progress=-1
    
    public Player(String newPlayerNo)
    {
	token = false;    // not your turn;
	gameStatus = -1;  // in progress
	playerNo = Integer.valueOf(newPlayerNo).intValue();
    }

    protected void setYourTurn( boolean turn )
    {
	token = turn;
    }

    public boolean isYourTurn()
    {
	return token;
    }

    protected void setGameStatus( int newStatus )
    {
	if (newStatus <=2 )
	    gameStatus = newStatus;
    }

    public int getGameStatus()
    {
	return gameStatus;
    }

    /** Establishes connection with RemoteGame
      *and makes player a servent class so 
      *that the RemoteGame can call us.
	*@param ORBArgs contains arguments to be used in establishing the ORB
	*pre: instance exists
	*post: instance is connected to the ORB
	*/
     public void initialize( String ORBArgs[] ) 
    {
	
	try {
	    // create and initialize the ORB
	    orb = ORB.init(ORBArgs, null);
	    System.out.println("inited\n");
	    // get the root naming context
	    org.omg.CORBA.Object objRef = 
		orb.resolve_initial_references("NameService");
System.out.println("ref\n");
	    NamingContext ncRef = NamingContextHelper.narrow(objRef);
	    System.out.println("narrowed\n");
	    // resolve the Object Reference in Naming
	    NameComponent nc = new NameComponent("Game", "");
	    NameComponent path[] = {nc};
	System.out.println("Going after Game\n");
	    while( true ) {
		try {
		    remoteGame = RemoteGameHelper.narrow(ncRef.resolve(path));
		    break;   
		}
		catch (Exception e) {
		    e.printStackTrace();
		}
	    } 
      
	    // create servant and register it with the ORB  
	    orb.connect(this);
	    
	    // bind the Object Reference in Naming
	    // Register Player as Player<Id> where 
	    // id is either 0 or 1

System.out.println("connected\n");
	    String playerName = "Player" + playerNo;
	    nc = new NameComponent(playerName, "");
	    NameComponent path2[] = {nc};
	    ncRef.rebind(path2, this);
	}
	catch (Exception e) {
	    e.printStackTrace();
	}
    }

	/**
	  *pre: no references exist to the instance
	  *post: instance is disconnected from ORB and no longer exists
	  */
    protected void finalize() // we are not guaranteed that initialize was called - jlr
    {
	
	try {
	    System.out.println("Humanplayer.finalize entered");
	    
	    // get the root naming context so that we can unbind
	    org.omg.CORBA.Object objRef = 
		orb.resolve_initial_references("NameService");
	    NamingContext ncRef = NamingContextHelper.narrow(objRef);
	    
	    String playerName = "Player" + playerNo;
	    NameComponent nc = new NameComponent(playerName, "");
	    NameComponent path[] = {nc};
	    ncRef.unbind(path); // unbind name from name registry    
	    
	    //  After orb.disconnect() returns, the ORB will reject incoming remote
	    //  requests for the disconnected servant and will send the 
	    //  exception org.omg.CORBA.OBJECT_NOT_EXIST back to the remote client.
	    orb.disconnect(this);
	}
	catch (Exception e) {
	    e.printStackTrace();
	}
	
    }
    
}
