//////////////////////////////////////////////////////////////////////////////
//
// Asura_ServerEntity_Objective.h
//
// Copyright (c) 2007 Rebellion. All rights reserved.
//
// Description:
//
//     Base Asura Objective Entity
//
//////////////////////////////////////////////////////////////////////////////

// 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_OBJECTIVE_H___
#define ASURA_SERVERENTITY_OBJECTIVE_H___ 1

#include "Entity/Asura_Entity.h"
#include "Entity/Asura_Entity_Classification.h"


// objective states - these are in addition to objectives being active/deactive
enum ASURA_OBJECTIVE_STATE
{
	ASURA_OBJECTIVE_PENDING = 0,	// objective not yet completable
	ASURA_OBJECTIVE_READY,			// objective not yet completed
	ASURA_OBJECTIVE_COMPLETE,		// objective completed
	ASURA_OBJECTIVE_FAILED,			// objective failed
	ASURA_OBJECTIVE_SKIPPED,		// objective is no longer completable

	ASURA_OBJECTIVE_NUM_STATES
};

//default text page for objectives
static const Asura_Hash_ID uASURA_HASH_TEXTPAGE_OBJECTIVES = 0x05DF63C0;			//Asura_GetHashID("Goals");

// forward declaration
class Asura_ClientEntity_Objective;

class Asura_ServerEntity_Objective : public Asura_Entity_Server
{
	friend class Tools_Entity_Objective;

public:
	//just the one constructor to help maintain consistency
	Asura_ServerEntity_Objective(Asura_Guid uGuid);
	virtual ~Asura_ServerEntity_Objective();

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

	virtual bool HandleMessage(const Asura_Message* pxMessage);

	virtual bool IsFilledFromChunkBuffer() const {return false;}
	virtual bool CanBeSavedToChunk() const {return true;}

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

	virtual void PostLoadInitialise();

	ASURA_OBJECTIVE_STATE GetObjectiveState() const {return m_eObjectiveState;}
	Asura_Hash_ID GetTextHash() const {return m_uTextHash;}
	u_int GetObjectiveNumber() const {return m_uObjectiveNumber;}

	//get the hash id of the text page. virtual so projects can override, either to a different constant,
	//or to allow different pages per objective (page per level for eg)
	//make sure client function is overriden as well!
	virtual Asura_Hash_ID GetObjectiveLocalisedPageID() const;

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

	void SetObjectiveState(ASURA_OBJECTIVE_STATE eObjectiveState) {m_eObjectiveState = eObjectiveState;}
	void SetTextHash(Asura_Hash_ID uTextHash) {m_uTextHash = uTextHash;}
	void SetObjectiveNumber(u_int uObjectiveNumber) {m_uObjectiveNumber = uObjectiveNumber;}
#endif // #ifdef ASURA_TOOLS

protected:
	virtual void MakeClientUpdateMessage();
	virtual void OnEntityActivateMessage();

	//internal state machine workings
	virtual void RequestObjectiveState(ASURA_OBJECTIVE_STATE eObjectiveState);

	ASURA_OBJECTIVE_STATE m_eObjectiveState;	//current state
	Asura_Hash_ID m_uTextHash;					//hash id for objective text
	u_int m_uObjectiveNumber;					//objective number for rendereding/sorting

	static const u_int uOBJECTIVE_CHUNK_VERSION = 0;

private:
	typedef Asura_Entity_Server PARENT;
};

//client update/create message. only sent on state change or create/activation, so not worth maintaining seperate create and update messages
class Asura_Message_Objective_ClientUpdate
{
public:
	void FillInObjective(const Asura_ServerEntity_Objective* pxObjective);
	void FillOutObjective(Asura_ClientEntity_Objective* pxObjective) const;

#ifdef ASURA_SUPPORT_NETMSG_SYSTEM
	static void RegisterFields(u_short usMsgID, u_short usEntityClassification);
	static void RegisterFields(class Asura_NetMsg* pxNetMsg);
	static u_char GetNumFields() { return 3; }
#endif//#ifdef ASURA_SUPPORT_NETMSG_SYSTEM

private:
	ASURA_OBJECTIVE_STATE m_eObjectiveState;
	Asura_Hash_ID m_uTextHash;
	u_int m_uObjectiveNumber;
};

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

#endif // #ifndef ASURA_SERVERENTITY_OBJECTIVE_H___
