package bwyap.statemachine;

import java.util.HashMap;

/**
 * A basic state machine which provide the {@code update()} method for each state.
 * @author bwyap
 *
 * @param <T> A subclass of {@code State} 
 */
public class StateMachine<T extends State> {
	
	protected State currentState;
	protected HashMap<String, State> states = new HashMap<String, State>();
	
	/**
	 * Initialize the state machine's default states.
	 */
	public void init() {
		
	}
	
	/**
	 * Validate a state transition.
	 * By default, this returns true.
	 * Override this method to implement custom transition validation.
	 * @param currentState
	 * @param nextState
	 * @return
	 */
	public boolean validateStateTransition(State currentState, String nextState) {
		return true;
	}
	
	/**
	 * Add a state to the state machine
	 * @param name
	 * @param state
	 */
	public void addState(String name, State state) {
		states.put(name, state);
	}
	
	/**
	 * Get the name of the current state
	 * @return
	 */
	public String getCurrentStateName() {
		if (currentState != null) {
			return currentState.getName();
		}
		else return "null";
	}
	
	/**
	 * Remove a state from the state machine
	 * @param name
	 */
	public void removeState(String name) {
		states.remove(name);
	}
	
	/**
	 * Change the current state to the one specified by the name.
	 * If no such state exists, it is set to null.
	 * @param name
	 */
	public void changeState(String name) {
		if (validateStateTransition(currentState, name)) {
			if (currentState != null) currentState.cleanupState();
			if (states.containsKey(name)) {
				currentState = states.get(name);
				currentState.initState();
				System.out.println("CHANGING STATE: " + name);
			}
			else {
				// no state 
				currentState = null;
			}
		}
		else {
			System.err.println("Invalid state transition: <" + currentState.getName() + "> to <" + name + ">");
		}
	}
	
	/**
	 * Update the current state.
	 * @param timeElapsed 
	 */
	public void update(float timeElapsed) {
		if(currentState != null) {
			currentState.updateState(timeElapsed);
			if(currentState.nextState() != null) {
				changeState(currentState.nextState());
			}
		}
	}
	
}

@@ -1640,26 +1640,36 @@
 %09%09%09%09
-System.out.
+if (getDebugMode()) 
 print
-ln
+Out
 (%22CH
@@ -1775,26 +1775,36 @@
 %0A%09%09%09
-System.err.
+if (getDebugMode()) 
 print
-ln
+Err
 (%22In
@@ -2152,23 +2152,23 @@
 te());%0A%09%09%09%7D%0A
-
 %09%09%7D%0A%09%7D%0A%09%0A%7D%0A
@@ -2165,10 +2165,724 @@
 %09%7D%0A%09%7D%0A%09%0A
+%09/**%0A%09 * Get the debug mode for the state machine. %0A%09 * By default, this is %7B@code true%7D so all debug information will be printed. %0A%09 * @return%0A%09 */%0A%09protected boolean getDebugMode() %7B%0A%09%09return true;%0A%09%7D%0A%09%0A%09/**%0A%09 * Log a message to the console.%0A%09 * By default this logs the message to %7B@code System.out%7D. %0A%09 * Override this method to direct the message.%0A%09 * @param message%0A%09 */%0A%09protected void printOut(String message) %7B%0A%09%09System.out.println(message);%0A%09%7D%0A%09%0A%09/**%0A%09 * Log am error message to the console.%0A%09 * By default this logs the message to %7B@code System.err%7D. %0A%09 * Override this method to direct the message.%0A%09 * @param message%0A%09 */%0A%09protected void printErr(String message) %7B%0A%09%09System.err.println(message);%0A%09%7D%0A%09%0A
 %7D%0A

Modify StateMachine to have inheritable logging methods