//------------------------------------------------------------------------------
// File   : ToolsAVP_Entity_GamePlayVolume.h
// Author : Gareth Thomas
// Date   : 22 / 10 / 07
// Copyright (C) 2007 Rebellion, All Rights Reserved.
//------------------------------------------------------------------------------

#ifdef ASURA_USE_PRAGMA_ONCE
#pragma once
#endif   // ifdef ASURA_USE_PRAGMA_ONCE
#ifndef __TOOLSAVP_ENTITY_GAMEPLAYVOLUME_H__
#define __TOOLSAVP_ENTITY_GAMEPLAYVOLUME_H__ 1

//------------------------------------------------------------------------------
// Include files...
//------------------------------------------------------------------------------
#include "Interface/Asura_Dialog.h"
#include "Entity/Tools_Entity_StartPoint.h"
#include "Entity/Tools_Entity_Object.h"
#include "Objects/Tools_Object_System.h"
#include "Objects/Tools_VolumeBaseEdit_Object.h"
#include "Objects/Tools_VolumeGroupEdit_Controller.h"

#include "Entity/GamePlayVolume/AVP_ServerEntity_GamePlayVolume.h"


//------------------------------------------------------------------------------
// Forward class declarations...
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
// Class declarations
//------------------------------------------------------------------------------
class Tools_VolumeGroupEdit_Controller;
class ToolsAVP_GamePlayVolume_VolumeEdit_Controller;

//------------------------------------------------------------------------------
// Class        : ToolsAVP_Entity_GamePlayVolume
// Author       : Gareth Thomas
// Date         : 22 / 10 / 07
// Description  : Class to handle Tools editing of Spawn Points.
//------------------------------------------------------------------------------
class ToolsAVP_Entity_GamePlayVolume : public Tools_Entity_Object
{

public:

	enum { MAX_LINKED_GAMEPLAYVOLUMES = 6};

	// Public Construction / Deconstruction functions...
	ToolsAVP_Entity_GamePlayVolume								(Asura_Entity* pxEntity);
	virtual ~ToolsAVP_Entity_GamePlayVolume						(void);

	// Public Static functions
	static void				Project_Create						(void);
	static void				Create								(void);
	static Tools_Object*	Create								(Asura_Entity* pxEntity);

	// Public Overridden Virtual Functions...
	virtual void			OnSelection							(void);
	virtual void			OnDeselection						(void);
	virtual void			Update								(void);
	virtual void			Render								(void);
	virtual const char*		GetTypeDescription					(void)								{return("Game Play Volume");}
	virtual void			UpdatePositionInAsuraData			(bool bUpdateLinkedObjects);
	virtual void			AddOverlayControls					(Asura_Overlay* pxOverlay, Asura_Vector_2& xOffset);
	virtual void			UpdateWhileSelected					(void);
	virtual bool			HandlesThisMessage					(int iMessageID);
	virtual bool			Verify								(const bool bAutomatic);
	virtual void			AddFilesToExportList( List<Asura_String>& xNameList ) const;

	virtual bool			GetParameter( Asura_Hash_ID uParamID, Tools_Parameter* pxParam ) const;
	virtual bool			SetParameter( Asura_Hash_ID uParamID, const Tools_Parameter* pxParam );

	static ToolsAVP_Entity_GamePlayVolume* FindEntity( const Asura_Guid uGuid ) { return s_xList.FindEntity( uGuid ); }
	static const Asura_Hashed_List<ToolsAVP_Entity_GamePlayVolume>* GetList(void)					{return &s_xList;}

	u_int					GetNumLinkedGamePlayVolumes			(void) const 						{return m_uNumLinkedGamePlayVolumes;}
	Asura_Guid				GetLinkedGamePlayVolumeGuid			(int iIndex) const 					{return m_puLinkedGamePlayVolumes[iIndex];}

	static void				ActuallyAddGamePlayVolumeLink		(const int iIndex, Tools_Object* pxObject);
	static void				ActuallyRemoveGamePlayVolumeLink	(const int iIndex, Tools_Object* pxObject);

