//
// Asura_Overlay_System.h
//
// Created by Kevin Lea - 12/06/2001 11:12:12
// 
// Copyright (C) 2001 Rebellion, All Rights Reserved.
//

#ifdef ASURA_USE_PRAGMA_ONCE
    #pragma once
#endif

#ifndef __ASURA_OVERLAY_SYSTEM_H__
#define __ASURA_OVERLAY_SYSTEM_H__

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

class Asura_Overlay;
class Asura_Gadget;

#define MAX_NUMBER_OF_OVERLAYS 30

#define OverlayFocusType_Keyboard 0x00000001
#define OverlayFocusType_Mouse 0x00000002

class Asura_Overlay_System
{
	public:
		static void Initialise(void);
		static void Shutdown(void);
		static void SubmitNewOverlay( Asura_Overlay* overlay, bool hasCloseGadget = true, bool hasMinimiseGadget = true, bool bDisplayName = true );
		static void Update() { Update(false); }
		static void Update(bool lockedOut);
		static void Render(void);

		static bool DoesOverlayExist(unsigned int id);
		static void CloseOverlays(unsigned int id);
		static Asura_Overlay* GetOverlay(unsigned int id);
        static Asura_Overlay* GetCurrentOverlay() { return CurrentOverlay; }

		// Returns the index of this overlay in the overlay storage. This allows us to recreate overlays in the correct order.
		static int GetOverlayIndex( u_int uOverlayID );

		static inline bool CursorIsOverAnOverlay(void)
		{
			return CursorIsOnAnOverlay;
		}

		static inline bool AnyOverlays(void)
		{
			return (NumberOfActiveOverlays!=0);
		}

		static bool AreAnyOverlaysVisible();

		static void TakeFocus(Asura_Gadget* gadget,int focusType);
		static void ReleaseFocus(int focusType=0xffffffff);

		static bool OverlaysHaveKeyboardFocus()
		{
			return (HasKeyboardFocus || s_bUsedKeypressThisFrame);		
		}

		static Asura_Gadget* GetFocusGadget(){return FocusGadget;}
		static bool AGadgetHasMouseFocus(){return (FocusType & OverlayFocusType_Mouse) ? true : false;}

		//used to delay callback functions in gadgets until overlay updating has finished
		//(to get rid of some annoying re-entrancy problems)
		static void SetCallbackFunctionToCall(void(*function)(void));
		static void SetCallbackFunctionToCall(void(*function)(int),int iUserData);
		static void SetCallbackFunctionToCall(const Asura_Callback_Base<void>& xCallback);
		static void SetCallbackFunctionToCall(const Asura_Callback_Wrapper<void>& xCallback);
		static void ClearCallbackFunctionToCall();

		static float GetPanelMinY(){return PanelMinY;}
		static float GetMinimisedOverlayY() {return MaxOverlayY;}

        static float GetMaxScreenX( void );
        static float GetMaxScreenY( void );

		static void RenderHelpText(const char* pszText);

		//sets the help text to be drawn this frame
		static void SetHelpText(const char* pszHelpText){s_xHelpText = pszHelpText;}
		static bool IsAnyHelpText(){return !s_xHelpText.IsBlank();}

		static void BringOverlayToTop(u_int uOverlayID);
		//Gets the ID of the current topmost overlay
		static u_int GetTopOverlayID();
		static Asura_Overlay* GetTopOverlay();

		static void SetAlwaysOnTop(Asura_Overlay* pxOverlay, bool bSet);

		static bool AreAnyOverlaysAlwaysOnTop();

		static bool WasLastMouseClickOnOverlay() { return s_bLastMouseClickWasOnOverlay; }

		//Allows modes to hide all overlays
		static void SetHideOverlays(bool bHide){s_bCodeHideOverlays = bHide; s_iHideOverlaysNestLevel += (bHide ? 1 : -1); }
		//Used by keyboard shortcut for hiding overlays
		static void SetUserHideOverlays(bool bHide){ s_bUserHideOverlays = bHide; s_iHideOverlaysNestLevel += (bHide ? 1 : -1); }
		static bool GetUserHideOverlays(){return s_bUserHideOverlays;}
		static int GetHideOverlaysNestLevel() { return s_iHideOverlaysNestLevel; }

		static bool AreOverlaysHidden(){return s_bCodeHideOverlays || s_bUserHideOverlays;}

		//Adds/removes hidden flags on all existing overlays
		static void SetHideFlagOnCurrentOverlays(u_int uFlags,bool bSet);

		static bool UseSkinnedUI(){return s_bUseSkinnedUI;}  
		static void SetUseSkinnedUI(bool bSkinned){ s_bUseSkinnedUI = bSkinned;}
		static void LoadSkinnedUITexture();

		static bool s_bUsedKeypressThisFrame;
		
		static u_int s_uOverlayColour;
		static u_int s_uFadedOverlayAlpha;//alpha value to use for overlays in the backgroun
//		static bool s_bUseTranslucentOverlays;

	private:

		static void CheckForClosingOverlays();
		
		static void UpdateOverlayPanelSize();
		static void RenderPanelBackdrop();		

        static void CreateCtrlTabOverlay();

		static void SortOverlays();
		static int SortOverlaysCallback(const void* ppOverlay1,const void* ppOverlay2);



		static Asura_Overlay* OverlayList[MAX_NUMBER_OF_OVERLAYS];
		static int NumberOfActiveOverlays;

		static float MaxOverlayY;
		static float PanelMinY;

		static bool CursorIsOnAnOverlay;

		static Asura_Overlay* CurrentOverlay;//overlay that is currently being Updated() each frame (or last one to do that anyway)
		static Asura_Gadget* FocusGadget;//gadget that is currently taking keyboard commands
		static int FocusType;
		static bool HasKeyboardFocus;
		static bool s_bFocusSetThisFrame;

		static Asura_Callback_Wrapper<void> s_xCallbackFunction;

		static Asura_String s_xHelpText;

		static bool s_bUserHideOverlays;
		static bool s_bCodeHideOverlays;
		static bool s_bUseSkinnedUI;
		static int s_iHideOverlaysNestLevel;
		static bool s_bLastMouseClickWasOnOverlay;

		static u_int s_uNextSubmissionIndex;
};

#endif//__ASURA_OVERLAY_SYSTEM_H__
