/*
 * $Id: moddefs.h 4790 2017-11-25 22:00:22Z sloup $
 *
 * Description  : One line description of file.
 * Author       : Vaclav Kyba <mail/Jabber: vaseo1@gmail.com>  <ICQ: 98576293>
 *
 * Purpose      :
 *     Long description of what the file is for.
 */


#ifndef __MOD__DEFS__H__
#define __MOD__DEFS__H__

#include <wx/string.h>
#include <stdint.h>


namespace VRUT
{
	///Server type enum
	enum SERVER_ID
	{
		MANIP_MANAGER   = 1,  ///<Manipulator manager
		IO_MANAGER      = 2,  ///<IO manager
		RENDER_MANAGER  = 3,  ///<Render manager
		GENERAL_MANAGER = 4,  ///<General manager
		SERVER_ID_NONE  = 0xf ///<No server
	};

	///Class names of different servers
	const wxString SERVER_CLASS_NAMES[] =
	{
		wxEmptyString,
		wxT("<EventManager>"),
		wxT("<IOManager>"),
		wxT("<RenderManager>"),
		wxT("<GeneralManager>")
	};

	///Paths to modules from different servers - server has all its module in 1 place (excluding GeneralManager)
	const wxString MODULE_PATHS[] =
	{
		wxEmptyString,
		wxT("modules/manip"),
		wxT("modules/io"),
		wxT("modules/render"),
		wxT("modules")
	};

	///Module types - server can manage more than 1 module type
	enum MODULE_TYPE
	{
		MODULE_TYPE_IO           = 0x01,  ///<Scene import/export module
		MODULE_TYPE_SCENE        = 0x02,  ///<Scene access module
		MODULE_TYPE_RENDER       = 0x04,  ///<Render module
		MODULE_TYPE_MANIPULATOR  = 0x08,  ///<Manipulator module
		MODULE_TYPE_CAMERA       = 0x10,  ///<Camera manipulator module
	};

	///Only modules with same version are supported
	const int MODULES_VER_SUPP = 1;

	///General ID type short
	typedef uint16_t _SHORT_ID;
	///General ID type
	typedef uint32_t _ID;

	typedef _ID NODE_ID;
	///Invalid scene node
	const NODE_ID NODE_ID_NONE = (NODE_ID)~(NODE_ID(0));

	typedef _SHORT_ID RENDER_WINDOW_ID;
	///Invalid render window ID
	const RENDER_WINDOW_ID RENDER_WINDOW_ID_NONE = (RENDER_WINDOW_ID)~(RENDER_WINDOW_ID(0));

	typedef _SHORT_ID SCENE_ID;
	///Invalid scene ID
	const SCENE_ID SCENE_ID_NONE = (SCENE_ID)~(SCENE_ID(0));

	typedef _ID MATERIAL_ID;
	///Invalid material ID
	const MATERIAL_ID MATERIAL_ID_NONE = (MATERIAL_ID)~(MATERIAL_ID(0));

	typedef _ID GEOMETRY_ID;
	///Invalid geometry ID
	const GEOMETRY_ID GEOMETRY_ID_NONE = (GEOMETRY_ID)~(GEOMETRY_ID(0));

	typedef _ID VARIANT_ID;
	///Invalid variant ID
	const VARIANT_ID VARIANT_ID_NONE = (VARIANT_ID)~(VARIANT_ID(0));

	typedef _ID ENVIRONMENT_PROBE_ID;
	///Invalid env probe ID
	const ENVIRONMENT_PROBE_ID ENVIRONMENT_PROBE_ID_NONE = (ENVIRONMENT_PROBE_ID)~(ENVIRONMENT_PROBE_ID(0));

	typedef _ID CLIPPING_PLANE_ID;
	///Invalid variant ID
	const CLIPPING_PLANE_ID CLIPPING_PLANE_ID_NONE = (CLIPPING_PLANE_ID)~(CLIPPING_PLANE_ID(0));

	typedef _SHORT_ID MODULE_HANDLE_ID;
	///Invalid module handle ID
	const MODULE_HANDLE_ID MODULE_HANDLE_ID_NONE = (MODULE_HANDLE_ID)~(MODULE_HANDLE_ID(0));

	typedef _SHORT_ID MODULE_INSTANCE_ID;
	///Invalid module instance ID
	const MODULE_INSTANCE_ID MODULE_INSTANCE_ID_NONE = (MODULE_INSTANCE_ID)~(MODULE_INSTANCE_ID(0));

	///Unique module ID consisting of server type, module handle id and its instance id
	class MODULE_ID
	{
	private:
		///Module id
		unsigned int id;

	public:
		///Constructor
		MODULE_ID(SERVER_ID server = SERVER_ID_NONE, MODULE_HANDLE_ID hid = MODULE_HANDLE_ID_NONE, MODULE_INSTANCE_ID iid = MODULE_INSTANCE_ID_NONE)
		{
			id = (iid & 0xffff) | ( (hid << 16) & 0xfff0000 ) | ( (server << 28) & 0xf0000000 );
		}

		///Constructor
		MODULE_ID(unsigned int _id) : id(_id)	{}

		///Copy constructor
		MODULE_ID(const MODULE_ID & mid)
		{
			id = mid.id;
		}

		///Comparison operator
		bool operator==(const MODULE_ID & mid) const
		{
			return id == mid.id;
		}

		///Comparison operator
		bool operator!=(const MODULE_ID & mid) const
		{
			return !operator==(mid);
		}

		///Get combined ID
		unsigned int GetID() const
		{
			return id;
		}

		///Get server type ID
		SERVER_ID GetServerID() const
		{
			return SERVER_ID( (id >> 28) & 0xf );
		}

		///Get handle ID
		MODULE_HANDLE_ID GetHandleID() const
		{
			return MODULE_HANDLE_ID( (id >> 16) & 0xfff );
		}

		///Get instance ID
		MODULE_INSTANCE_ID GetInstanceID() const
		{
			return MODULE_INSTANCE_ID( id & 0xffff );
		}

		///Get module ID as string
		wxString ToString() const
		{
			return wxString::Format(wxT("%lu:%lu:%lu"), (unsigned long)GetServerID(), (unsigned long)GetHandleID(), (unsigned long)GetInstanceID());
		}
	};

	///Invalid module ID
	const MODULE_ID MODULE_ID_NONE(SERVER_ID_NONE, MODULE_HANDLE_ID_NONE, MODULE_INSTANCE_ID_NONE);
}

#endif
