//////////////////////////////////////////////////////////////////////////////
//
// Asura_ServerEntity_CountedTrigger.h
//
// Copyright (c) 2002 Rebellion. All rights reserved.
//
// Description:
//
//     trigger that sends its trigger messages only when it has been triggered
//     a certain number of times.
//
//////////////////////////////////////////////////////////////////////////////

// B E G I N   F I L E   W R A P P E R ///////////////////////////////////////

#ifdef ASURA_USE_PRAGMA_ONCE
    #pragma once
#endif

#ifndef ___ASURA_SERVERENTITY_COUNTEDTRIGGER_H___
#define ___ASURA_SERVERENTITY_COUNTEDTRIGGER_H___ 1

#include "Asura_ServerEntity_Trigger.h"
#ifdef ASURA_TOOLS
#include "Entity/Asura_Entity_Classification.h"
#endif

//data for single trigger for counted teigger
class Asura_CountedTrigger_MessageBlock
{
public :
	void SetDefaultValues();

	Asura_Hash_ID m_uHashID;//generated from name
	int m_iTriggerCount;//count at which this becomes triggered

	unsigned short m_usMessageBlock;
	union
	{
		unsigned short m_usFlags;
		struct
		{
			unsigned short	m_bActive :1,
							m_bRetriggerable:1;//otherwise deactivated on trigger
		};
	};

	#ifdef ASURA_TOOLS
	Asura_String m_xName;
	#endif
};

class Asura_ServerEntity_CountedTrigger : public Asura_ServerEntity_Trigger
{
	typedef Asura_ServerEntity_Trigger PARENT;

	friend class Tools_Entity_CountedTrigger_Object;
    
public:

    Asura_ServerEntity_CountedTrigger(bool initiallyActive = true);
	//constructor from load
	Asura_ServerEntity_CountedTrigger(Asura_Guid uGuid);

	~Asura_ServerEntity_CountedTrigger();


	#ifdef ASURA_TOOLS
	virtual bool CanBeIncludedInTemplate() const {return Classification == AsuraEntityClass_CountedTrigger;}
	virtual void ApplyChangesForTemplateInstance(class Tools_EntityTemplateInstance* pxInstance);
	#endif

	#ifdef ASURA_TOOLS
	//gets a more detailed description of activate/deactiivate messages
	static const char* GetMessageDescription(const struct Asura_StaticMessage* pxMessage);
	#endif
	


	#ifdef ASURA_SUPPORT_ENTITYWATCH
	virtual void DisplayEntityWatchText();
	#endif

	int GetCount() const { return m_iCounter; }

	static void CreateFromChunkStream(Asura_Guid uGuid, Asura_Chunk_Stream& xStream);

	#ifdef ASURA_TOOLS
	virtual bool SupportsCustomEvents() const { return true; }
	virtual int GetNumCustomEvents() const { return m_uNumberOfMessageBlocks; }
	virtual unsigned short* GetCustomEvent(int iIndex) { return &m_pxMessageBlocks[iIndex].m_usMessageBlock; }
	virtual void GetCustomEventName(int iEventIndex, Asura_String& xEventName);
	#endif

protected:

	virtual bool HandleMessage(const Asura_Message* pxMessage);
    
    virtual bool IsTriggered(void){return false;}
    virtual void OnTrigger();
	virtual void OnUnTrigger();

	void TriggerMessages(int iOldCounter,int iNewCounter);
	void SetTriggerCount(u_int uOutput,int iTriggerCount);

	//virtual function overides for loading/saving
	virtual	bool IsFilledFromChunkBuffer(void) const { return false; }
	virtual	void ReadFromChunkStream(Asura_Chunk_Stream& xStream);
	virtual	void WriteToChunkStream(Asura_Chunk_Stream& xStream) const;
	// deprecated functions
	int GetChunkBufferSize();
	void FillInChunkBuffer(char*& pcChunkBuffer);
	#ifdef ASURA_TOOLS
	int GetToolsDataSize();
	#endif

	int m_iCounter;

	unsigned int m_uNumberOfMessageBlocks;
	class Asura_CountedTrigger_MessageBlock* m_pxMessageBlocks;

	#ifdef ASURA_TOOLS
	public:
		static Asura_ServerEntity_CountedTrigger* FindEntity(Asura_Guid uGuid)
		{
			return s_xList.FindEntity(uGuid);
		}

		static const Asura_Hashed_List<Asura_ServerEntity_CountedTrigger>* GetList()
		{
			return &s_xList;
		}


	private:
		static Asura_Hashed_List<Asura_ServerEntity_CountedTrigger> s_xList;
	#endif // ASURA_TOOLS

};

//These messages are saved out to static message system , so care needs to be taken about altering them
struct Asura_Message_CountedTrigger_MessageHash
{
	Asura_Hash_ID m_uMessageHash;	
};


struct Asura_Message_CountedTrigger_SetTriggerCount : Asura_Message_CountedTrigger_MessageHash
{
	int m_iTriggerCount;
};

struct Asura_Message_CountedTrigger_SetCounter
{
	int m_iCounter;
};

struct Asura_Message_CountedTrigger_AddCounter
{
	int m_iChange;
};


// E N D   F I L E   W R A P P E R ///////////////////////////////////////////

#endif // #ifndef ___ASURA_SERVERENTITY_COUNTEDTRIGGER_H___
