/**
*
* \file Asura_ServerEntity_AdvancedVolumeTrigger.h
*
* Created by Andrew Weinkove - 29/01/2003
*
* Copyright (C) 2003 Rebellion, All Rights Reserved.
*
* A volume trigger with trigger and untrigger functionality that
* will check entities contained in project-specific lists.
* AdvancedVolumeTrigger is a slightly grand title, the old volume triggers
* aren't actually any real use for anything other than checking the camera
* position in single-player single-machine games. This class attempts to 
* remove these limitations without breaking any old code, and to eventually
* make the old volume triggers redundant.
*
**/
#ifdef ASURA_USE_PRAGMA_ONCE
	#pragma once
#endif

#ifndef __ASURA_SERVERENTITY_ADVANCEDVOLUMETRIGGER_H__
#define __ASURA_SERVERENTITY_ADVANCEDVOLUMETRIGGER_H__

#include "Entity/Triggers/Asura_ServerEntity_Trigger.h"
#include "Core/Asura_Maths.h"
#include "Core/Asura_OrientedVolume.h"


#ifdef ASURA_TOOLS
//flag values for use with tickboxes... must correspond to the bitfield positions below
#define ASURAVOLUMETRIGGERFLAG_TRIGGERONCE 0x00000002
#define ASURAVOLUMETRIGGERFLAG_TRIGGERONNOTOCCUPIED 0x00000004
#endif

class Asura_ServerEntity_AdvancedVolumeTrigger : public Asura_ServerEntity_Trigger
{
	public:
		Asura_ServerEntity_AdvancedVolumeTrigger( const Asura_Bounding_Box& xBB, bool bInitiallyActive = false );
		//constructor from load
		Asura_ServerEntity_AdvancedVolumeTrigger(Asura_Guid uGuid);
		Asura_ServerEntity_AdvancedVolumeTrigger(Asura_Guid uGuid,const char*& chunkBuffer);
		~Asura_ServerEntity_AdvancedVolumeTrigger();
        
        struct ChunkData
        {
			//If this gets updated then the loaders for the client entity version
			//will need to updatd as well.
            enum { CURRENT_VERSION = 4 };

			int				m_iListFlags;
			unsigned int	m_uFlags;
            Asura_Guid		m_uSpecificGuid;
			int				m_iNumberOfVolumes;
			//(followed by array of volumes after this ChunkData)

        };
        struct ChunkData_V1
        {
			Asura_Bounding_Box m_xVolume;
			int                m_iListFlags;
			unsigned int       m_uFlags;
            Asura_Guid         m_uSpecificGuid;
        };
		struct ChunkData_V0
		{
			Asura_Bounding_Box m_xVolume;
			int m_iListFlags;
			unsigned m_uFlags;
		};
		int        m_iListFlags;	//Bit-field of lists to use - limits max lists to 32.
        Asura_Guid m_uSpecificGuid; //Specific Guid to check
		
		int GetNumberOfVolumes() const {return m_iNumberOfVolumes;}
		const Asura_OrientedVolume& GetVolume(int iIndex) const { return m_pxVolumes[iIndex]; }

		//checks to see if a point lies in any of the volumes associated with this trigger
		virtual bool Contains(const Asura_Vector_3& xPosition) const;

		#ifdef ASURA_TOOLS
		virtual void ApplyChangesForTemplateInstance(class Tools_EntityTemplateInstance* pxInstance);
		//This must be set back to true in project derived version if this is to be allowed in templates
		//virtual bool CanBeIncludedInTemplate() const {return false;}
		#endif


		#ifdef ASURA_SUPPORT_ENTITYWATCH
		virtual void DisplayEntityWatchText();
		#endif

				
	protected:
		virtual bool IsTriggered(void);
		virtual bool IsUnTriggered(void);
		virtual void OnUnTrigger();
		virtual bool IsVolumeOccupied();
				

		void Reset(void){} 

		//virtual function overides for saving
//		virtual	bool	IsFilledFromChunkBuffer		(void) const					{ return (true); }

		virtual	int		GetChunkBufferSize			(void);
		virtual	void	FillInChunkBuffer			(char*& pcChunkBuffer);
//		virtual	void	InitialiseFromChunkBuffer	(const char*& pcChunkBuffer);

		virtual	void	ReadFromChunkStream			(Asura_Chunk_Stream& xStream);
		virtual	void	WriteToChunkStream			(Asura_Chunk_Stream& xStream) const;

		int m_iNumberOfVolumes;
		Asura_OrientedVolume* m_pxVolumes;

		union
		{
			struct
			{
				unsigned int m_bHasAlreadyTriggered		: 1,
							 m_bTriggerOnce				: 1,//Volume trigger is deactivated when un-triggered (so it only gets triggered once per activation)
							 m_bTriggerOnNotOccupied	: 1,//Becomes triggered upon becoming unocupied instead
							 SpareBits					: 29;
			};
			unsigned int m_uFlags;
		};
		friend class Tools_Entity_AdvancedVolumeTrigger;
		friend class Tools_AdvancedVolumeTrigger_VolumeEdit_Controller;
		static const int s_iMaxNumberOfLists;

private:

	typedef Asura_ServerEntity_Trigger PARENT;
};

#endif//__ASURA_SERVERENTITY_ADVANCEDVOLUMETRIGGER_H__
