function StateMachine(){
	var
		currentState, previousState;
		
	this.setState = setState;
	this.transite = transite;
	this.goBack = goBack;
	this.addState = addState;
	this.addStateObj = addStateObj;
	this.setStateAttributes = setStateAttributes;
	this.setTransition = setTransition;

	var
		states = new Array();
	var
		attributes = new Array();

	function addState(_stateName, _initFkn, _exitFkn){
		//debug("addState: "+_stateName);
		var
			state = new Object();
		state.init = _initFkn;
		state.exit = _exitFkn;
		state.transitions = new Array();
		
		this.addStateObj(_stateName, state);
	}
	
	function addStateObj(_stateName, _state){
		_state.name = _stateName;
		states[_stateName] = _state;
	}
	
	function setStateAttributes(_state, _attr){
		if (states[_state])
			states[_state].attributes = _attr;
		else
			error("state: "+_state+" not defined!");
	}
	
	function setTransition(_state, _transitionName, _targetState, _checkFkt){
		//debug("setTransition state: "+_state+' transition: '+_transitionName);
		if (states[_state]){
			var
				trans = new Object();
			trans.src = _state;
			trans.name = _transitionName;
			trans.check = _checkFkt;
			trans.target = _targetState;
			
			states[_state].transitions[_transitionName] = trans;
		}
	}
	
	function setState(_state){
		debug("setState:"+ _state);

		if (currentState == _state)
			return;

		// call exit function ?
		if (currentState && states[currentState] && states[currentState].exit){
			debug("call exit on state: "+states[currentState].name);
			states[currentState].exit(this);
		}
		// call init function ?
		if (states[_state]){ 
			if (states[_state].init){
				debug("call init on state:"+states[_state].name);
				states[_state].init(this);
			}
		}else
			error('state: '+_state+' not defined!');

		previousState = currentState;
		currentState = _state;
	}
	function transite(_transitionName){
		//debug('transite state:'+currentState+' transition: '+_transitionName);
		var
			state = states[currentState];
			
		if (state && state.transitions[_transitionName]){
			var target = state.transitions[_transitionName].target;
			
			if (state.transitions[_transitionName].check == null || (target = state.transitions[_transitionName].check(this))){
				this.setState(target);
				return true;
			}
		}else
			error('transition: '+_transitionName+' not found in state: '+currentState);
		
		return false;
	}
		
	function goBack(){
		if (previousState)
			this.setState(previousState);
	}	
}
