//////////////////////////////////////////////////////////////////////////////
//
// ToolsAVP_Entity_RoomNode.h
//
// Created by AJK 15/01/2009
//
// Copyright (c) 2009 Rebellion. All rights reserved.
//
//////////////////////////////////////////////////////////////////////////////

#ifdef ASURA_USE_PRAGMA_ONCE
#pragma once
#endif

#ifndef TOOLSAVP_ENTITY_ROOMNODE_H
#define TOOLSAVP_ENTITY_ROOMNODE_H

// Asura Tools
#include "Entity/ObjectiveSystem/RoomNode/AVP_ServerEntity_RoomNode.h"
#include "Entity/Tools_Entity_Object.h"
#include "Objects/ToolsAVP_Object_Type.h"
#include "Objects/Tools_VolumeGroupEdit_Controller.h"

class ToolsAVP_RoomNode_VolumeEdit_Controller;
class ToolsAVP_Object_ExitLink;

class ToolsAVP_Entity_RoomNode : public Tools_Entity_Object
{
public:

	static void						 Create();
	static Tools_Object*			 Create(Asura_Entity* pxEntity);
	static ToolsAVP_Entity_RoomNode* FindEntity(Asura_Guid uGuid)		      { return s_xList.FindEntity(uGuid); }
	static const Asura_Hashed_List<ToolsAVP_Entity_RoomNode>*  GetList (void) { return(&s_xList); }

	virtual bool			CanBeCopied() const { return ( Type == TOT_Entity_RoomNode ); }
	virtual void			Copy( const Tools_Object* pxObject );
	virtual Tools_Object*	CreateObjectOfThisType() const;
	virtual const char*		GetTypeDescription(){return "Room Node";}
	virtual void			AddOverlayControls(Asura_Overlay* pxNewOverlay, Asura_Vector_2& xOffset);
    virtual bool            Verify( const bool bAutomatic );
	virtual void			OnSelection();
	virtual void			OnDeselection();

	virtual void			UpdateWhileSelected();
	virtual void			UpdatePositionInAsuraData( bool bUpdateLinkedObjects );
	virtual void			Destroy();
	virtual void            Render();

	AVP_ServerEntity_RoomNode*	GetRoomNode() { return m_pxRoomNode; }

protected:
	ToolsAVP_Entity_RoomNode(AVP_ServerEntity_RoomNode* pxRoomNode);
	virtual ~ToolsAVP_Entity_RoomNode();

	AVP_ServerEntity_RoomNode*	m_pxRoomNode;

	ToolsAVP_Entity_RoomNode	(void);
	ToolsAVP_Entity_RoomNode	(const ToolsAVP_Entity_RoomNode& xOther);
	ToolsAVP_Entity_RoomNode&	operator=	(const ToolsAVP_Entity_RoomNode& xOther);

	Asura_Vector_3									m_xPreviousPosition;
	Asura_Matrix_3x3								m_xPreviousOrientation;

	ToolsAVP_RoomNode_VolumeEdit_Controller*        m_pxVolumeController;

	static ToolsAVP_Entity_RoomNode*			    s_pxThis;

	friend class ToolsAVP_RoomNode_VolumeEdit_Controller;

private :
	void							RemoveRoomNode ( const Asura_Guid uNode );
	void							UpdateRoomNodeListStrings();
	void						    ShowVolume(bool bShow);
	const ToolsAVP_Object_ExitLink* GetExitLinkTo(Asura_Guid uRoomNode) const;

	static void EditVolume();
	static void AddExitLink(int iUserData);
	static void RemoveRoomNode();

	char**					m_pszRoomNode;
	int						m_iSelectedRoomNode;
	u_int                   m_numRoomStrings;
	u_int					m_uSelectedExitPoint;
	Asura_Mesh*				m_pxExitPointMesh;
	u_int					m_uPositionEditObjectID;

	Asura_Hashed_List<ToolsAVP_Object_ExitLink> xExitLinkList;

