/**
 * $Id: MetaforgeAIBase.java,v 1.4 2007/11/26 07:11:11 chip Exp $
 * $Source: /opt/repository/metaforge/dev/java/webstratego/src/com/metaforge/olg/ws/ai/MetaforgeAIBase.java,v $
 * $Revision: 1.4 $
 * $Date: 2007/11/26 07:11:11 $
 */
package com.metaforge.olg.ws.ai;

import java.util.Properties;

/**
 * This class implements the Stratego AI interface, providing default implementations for many
 * methods. This reduces the amount of work needed to create an AI implementation. Certain key
 * methods must be implemented by the developer, and the developer may also wish to override some of
 * the methods defined in this base class.
 * 
 * @author <a href="mailto:chip@metaforge.net">Chip McVey</a>
 */
public abstract class MetaforgeAIBase implements MetaforgeStrategoAI {

  /**
   * Default constructor. No-op.
   */
  public MetaforgeAIBase() {
    // no-op
  }

  /**
   * No-op stub method.
   * 
   * @see com.metaforge.olg.ws.ai.MetaforgeStrategoAI#abortGame(int)
   */
  public void abortGame(int reason) {
    // no-op
  }

  /**
   * Must be implemented.
   * 
   * @see com.metaforge.olg.ws.ai.MetaforgeStrategoAI#createAISetup(int)
   */
  public abstract void createAISetup(int color);

  /**
   * Stub method that returns false, telling the bot not to create a game.
   * 
   * @return false
   * @see com.metaforge.olg.ws.ai.MetaforgeStrategoAI#createGame()
   */
  public boolean createGame() {
    return false;
  }

  /**
   * No-op stub method.
   * 
   * @see com.metaforge.olg.ws.ai.MetaforgeStrategoAI#endGame
   */
  public void endGame(int result, int reason) {
    // no-op
  }

  /**
   * No-op stub method.
   * 
   * @see com.metaforge.olg.ws.ai.MetaforgeStrategoAI#gameCreated()
   */
  public void gameCreated() {
    // no-op
  }

  /**
   * No-op stub method.
   * 
   * @see com.metaforge.olg.ws.ai.MetaforgeStrategoAI#gameJoined()
   */
  public void gameJoined() {
    // no-op
  }

  /**
   * Must be implemented.
   * 
   * @see com.metaforge.olg.ws.ai.MetaforgeStrategoAI#getAIMove(int[])
   */
  public abstract void getAIMove(byte[] move);

  /**
   * Must be implemented.
   * 
   * @see com.metaforge.olg.ws.ai.MetaforgeStrategoAI#getAISetupPiece(int, int)
   */
  public abstract int getAISetupPiece(int x, int y);

  /**
   * Defaults to creating a classic game.
   * 
   * @return GAMEMODE_CLASSIC
   * @see #GAMEMODE_CLASSIC
   * @see com.metaforge.olg.ws.ai.MetaforgeStrategoAI#getCreateGameMode()
   */
  public int getCreateGameMode() {
    return GAMEMODE_CLASSIC;
  }

  /**
   * Defaults to returning OPTION_OFF for any option.
   * 
   * @return OPTION_OFF
   * @see com.metaforge.olg.ws.ai.MetaforgeStrategoAI#getCreateGameOption(int)
   */
  public int getCreateGameOption(int option) {
    return OPTION_OFF;
  }

  /**
   * Defaults to send no message.
   * 
   * @return null
   * @see com.metaforge.olg.ws.ai.MetaforgeStrategoAI#getPostGameChat()
   */
  public String getPostGameChat() {
    return null;
  }

  /**
   * Defaults to send no message.
   * 
   * @return null
   * @see com.metaforge.olg.ws.ai.MetaforgeStrategoAI#getPreGameChat()
   */
  public String getPreGameChat() {
    return null;
  }
  
  public String getPublicName() {
    return "MetaforgeAIBase"; //$NON-NLS-1$
  }

  /**
   * Defaults to ignoring the illegal move notification. You probably want to override this method
   * and actually handle the illegal move.
   * 
   * @see com.metaforge.olg.ws.ai.MetaforgeStrategoAI#illegalMove(int[])
   */
  public byte illegalMove(byte[] move) {
    // no-op
    return MetaforgeStrategoAI.AI_SPECIAL_MOVE_RESIGN;
  }

  /**
   * Must be implemented.
   * 
   * @see com.metaforge.olg.ws.ai.MetaforgeStrategoAI#illegalSetup(int, int, int)
   */
  public abstract void illegalSetup(int x, int y, int rank);

  /**
   * Defaults to return true, such that initialization is successful.
   * 
   * @return true
   * @see com.metaforge.olg.ws.ai.MetaforgeStrategoAI#initialize()
   */
  public boolean initialize(Properties props, String password) {
    return true;
  }

