package Cluedo.g1;

import Cluedo.*;
import ui.*;
import java.util.*;
import java.io.*;
import java.awt.Color;

/**
 * A base implementation of a player.  Provides definitions for methods common
 * to all of our players and insulates against gratuitous "throws Exception"
 * clauses in the Cluedo class.
 * 
 * @author Mark Ayzenshtat
 * @author Hanhua Feng
 * @author Stephen Lee
 */
public abstract class PlayerBase implements IFCPlayer {
	private static final Color kColor = Color.RED;
	private static final String kName = "Scarlet Fever";

	protected Cluedo mClue;
	private int mNumCards;
	private int mNumCardsPerPlayer;
	private int mNumPlayers;
	private int mNumHiddenCards;
	private int mMyIndex;
	private int[] mMyCards;
	private int mMaxNumRounds;
	private int mLastTurn;

	public void register(Cluedo iClue) {
		try {
			mClue = iClue;
			mNumCards = iClue.numCards();
			mNumCardsPerPlayer = iClue.numCardsPerPlayer();
			mNumPlayers = iClue.numPlayers();
			mNumHiddenCards = iClue.numHiddenCards();
			mMyIndex = iClue.indexOf(this);
			mMyCards = iClue.getPlayerList(mMyIndex, this);			
			mMaxNumRounds = iClue.maxRounds();
			mLastTurn = -1;
		} catch (Exception ex) {
			// should never happen
			System.err.println("Exception thrown: " + ex);
		}
	}	
	
	/**
	 * Return our name.
	 */
	public String name() throws Exception {
		return kName;
	}
	
	/**
	 * Return our color.
	 */
	public Color color() throws Exception {
		return kColor;
	}
	
	public boolean interactive() throws Exception {
		return false;
	}
	
	/**
	 * Make a final guess. 
	 */
	protected Move guess(int[] iCardsToGuess) throws Exception {
		return new Move(IFCPlayer._CGUESS, iCardsToGuess);
	}
	
	/**
	 * Interrogate a player.
	 */
	protected Move interrogate(int[] iCards, int iTargetIndex) throws Exception {
		return new Move(IFCPlayer._CINTERROGATION, iCards, iTargetIndex);
	}
	
	public MoveResult getMoveResult(int iIndex) {
		try {
			return mClue.history(iIndex);
		} catch (Exception ex) {
			// should never happen
			System.err.println("Exception thrown: " + ex);
			return null;
		}
	}
	
	protected static boolean cardsIntersect(int[] iCardList1, int[] iCardList2) {
		for (int i = 0, j = 0; i < iCardList1.length && j < iCardList2.length; ) {
			if (iCardList1[i] == iCardList2[j]) {
				return true;
			}
			
			if (iCardList1[i] < iCardList2[j]) {
				i++;
			} else {
				j++;
			}
		}
		
		return false;
	}
	
	/**
	 * @return
	 */
	public int[] getMyCards() {
		return mMyCards;
	}

	/**
	 * @return
	 */
	public int getMyIndex() {
		return mMyIndex;
	}

	/**
	 * @return
	 */
	public int getNumCards() {
		return mNumCards;
	}

	/**
	 * @return
	 */
	public int getNumCardsPerPlayer() {
		return mNumCardsPerPlayer;
	}

	/**
	 * @return
	 */
	public int getNumHiddenCards() {
		return mNumHiddenCards;
	}

	/**
	 * @return
	 */
	public int getNumPlayers() {
		return mNumPlayers;
	}

	/**
	 * @return
	 */
	public int getRoundNumber() {
		try {
			return mClue.currRound();
		} catch (Exception ex) {
			// should never happen
			System.err.println("Exception thrown: " + ex);
			return 0;
		}
	}
	
	/**
	 * @return
	 */
	public int getMaxNumRounds() {
		return mMaxNumRounds;
	}
	
	/**
	 * @return Returns the lastTurn.
	 */
	public int getLastTurn() {
		return mLastTurn;
	}

	/**
	 * @param iLastTurn The lastTurn to set.
	 */
	public void setLastTurn(int iLastTurn) {
		mLastTurn = iLastTurn;
	}
}
