package senseiTests.domainsTest;

import java.util.Iterator;
import java.util.Random;
import java.util.Vector;

//import sensei.util.Debug;

/**
 * The state is given by a collection of strings. This class handles any operation
 * related to the state
 */
class StateKeeper
{
  public StateKeeper()
  {
    validated=false;
    state=new Vector();
    clear();
  }

  public void validateState()
  {
    validated=true;
  }

  public boolean isValidatedState()
  {
    return validated;
  }

  /**
   * Generates a random state
   */
  public synchronized void generateRandomState()
  {
    validateState();
    state.clear();
    int n = generator.nextInt(MAX_GENERATED_SUBSTATES-MIN_GENERATED_SUBSTATES) + MIN_GENERATED_SUBSTATES;
    while(n-->0)
      addSubState(generateRandomSubState());
  }

  /**
   * Generates a random substate
   */
  public String generateRandomSubState()
  {
    return new String(COLORS[generator.nextInt(COLORS.length)]);
  }

  /**
   * Sets the state
   */
  public synchronized void setState(String subStates[])
  {
    state.clear();
    int len=subStates.length;
    for(int i=0;i<len;i++)
      addSubState(subStates[i]);
  }

  /**
   * Adds a substate to the current state
   */
  public synchronized void addSubState(String subState)
  {
    state.add(subState);
    stateAsString=null;
  }

  /**
   * Removes the last substate, returns true if there was something to be removed
   */
  public synchronized boolean removeSubState()
  {
    int length=state.size();
    boolean ret = length>0;
    if (ret)
    {
      state.removeElementAt(length-1);
      stateAsString=null;
    }
    return ret;
  }

  /**
   * Returns a valid and random index
   */
  public int getValidRandomSubStateIndex()
  {
    return generator.nextInt(state.size());
  }

  /**
   * The state can not be changed at once. It is possible with this method to specify a specific
   * substate, including as well the maximum number of substates, that can change dynamically
   */
  public synchronized void setSubState(String subState, int which, int maxSubStates)
  {
    //Debug.assert((which>=0) && (maxSubStates>which) , Consts.AREA, "StateKeeper::setSubState::1::"+which+"::"+maxSubStates);

    while (maxSubStates>state.size())
      state.add("");
    while (maxSubStates<state.size())
      state.remove(state.size()-1);
    state.setElementAt(subState, which);
    stateAsString=null;
  }

  /**
   * Returns a string representation of the object
   */
  public String toString()
  {
    if(stateAsString==null)
    {
      StringBuffer buffer = new StringBuffer();
      Iterator it=state.iterator();
      if (it.hasNext())
      {
        buffer.append(it.next());
        while(it.hasNext())
        {
          buffer.append(" - ");
          buffer.append(it.next());
        }
      }
      stateAsString = buffer.toString();
    }
    return stateAsString;
  }

  /**
   * Return the number of substates
   */
  public synchronized int getNumberOfSubStates()
  {
    return state.size();
  }

  /**
   * Returns the substate specified
   */
  public synchronized String getSubState(int which)
  {
    return (which>=0) && (which<state.size())? (String)(state.get(which)) : null;
  }

  /**
   * Returns the state
   */
  public synchronized String[] getSubStates()
  {
    int len=state.size(), i=0;
    String[] ret = new String[len];
    Iterator it=state.iterator();
    while(it.hasNext())
      ret[i++]=(String)it.next();
    return ret;
  }

  /**
   * Resets the substates information
   */
  public synchronized void clear()
  {
    stateAsString=null;
    state.clear();
  }

  String stateAsString;
  Vector state;
  boolean validated;

  static Random generator = new Random();
  final static int MIN_GENERATED_SUBSTATES = 2; //minimum number of substates to generate
  final static int MAX_GENERATED_SUBSTATES = 10; //maximum number of substates to generate
  final static String COLORS[];
  static
  {
    COLORS=new String[10];
    COLORS[0] = new String("RED");
    COLORS[1] = new String("YELLOW");
    COLORS[2] = new String("BLUE");
    COLORS[3] = new String("MAGENTA");
    COLORS[4] = new String("GREEN");
    COLORS[5] = new String("PINK");
    COLORS[6] = new String("WHITE");
    COLORS[7] = new String("BLACK");
    COLORS[8] = new String("CYAN");
    COLORS[9] = new String("ORANGE");
  }
};