#ifndef _NPC_H_
#define _NPC_H_

#include "Item.h"
#include <string>
#include <list>

class NPCState;

class NPC
{
	NPCState* mInitialState;
	NPCState* mCurrentState;
	std::string mName;
	std::string mByeMessage;
	bool mScoreTalked;

	friend class NPCState;
	void ChangeState(NPCState* aState);

public:
	NPC(std::string aName, std::string aByeMessage, NPCState* aInitialState);
	~NPC();

	void Talk();
	void SayBye();
	void InvalidInput();
	std::string GetNPCName() const { return mName; }
	NPCState* GetInitialState() const { return mInitialState; }
	NPCState* GetCurrentState() const { return mCurrentState; }
};


class NPCState //Abstract Class
{
protected:
	std::list <NPCState*> mMoreStates;
	NPC* mNPC; //Which npc to manipulate
	std::string mName;
	std::string mText;
	int mReferenceCount;
	bool mScoreTalked;

	void ChangeState(NPC* aNPC, NPCState* aState);
	//These are pieces of the talk function and you can use whatever pieces you need
	void PieceSayText(std::string aText);
	bool PieceCheckStateList();
	bool PieceCheckElse();

public:
	NPCState();
	virtual ~NPCState();

	static int sNPCStateCount;
	static int sNPCStateLookCount;

	std::string GetStateName() const { return mName; }
	std::string GetStateText() const { return mText; }

	virtual void Talk() = 0;

	void SetNPC(NPC* aNPC) { mNPC = aNPC; }
	void AddState(NPCState* aStateToAdd);
};


class NPCSayMore : virtual public NPCState
{
public:
	NPCSayMore(std::string aName, std::string aText);
	NPCSayMore(std::string aText);
	void Talk();
};


class NPCItemLook : virtual public NPCState
{
	bool mGotItem;
	bool mDestroy;
	std::string mLookingText;
	Item* mLookingItem;

public:
	NPCItemLook(bool aDestroy, std::string aName, std::string aText, std::string aLookingText);
	void AddLookingItem(Item* aLookingItem);
	void Talk();
	void DontHaveItem();
	void HaveItem();
};

class NPCItemGive : virtual public NPCState
{
	bool mGave;
	Item* mGiveItem;

public:
	NPCItemGive(std::string aName, std::string aText);
	void AddItemToGive(Item* aGiveItem);
	void Talk();
};

#endif //Close _NPC_H_