//
// Tools_MessageLog.h
//
// Created by Richard Rice - 27/07/2006
// 
// Copyright (C) 2006 Rebellion, All Rights Reserved.
//

#ifdef ASURA_USE_PRAGMA_ONCE
    #pragma once
#endif
#ifndef __TOOLS_MESSAGELOG__
#define __TOOLS_MESSAGELOG__

#include "Core/Asura_Maths.h"
#include "Core/Asura_String.h"

class Asura_NameTree;
template<class T> class List;
class Tools_MessageLogAction;
class Tools_MessageLogEntry;

//defines for internal flags for determining which systems should automatically show the message log
#define TOOLS_MESSAGELOG_TEXTURES	0x00000001
#define TOOLS_MESSAGELOG_SOUND		0x00000002
#define TOOLS_MESSAGELOG_DIALOGUE	0x00000004
#define TOOLS_MESSAGELOG_AXON		0x00000008
#define TOOLS_MESSAGELOG_CUTSCENE	0x00000010
#define TOOLS_MESSAGELOG_ENTITIES	0x00000020

//Class for overlay that shows a list of all messages shown while in tools
class Tools_MessageLog
{
public:
	static void Initialise();
	static void Shutdown();
	static void Update();

	enum Category
	{
		ALL_CATEGORIES,
		NO_CATEGORY,

		// Mode-type categories.
		BLUEPRINTS,
		BOTANICALS,
		CUTSCENE,
		DIALOGUE,
		ENTITIES,
		GUI_MENU,
		IK,
		MATERIAL_RESPONSE,
		MESH_EDIT,
		PFX,
		SOUND_EVENT,
		WAYPOINTING,

		// Event-type categories.
		EXPORT,
		VERIFICATION,

		NUM_CATEGORIES
	};

	//Creates the message log overlay (if required) and brings to the front
	static void ShowOverlay();
	//As above , but also sets the current category and subcategory filters
	//(If null/blank then the *All* filter is selected)
	//uInitialSelectedID is used to determine the message that is initially selected (if non-zero)
	static void ShowOverlay(const char* szCat,const char* szSubCat,u_int uInitialSelectedID = 0);
	static void ShowOverlay(Category eCat,const char* szSubCat,u_int uInitialSelectedID = 0);

	//Gets the ID of the next message to be allocated. Can be used to set the initial position when opening the overlay.
	static u_int GetNextID(){return s_uNextID;}

	//Returns true if there are any messages for the specified category.subcategory filters.
	//If uMinID is used  , then only messages with that ID or higher will be considered
	//(Added as a means for verification processes etc to check whether they have added anything)
	static bool AreThereAnyMessages(const char* szCat, const char* szSubCat, u_int uMinID = 0);
	static bool AreThereAnyMessages(Category eCat,const char* szSubCat, u_int uMinID = 0);

	//Closes the message log overlay
	static void CloseOverlay();

	//Adds a message to the log in the specified category and subcategories.
	//The caategories can be null/blank if not wanted
	static void AddMessage(const char* szCat,const char* szSubCat,const char* szFormat,...);
	static void AddMessage(Category eCat,const char* szSubCat,const char* szFormat,...);

	//As above ,but this takes pointer to a class derived from Tools_MessageLogAction which will be used to
	//goto the target of the message.
	//It is assumed that pxAction is allocated by new , and the message log system will delete it when it has finished with it.
	static void AddMessage(const char* szCat,const char* szSubCat,class Tools_MessageLogAction* pxAction,const char* szFormat,...);
	static void AddMessage(Category eCat,const char* szSubCat,class Tools_MessageLogAction* pxAction,const char* szFormat,...);

	//Deletes all messages in the specified category/subcategory.
	//If null or blank then it will match all categories/subcategories.
	//May be useful to ditch old messages before doing a verify' procedure , or to get
	//rid of messages when leaving a mode if the 'actions' are no longer safe to use.
	static void DeleteMessages(const char* szCat,const char* szSubCat);
	static void DeleteMessages(Category eCat,const char* szSubCat);

