//-----------------------------------------------------------------------------------------------
// EngineSubsystem.hpp
//
#pragma once
#ifndef include_EngineSubsystem
#define include_EngineSubsystem

//-----------------------------------------------------------------------------------------------
#include "Engine/Core/EngineCommon.hpp"


/////////////////////////////////////////////////////////////////////////////////////////////////
enum EngineSubsystemState
{
	ENGINE_SUBSYSTEM_STATE_MISSING,			// Compiled out or disabled; not requested by game
	ENGINE_SUBSYSTEM_STATE_INACTIVE,		// Not currently instantiated, but probably will be
	ENGINE_SUBSYSTEM_STATE_CONSTRUCTING,	// Running its constructor (should be lightweight)
	ENGINE_SUBSYSTEM_STATE_CONSTRUCTED,		// Finished constructing, but not yet started up
	ENGINE_SUBSYSTEM_STATE_STARTING_UP,		// Running its StartUp() method (heavy initialization)
	ENGINE_SUBSYSTEM_STATE_READY,			// Finished starting up, ready for use
	ENGINE_SUBSYSTEM_STATE_SHUTTING_DOWN,	// Running its ShutDown() method (heavy destruction)
	ENGINE_SUBSYSTEM_STATE_DESTRUCTING,		// Running its destructor (should be lightweight)
	NUM_ENGINE_SUBSYSTEM_STATES
};


/////////////////////////////////////////////////////////////////////////////////////////////////
class EngineSubsystem
{
public:
	EngineSubsystem()
		: m_state( ENGINE_SUBSYSTEM_STATE_CONSTRUCTING )
	{}

	virtual ~EngineSubsystem() {}

	virtual const char* GetName() { return "UNNAMED SYSTEM!"; }
//	virtual void PreConfigure( const NamedProperties& configParams ) { UNUSED( configParams ); }
	virtual void StartUp() {}
	virtual void BeginFrame() {}
	virtual void EndFrame() {}
	virtual void ShutDown() {}
	virtual bool ProcessSystemEventPreGame( const SystemEvent& systemEvent );
	virtual bool ProcessSystemEventPostGame( const SystemEvent& systemEvent );
	EngineSubsystemState GetState() const { return m_state; }
	bool IsIncluded() const { return m_state != ENGINE_SUBSYSTEM_STATE_MISSING; } // Whether this subsystem is used by this game
	bool IsConstructed() const { return (m_state >= ENGINE_SUBSYSTEM_STATE_CONSTRUCTED) && (m_state <= ENGINE_SUBSYSTEM_STATE_READY); } // Whether the subsystem physically exists
	bool IsReady() const { return m_state == ENGINE_SUBSYSTEM_STATE_READY; } // Whether the subsystem is fully operational

private:
	EngineSubsystemState	m_state;

	friend class Application;
};


//-----------------------------------------------------------------------------------------------
inline VIRTUAL bool EngineSubsystem::ProcessSystemEventPreGame( const SystemEvent& systemEvent )
{ 
	UNUSED( systemEvent );
	return false;
}


//-----------------------------------------------------------------------------------------------
inline VIRTUAL bool EngineSubsystem::ProcessSystemEventPostGame( const SystemEvent& systemEvent )
{ 
	UNUSED( systemEvent );
	return false;
}



#endif // include_EngineSubsystem
