#ifndef _RUGAIA_BASE_
#define _RUGAIA_BASE_

// Base types
#include "../Collision/RuCollisionHierarchy_Base.h"
#include "../PathEngine/RuPathHierarchy_Base.h"

#pragma unmanaged

// ************************************************************************************************************************************************************

inline INT32 RuGaia_ZoneFlags_GetID(UINT32 zoneFlags)
{
	return zoneFlags & 0x000FFFFF;
}

inline UINT32 RuGaia_ZoneFlags_SetID(UINT32 zoneFlags, INT32 zoneID)
{
	return (zoneFlags & ~0x000FFFFF) | (zoneID & 0x000FFFFF);
}

inline INT32 RuGaia_ZoneFlags_IsFoliage(UINT32 zoneFlags)
{
	return zoneFlags & 0x00800000;
}

inline INT32 RuGaia_ZoneFlags_IsLocked(UINT32 zoneFlags)
{
	return zoneFlags & 0x00400000;
}

inline INT32 RuGaia_ZoneFlags_IsWalkable(UINT32 zoneFlags)
{
	return zoneFlags & 0x00100000;
}

inline INT32 RuGaia_ZoneFlags_IsWaterSurface(UINT32 zoneFlags)
{
	return zoneFlags & 0x00200000;
}

// ************************************************************************************************************************************************************

class CRuGaia_ZoneDescriptor
{
public:
	INT32									m_id;													//!< Zone ID
	INT32									m_timeGroup;											//!< Time group
	INT32									m_weatherGroup;											//!< Weather group
	char*									m_name;													//!< Zone name

	// Color setup
	DWORD									m_color_Primary;
	DWORD									m_color_Secondary;
	DWORD									m_color_Ambient;
	DWORD									m_color_Specular;
	DWORD									m_color_Fog;

	// Fog setup
	REAL									m_fog_Start;
	REAL									m_fog_End;

	// Lighting direction setup
	REAL									m_theta_Standard;
	REAL									m_phi_Standard;

	REAL									m_theta_Specular;
	REAL									m_phi_Specular;

	// Sky and cloud setup
	DWORD									m_cloud_HorizonColor;
	DWORD									m_cloud_OverheadColor;
	INT32									m_cloud_HorizonCount;
	INT32									m_cloud_OverheadCount;

	char*									m_skyGradientTextureName;								//!< Texture name to use for sky gradient
	char*									m_horizonCloudTextureName;
	char*									m_overheadCloudTextureName;
	DWORD									m_cloudMode;											//!< Cloud display mode

	char*									m_customSkyBoxName;										//!< Name of the custom skybox to use in place of the standard one
	REAL									m_frameRateMultiplier;									//!< Multiplier for the frame rate

public:
											CRuGaia_ZoneDescriptor()
											{
												m_name = NULL;
												m_fog_Start = 200.0f;
												m_fog_End = 800.0f;
												m_theta_Standard = 15.0f;
												m_phi_Standard = 35.0f;
												m_theta_Specular = 15.0f;
												m_phi_Specular = 15.0f;
												m_cloud_HorizonColor = 0xFFFFFFFF;
												m_cloud_OverheadColor = 0xFFFFFFFF;
												m_cloud_HorizonCount = 0;
												m_cloud_OverheadCount = 0;
												m_skyGradientTextureName = NULL;
												m_horizonCloudTextureName = NULL;
												m_overheadCloudTextureName = NULL;
												m_customSkyBoxName = NULL;
												m_frameRateMultiplier = 1.0f;
											}

											~CRuGaia_ZoneDescriptor()
											{
												delete[] m_name;
												delete[] m_skyGradientTextureName;
												delete[] m_horizonCloudTextureName;
												delete[] m_overheadCloudTextureName;
												delete[] m_customSkyBoxName;
											}

	const char*								GetName() const
	{
		if(m_name)
		{
			return m_name;
		}

		return "";
	}

	void									SetName(const char *name)
	{
		delete[] m_name;
		
		m_name = ruNEW char [strlen(name) + 1];
		strcpy(m_name, name);
	}

	void									SetSkyGradientTextureName(const char *skyGradientTextureName)
											{
												delete[] m_skyGradientTextureName;

												if(skyGradientTextureName)
												{
													m_skyGradientTextureName = ruNEW char [strlen(skyGradientTextureName) + 1];
													strcpy(m_skyGradientTextureName, skyGradientTextureName);
												}
												else
												{
													m_skyGradientTextureName = NULL;
												}
											}

	void									SetHorizonCloudTextureName(const char *horizonCloudTextureName)
											{
												delete[] m_horizonCloudTextureName;

												if(horizonCloudTextureName)
												{
													m_horizonCloudTextureName = ruNEW char [strlen(horizonCloudTextureName) + 1];
													strcpy(m_horizonCloudTextureName, horizonCloudTextureName);
												}
												else
												{
													m_horizonCloudTextureName = NULL;
												}
											}

	void									SetOverheadCloudTextureName(const char *overheadCloudTextureName)
											{
												delete[] m_overheadCloudTextureName;

												if(overheadCloudTextureName)
												{
													m_overheadCloudTextureName = ruNEW char [strlen(overheadCloudTextureName) + 1];
													strcpy(m_overheadCloudTextureName, overheadCloudTextureName);
												}
												else
												{
													m_overheadCloudTextureName = NULL;
												}
											}

	void									SetCustomSkyBoxName(const char *customSkyBoxName)
											{
												delete[] m_customSkyBoxName;

												if(customSkyBoxName)
												{
													m_customSkyBoxName = ruNEW char [strlen(customSkyBoxName) + 1];
													strcpy(m_customSkyBoxName, customSkyBoxName);
												}
												else
												{
													m_customSkyBoxName = NULL;
												}
											}

	void									CopySettings(const CRuGaia_ZoneDescriptor &zoneDesc);
	CRuGaia_ZoneDescriptor&					operator=(const CRuGaia_ZoneDescriptor &zoneDesc);
};

// ************************************************************************************************************************************************************

class CRuGaia_Base : public IRuCollisionHierarchy
{
	ruRTTI_DECLARE
	ruHEAP_DECLARE
	ruCLASSGUID_DECLARE

protected:

public:
	virtual										~CRuGaia_Base();

	virtual BOOL								Save() = 0;

	virtual float								GetGridSpacing() const = 0;
	virtual const char*							GetSourceResourceName() const = 0;
	
	virtual INT32								GetNumZoneDescriptors() const = 0;

	virtual const CRuGaia_ZoneDescriptor*		GetZoneDescriptor(INT32 id, INT32 timeGroup, INT32 weatherGroup) const = 0;
	virtual const CRuGaia_ZoneDescriptor*		GetZoneDescriptorByIndex(INT32 index) const = 0;

	virtual BOOL								SetZoneDescriptor(const CRuGaia_ZoneDescriptor *zoneDesc) = 0;
	virtual BOOL								RemoveZoneDescriptor(const CRuGaia_ZoneDescriptor *zoneDesc) = 0;
	virtual BOOL								RemoveZoneDescriptorAtIndex(INT32 index) = 0;

	virtual BOOL								SetZoneName(INT32 id, const char *zoneName) = 0;
	virtual BOOL								SetZoneID(INT32 oldID, INT32 newID) = 0;

	virtual IRuPathHierarchy_Base*				GetPathHierarchy() = 0;
};

// ************************************************************************************************************************************************************

#pragma managed

#endif