	static void				AddLinkToGPVolume					(ToolsAVP_Entity_GamePlayVolume* pxGPToAddTo, Asura_Guid uGuidToAdd);
	static void				RemoveLinkToGPVolume				(ToolsAVP_Entity_GamePlayVolume* pxGPToRemoveFrom, Asura_Guid uGuidToRemove);

	static	bool			s_bAdd;
	static ToolsAVP_Entity_GamePlayVolume*						s_pxGPvolume;				// static pointer to the currently selected tools object of this type

protected:

	// Protected Member Functions
	ToolsAVP_GamePlayVolume_VolumeEdit_Controller*				GetVolumeController(void)			{return m_pxVolumeController;}
	List<Asura_Guid>*											GetAlienSpawnerList(void)			{return m_pxAlienSpawnerGuids;}
	static void													AddGamePlayVolumeLink(int iIndex);
	static void													RemoveGamePlayVolumeLink(int iIndex);

	void	HideOutsideEntities(bool bVal);
	void	UnhideEverything(void);
	void	ProcessShowHide(void);
	void	HideLinkedOutsideEntities(void);
	void	ShowLinkedOutSideEntities(void);

	virtual void AddGeneralTabControls			(Asura_Tabs_Dialog* pxTabsDialog, Asura_Vector_2& xOffset);
	virtual void AddEntityControlTabControls	(Asura_Tabs_Dialog* pxTabsDialog, Asura_Vector_2& xOffset);
	virtual void AddUnderTabsControls			(Asura_Overlay*		pxOverlay,		Asura_Vector_2& xOffset);

	// Protected Variables...
	ToolsAVP_GamePlayVolume_VolumeEdit_Controller*				m_pxVolumeController;		// The volume controller for creating and editing the volumes
	
	Asura_Vector_3												m_xPreviousPosition;		// Previous position of the tools object
	List<Asura_Guid>*											m_pxAlienSpawnerGuids;
	Asura_Guid													m_puLinkedGamePlayVolumes[MAX_LINKED_GAMEPLAYVOLUMES];
	u_int														m_uNumLinkedGamePlayVolumes;
	bool														m_bLinkChanged;
	int															m_iGamePlayAreaType;
	bool														m_bAreaChanged;
	Asura_Tabs_Dialog*											m_pxTabsDialog;
	int															m_iBitFlags;

	enum Tabs	{ TAB_GENERAL, TAB_ENTITY_CONTROL, TAB_END_ENUM };

	// statics
	static bool													s_bShowVolumes;				// flag value to indicate if rendering of the volumes is on / off
	static bool													s_bShowSelectedVolume;
	static bool													s_bHideEntitiesOutside;
	static bool													s_bEntitesOutsideAreHidden;
	static bool													s_bIncludeLinkedVolumes;
	static bool													s_bLinkedEntitesOutsideAreHidden;
	static bool													s_bVolumesEdited;
	static u_int												s_uCurrentTab;
	static const char*											s_aszTabNames[TAB_END_ENUM];
	static const char*											s_aszFlagNames[AVP_ServerEntity_GamePlayVolume::FLAG_END_ENUM];

private:

	// Private typedefs...
	typedef Tools_Entity_Object PARENT;		 

	// Private Static variables...
	
	static bool													s_bMoveVolumeWithObject;	// static flag to indicate if the volumes should be moved with the tools object of this type
	static Asura_Hashed_List<ToolsAVP_Entity_GamePlayVolume>	s_xList;

	// Static Private Functions...
	static void EditVolume										(void);

	// Private functions and operators...
	ToolsAVP_Entity_GamePlayVolume								(void);
	ToolsAVP_Entity_GamePlayVolume								(const ToolsAVP_Entity_GamePlayVolume& xOther);
	ToolsAVP_Entity_GamePlayVolume&	operator=					(const ToolsAVP_Entity_GamePlayVolume& xOther);

};   /// End of class 'ToolsAVP_Entity_GamePlayVolume'.


//----------------------------------------------------------------------------------
// Class        : ToolsAVP_Entity_GamePlayVolume
// Author       : Gareth Thomas
// Date         : 22 / 10 / 07
// Description  : For dealing with editing the volumes associated with this entity
//----------------------------------------------------------------------------------
class ToolsAVP_GamePlayVolume_VolumeEdit_Controller : public Tools_VolumeGroupEdit_Controller
{

public:

	typedef Tools_VolumeGroupEdit_Controller PARENT;

	// Public Construction / Deconstruction functions...
	ToolsAVP_GamePlayVolume_VolumeEdit_Controller(ToolsAVP_Entity_GamePlayVolume* pxToolsEntity);

	// Public Virtual Functions...
	virtual void				StartVolumeEditing();
	virtual void				EndVolumeEditing();

	// Returns a Volume corresponding with the passed in index
	virtual Asura_Volume* GetVolume(u_int uIndex) { return m_pxAVPEntity->GetVolume(uIndex); }

protected:

	// Protected Overridden Virtual Functions...
	virtual bool				CanCreateVolume()									{return true;}
	virtual bool				CanDeleteVolume()									{return GetNumberOfVolumes() > 1;}

	//Gets the current number of volumes
	virtual int					GetNumberOfVolumes()								{return m_pxAVPEntity->GetNumVolumes();}

	//Gets a pointer to the orientation for a given volume. Returns 0 if there is none
	// - OLD - virtual Asura_Quat*			GetVolumeOrient(int iIndex)							{return &(m_pxAVPEntity->GetVolumes()[iIndex].m_xOrient);}
	virtual Asura_Quat*			GetVolumeOrient(int iIndex)							{ return m_pxAVPEntity->GetVolumeOrient(static_cast<u_int>(iIndex)); }
	
	//Gets a default position for volume objects that have yet to gain a proper volume
	virtual Asura_Vector_3		GetDefaultPosition()								{return m_pxToolsEntity->Position;}
	
	//Gets the name of the owner , to use for part of the volume names
	virtual const char*			GetName()											{return m_pxToolsEntity->GetName();}

	// Creates the new volume in the asura data
	virtual void CreateVolumeCuboidMain();
	// Creates the new volume in the asura data
	virtual void CreateVolumeSphereMain();
	// Creates the new volume in the asura data
	virtual void CreateVolumeCylinderMain();

	virtual void				DeleteVolumeMain(int iIndex);

private:

	// Private Member Variables...
	ToolsAVP_Entity_GamePlayVolume*		m_pxToolsEntity;
	AVP_ServerEntity_GamePlayVolume*	m_pxAVPEntity;

};

//----------------------------------------------------------------------
// ToolsAVP_ChooseObject_GamePlayVolume
//----------------------------------------------------------------------
class ToolsAVP_ChooseObject_GamePlayVolume : public Tools_ChooseObject
{
public:

	// Public functions...
	ToolsAVP_ChooseObject_GamePlayVolume(const int iIndex, ToolsAVP_Entity_GamePlayVolume* pxGamePlayVolume)
	{
		m_iIndex = iIndex;
		m_pxGamePlayVolume = pxGamePlayVolume;
	}

	// Overridden functions...
	virtual bool	CanBeSelected(Tools_Object* pxObject);
	virtual void	ObjectSelected(Tools_Object* pxObject);

	// Pretty nasty, but if you can't get around it at least declare the destructor private (or protected, if you want to inherit)!
	// BTW, why isn't this implemented in the base class? Everyone now seems to be doing it this way. (AN 29/11/07)
	virtual void	OnFinish() { delete this; }

protected:
	// Protected variables...

	// Protected functions...

private:
	// Private variables...
	int											m_iIndex;			// The index of the GamePlayVolume we're using.
	ToolsAVP_Entity_GamePlayVolume*				m_pxGamePlayVolume;

	// Private functions...
	ToolsAVP_ChooseObject_GamePlayVolume				(void);
	ToolsAVP_ChooseObject_GamePlayVolume				(const ToolsAVP_ChooseObject_GamePlayVolume& xOther);
	ToolsAVP_ChooseObject_GamePlayVolume&	operator=	(const ToolsAVP_ChooseObject_GamePlayVolume& xOther);

	virtual ~ToolsAVP_ChooseObject_GamePlayVolume		(void) {;}

};   // End of class 'ToolsAVP_ChooseObject_SquadMember'.

#endif   // ifndef __ToolsAVP_Entity_GamePlayVolume_H__
/// End of file 'ToolsAVP_Entity_GamePlayVolume'.