  /**
   * Defaults to a no-op.
   * 
   * @see com.metaforge.olg.ws.ai.MetaforgeStrategoAI#initializeGame()
   */
  public void initializeGame() {
    // no-op
  }

  /**
   * Defaults to return false, so that no game is joined.
   * 
   * @return false
   * @see com.metaforge.olg.ws.ai.MetaforgeStrategoAI#joinGame()
   */
  public boolean joinGame() {
    return false;
  }

  /**
   * Defaults to return false, so that the new game is ignored.
   * 
   * @return false
   * @see com.metaforge.olg.ws.ai.MetaforgeStrategoAI#newGameCreated(java.lang.String, int)
   */
  public boolean newGameCreated(String owner, int mode) {
    return false;
  }

  /**
   * Defaults to return false, indicating no interest in knowing further game options for potential
   * game to join.
   * 
   * @return false
   * @see com.metaforge.olg.ws.ai.MetaforgeStrategoAI#newGameOption(int, int)
   */
  public boolean newGameOption(int option, int value) {
    return false;
  }

  /**
   * No-op stub method.
   * 
   * @see com.metaforge.olg.ws.ai.MetaforgeStrategoAI#setAIUsername(java.lang.String)
   */
  public void setAIUsername(String aiUsername) {
    // no-op
  }

  /**
   * Defaults to return false, indicating the AI does not accept custom piece counts.
   * 
   * @return false
   * @see com.metaforge.olg.ws.ai.MetaforgeStrategoAI#setCustomPieceCount(int, int, int, int, int,
   *      int, int, int, int, int, int, int)
   */
  public boolean setCustomPieceCount(int marshals, int generals, int colonels, int majors,
      int captains, int lieutenants, int sergeants, int miners, int scouts, int spies, int bombs,
      int flags) {
    return false;
  }

  /**
   * No-op stub method.
   * 
   * @see com.metaforge.olg.ws.ai.MetaforgeStrategoAI#setGameAids(boolean)
   */
  public void setGameAids(boolean value) {
    // no-op
  }

  /**
   * Returns true if the game mode is classic, false otherwise. This provides the behavior of an AI
   * which can play classic, but no other modes.
   * 
   * @return <em>true</em> if classic mode, <em>false</em> otherwise.
   * @see com.metaforge.olg.ws.ai.MetaforgeStrategoAI#setGameMode(int)
   */
  public boolean setGameMode(int mode) {
    return (mode == GAMEMODE_CLASSIC);
  }

  /**
   * Must be implemented.
   * 
   * @see com.metaforge.olg.ws.ai.MetaforgeStrategoAI#setGameOption(int, int)
   */
  public abstract boolean setGameOption(int option, int value);

  /**
   * Defaults to return true, as most AIs will be relatively unaffected by turn time limit and
   * should be able to accept just about any value.
   * 
   * @see com.metaforge.olg.ws.ai.MetaforgeStrategoAI#setMoveTimeLimit(int)
   */
  public boolean setMoveTimeLimit(int turnTimeLimitSecs) {
    return true;
  }

  /**
   * Must be implemented.
   * 
   * @see com.metaforge.olg.ws.ai.MetaforgeStrategoAI#setOpponentSetupPiece(int, int)
   */
  public abstract void setOpponentSetupPiece(int x, int y);

  /**
   * No-op stub method.
   * 
   * @see com.metaforge.olg.ws.ai.MetaforgeStrategoAI#setOpponentUsername(java.lang.String)
   */
  public void setOpponentUsername(String opponentName) {
    // no-op
  }

  /**
   * Defaults to accepting whatever level is specified.
   * 
   * @see com.metaforge.olg.ws.ai.MetaforgeStrategoAI#setSkillLevel(int)
   */
  public boolean setSkillLevel(int level) {
    return true;
  }

  /**
   * No-op stub method.
   * 
   * @see com.metaforge.olg.ws.ai.MetaforgeStrategoAI#startGame()
   */
  public void startGame() {
    // no-op
  }

  /**
   * Must be implemented.
   * 
   * @see com.metaforge.olg.ws.ai.MetaforgeStrategoAI#submitAIMoveResult(int, int)
   */
  public abstract byte submitAIMoveResult(int rank, int result);

  /**
   * Must be implemented.
   * 
   * @see com.metaforge.olg.ws.ai.MetaforgeStrategoAI#submitOpponentMove(int, int, int, int, int,
   *      int)
   */
  public abstract byte submitOpponentMove(int xo, int yo, int xf, int yf, int rank, int result);

  /**
   * No-op stub method.
   * 
   * @see com.metaforge.olg.ws.ai.MetaforgeStrategoAI#terminate()
   */
  public void terminate() {
    // no-op
  }
  
  public void postGameLogOriginalOpponentSetup(int x, int y, int rank) {
    // no-op
  }
  
  public void postGameLogClose() {
    // no-op
  }

  public void postGameLogStart() {
    // no-op
  }

}