	//User preferences for what thinsg should automatically open the message log
	static bool ShouldShowForMissingTextures() {return (s_uShowOverlayOptions & TOOLS_MESSAGELOG_TEXTURES)!=0;}
	static bool ShouldShowForSound() {return (s_uShowOverlayOptions & TOOLS_MESSAGELOG_SOUND)!=0;}
	static bool ShouldShowForDialogue() {return (s_uShowOverlayOptions & TOOLS_MESSAGELOG_DIALOGUE)!=0;}
	static bool ShouldShowForAxon() {return (s_uShowOverlayOptions & TOOLS_MESSAGELOG_AXON)!=0;}
	static bool ShouldShowForCutscene() {return (s_uShowOverlayOptions & TOOLS_MESSAGELOG_CUTSCENE)!=0;}
	static bool ShouldShowForEntities() {return (s_uShowOverlayOptions & TOOLS_MESSAGELOG_ENTITIES)!=0;}

private:
	static void AddMessageInternal(const char* szCat,const char* szSubCat,class Tools_MessageLogAction* pxAction,const char* szFormat,va_list xArgs);

	static bool OverlayExists();
	static void CreateOverlay();

	static void UpdateCatList();
	static void DeleteCatList();

	static void UpdateSubCatList();
	static void DeleteSubCatList();

	static void UpdateMessageStrings();
	static void DeleteMessageStrings();

	static void GotoMessage();
	static void GotoMessage(int iJunk) {GotoMessage();}
	static bool IsEnabled_GotoMessage();

	static void DeleteAllMessages();
	static void DeleteVisibleMessages();

	static void CopyToClipboard();

    static void TransferModeData( const int iMode );

	static bool s_bInitialised;
	static u_int s_uNextID;
	static List<Tools_MessageLogEntry*> s_xMessageList;

	static Asura_String s_xSearchString;
	static bool s_bSearchStringChanged;

	static Asura_NameTree s_xCatNameTree;
	static const char** s_pszCatList;
	static u_int s_uCatListSize;
	static int s_iCatIndex;
	static bool s_bCatIndexChanged;
	static Asura_String s_xCatFilter;
	static class Asura_DropDown_List_Dialog* s_pxCatListDialog;

	static Asura_NameTree s_xSubCatNameTree;
	static const char** s_pszSubCatList;
	static u_int s_uSubCatListSize;
	static int s_iSubCatIndex;
	static bool s_bSubCatIndexChanged;
	static Asura_String s_xSubCatFilter;
	static class Asura_DropDown_List_Dialog* s_pxSubCatListDialog;

	static const char** s_pszMessageStrings;
	static const char** s_pszMessageHelpStrings;
	static Tools_MessageLogEntry** s_ppxMessages;
	static u_int s_uMessageStringsSize;
	static int s_iMessageIndex;
	static bool s_bMessageIndexChanged;
	static class Asura_List_Dialog* s_pxMessageListDialog;
	static u_int s_uMostRecentSelectedID;

	static u_int s_uNextIDWhenStringsWereLastUpdated;

	//user options for determining which systems should automatically show the overlay
	static u_int s_uShowOverlayOptions;

	static Asura_Vector_2 s_xPosition;

	static const char* s_aszCatStrings[ NUM_CATEGORIES ];
};

//Class used for the 'Goto' action for any messages added to the log.
//A derived class should be made , and Execute() overriden to do something appropriate.
class Tools_MessageLogAction
{
public :
	virtual ~Tools_MessageLogAction(){};
	virtual void Execute(){};
};

class Tools_MessageLogEntry
{
public :
	~Tools_MessageLogEntry()
	{
		delete m_pxAction;
	}

	Asura_String m_xText;
	Asura_String m_xShortText;
	Asura_String m_xCategory;
	Asura_String m_xSubCategory;
	u_int m_uID;
	bool m_bShown;

	Tools_MessageLogAction* m_pxAction;
};

#endif //__TOOLS_MESSAGELOG__
