/** SGX

The   sss    gggg x   x   
     s      g      x x    Engine
      sss   g  gg   x
         s  g   g  x x          Copyright 1995-2009.
     ssss    gggg x   x         Steven Goodwin. All Rights Reserved.
    
This version has been released under the GNU Public License v2.0.

Please see the license files for details.

File: sgx/include/sgx/core/sgxlib/states.hpp

*/

#ifndef SGX_CORE_SGXLIB_STATES_HPP
#define SGX_CORE_SGXLIB_STATES_HPP

//
// A generic template to handle state changes of an arbitrary type
// Note: type must support operator!= and assignment. Must also be
// able to construct a default state.
//
template<typename STATE_TYPE>
class sgxStateTemplate {
public:
	tBOOL		bDirty;
	tBOOL		bUndefined;
	STATE_TYPE	state;

	sgxStateTemplate<STATE_TYPE>()
	{ 
		bDirty = FALSE; 
		bUndefined = TRUE; 
	}
	sgxStateTemplate<STATE_TYPE>(const STATE_TYPE &intial)  
	{ 
		bDirty = TRUE; 
		bUndefined = FALSE; 
		state = intial; 
	}

	SGX_INLINE tBOOL	  isDirty()	const				{ return bDirty; }
	SGX_INLINE tBOOL	  isUndefined()	const			{ return bUndefined; }
	SGX_INLINE void		  setState(STATE_TYPE new_state)
	{ 
		if (bUndefined) 
		{ 
			state = new_state; 
			bDirty = TRUE; 
			bUndefined = FALSE; 
		}
		else if (state != new_state) 
		{ 
			state = new_state; 
			bDirty = TRUE; 
		} 
	}
	SGX_INLINE STATE_TYPE getState() const
	{ 
		return state; 
	}
	SGX_INLINE tBOOL	apply()		
	{ 
		if (bDirty) 
		{ 
			doApply(); 
			bDirty = FALSE; 
			return TRUE; 
		} 
		return FALSE; 
	}
	SGX_INLINE tBOOL	apply(STATE_TYPE new_state)		
	{ 
		setState(new_state); 
		return apply(); 
	}
	SGX_INLINE void		reapply()	{ forceDirty(); apply(); }
	SGX_INLINE void		forceClean(){ bDirty = FALSE; }
	SGX_INLINE void		forceDirty(){ bDirty = TRUE; }

	virtual    tBOOL	doApply()	{ return bDirty; }
};

//
// Basic types
//
typedef sgxStateTemplate<tUINT32>		sgxState;
typedef sgxStateTemplate<tBOOL>			sgxStateBool;
typedef sgxStateTemplate<void *>		sgxStatePtr;
typedef sgxStateTemplate<tREAL32>		sgxStateReal32;
typedef sgxStateTemplate<tREAL64>		sgxStateReal64;

#endif	/* SGX_STATES_HPP */