	static bool                      s_bRefreshOverlay;
	static bool				         s_bMoveVolumeWithObject;
	static bool			             s_bShowAllVolumes;
	static bool				         s_bShowSelectedVolume;
	static ToolsAVP_Entity_RoomNode* s_pxLastSelected;
	static bool				         s_bMoveExitPointsWithEntity;
	static Asura_Hashed_List<ToolsAVP_Entity_RoomNode> s_xList;

	typedef Tools_Entity_Object PARENT;
};

class ToolsAVP_RoomNode_VolumeEdit_Controller : public Tools_VolumeGroupEdit_Controller
{
public :
	ToolsAVP_RoomNode_VolumeEdit_Controller(ToolsAVP_Entity_RoomNode* pxToolsEntity);

	virtual void StartVolumeEditing();
	virtual void EndVolumeEditing();

protected :
	virtual bool CanCreateVolume()	{ return true; }
	virtual bool CanDeleteVolume()  { return GetNumberOfVolumes()>1; }

	virtual Asura_Volume* GetVolume(u_int uIndex) { return m_pxToolsEntity->m_pxRoomNode->GetVolumeGroup().GetVolume(uIndex); }

	virtual int GetNumberOfVolumes() { return m_pxToolsEntity->m_pxRoomNode->GetVolumeGroup().GetNumberOfVolumes(); }

	virtual Asura_Quat* GetVolumeOrient(int iIndex)	{ return m_pxToolsEntity->m_pxRoomNode->GetVolumeGroup().GetVolumeOrient(static_cast<u_int>(iIndex)); }

	virtual Asura_Vector_3 GetDefaultPosition()	{ return m_pxToolsEntity->Position; }

	virtual const char* GetName() { return m_pxToolsEntity->GetName(); }

	virtual void CreateVolumeCuboidMain();
	virtual void CreateVolumeSphereMain();
	virtual void CreateVolumeCylinderMain();

	virtual void DeleteVolumeMain(int iIndex);

private :
	ToolsAVP_Entity_RoomNode*	m_pxToolsEntity;
};

class ToolsAVP_Object_ExitLink : public Tools_Object
{
	typedef Tools_Object PARENT;

public:
	static Asura_List<ToolsAVP_Object_ExitLink>*  GetList (void) { return(&s_xList); }
	static ToolsAVP_Object_ExitLink* GetToolsObjectExitLink(const AVP_RoomNode_ExitLink* pxExitLink );

	ToolsAVP_Object_ExitLink();
	virtual ~ToolsAVP_Object_ExitLink();

	virtual const char* GetTypeDescription() { return "Exit Point"; }
	virtual const char* GetName()            { return "Exit Point"; }
	virtual void UpdatePositionInAsuraData( bool bUpdateLinkedObjects );
	        void Update();
	virtual void Destroy();

	virtual void AddOverlayControls(Asura_Overlay* pxNewOverlay, Asura_Vector_2& xOffset);
	virtual void Render();
	virtual bool ShouldCreateObjectOverlay() { return true; }
	virtual bool GetParameter( Asura_Hash_ID uParamID, Tools_Parameter* pxParam ) const;
	virtual bool SetParameter( Asura_Hash_ID uParamID, const Tools_Parameter* pxParam );
	virtual void UpdateWhileSelected();
	virtual void OnSelection();
	virtual void OnDeselection();

	void	               SetExitLink ( AVP_RoomNode_ExitLink* pxExitLink ) { m_pxExitLink = pxExitLink; }
	AVP_RoomNode_ExitLink* GetExitLink () { return m_pxExitLink; }
	void                   SetSourceRoomGuid( Asura_Guid uSourceRoomGuid ) { m_uSourceRoomGuid = uSourceRoomGuid; }
	Asura_Guid             GetSourceRoomGuid() { return m_uSourceRoomGuid; }

private:
	void MergeExitLinks(bool bTryMerge);
	void RemoveMeFromRoomNodeList(Asura_Guid uRoomGuid) const;

	Asura_Guid             m_uSourceRoomGuid;
	AVP_RoomNode_ExitLink* m_pxExitLink;

	static bool s_bShowMergeMessage;
	static Asura_List<ToolsAVP_Object_ExitLink> s_xList;
};
#endif // #ifndef TOOLSAVP_ENTITY_ROOMNODE_H
