/*************************************************************************
Crytek Source File.
Copyright (C), Crytek Studios, 2001-2005.
-------------------------------------------------------------------------
$Id$
$DateTime$
Description: 
	Common functionality for all HUDs using Flash player
	Code which is not game-specific should go here
	Shared by G02 and G04

-------------------------------------------------------------------------
History:
- 22:02:2006: Created by Matthew Jack from original HUD class

*************************************************************************/
#include "StdAfx.h"
#include "HUDCommon.h"

#include "HUDDraw.h"
#include "IGameFlash.h"
#include "GameFlashAnimation.h"
#include "GFGotoAndStop.h"
#include "GFVariable.h"

#include "Player.h"
#include "Weapon.h"
#include "Game.h"

//-----------------------------------------------------------------------------------------------------

CHUDCommon *CHUDCommon::s_pHUD = NULL;

//-----------------------------------------------------------------------------------------------------


//-----------------------------------------------------------------------------------------------------
//-- IGameObjectExtension
//-----------------------------------------------------------------------------------------------------

void CHUDCommon::PostInit(IGameObject *pGameObject)
{
	pGameObject->EnablePostUpdates(this);
}

//-----------------------------------------------------------------------------------------------------

void CHUDCommon::Release()
{
	GetISystem()->GetISystemEventDispatcher()->RemoveListener(this);

	delete this;
}
//-----------------------------------------------------------------------------------------------------
//-- ~ IGameObjectExtension
//-----------------------------------------------------------------------------------------------------



//-----------------------------------------------------------------------------------------------------
//-- IConsoleArgs
//-----------------------------------------------------------------------------------------------------

void CHUDCommon::ConsoleCommandFunc(IConsoleCmdArgs *pConsoleCmdArgs)
{
	if(2 == pConsoleCmdArgs->GetArgCount())
	{
		bool bHideLuaHud = false;
		bool bHideFlashHud = false;

		if(0 == strcmp(pConsoleCmdArgs->GetArg(1),"0"))
		{
			bHideLuaHud = true;
			bHideFlashHud = true;
		}
		else if(0 == strcmp(pConsoleCmdArgs->GetArg(1),"1"))
		{
			bHideLuaHud = false;
			bHideFlashHud = true;
		}
		else if(0 == strcmp(pConsoleCmdArgs->GetArg(1),"2"))
		{
			bHideLuaHud = true;
			bHideFlashHud = false;
		}

		if(bHideLuaHud)
		{
			SmartScriptTable rSmartScriptTable;
			GetISystem()->GetIScriptSystem()->GetGlobalValue("HUD",rSmartScriptTable);
			Script::CallMethod(rSmartScriptTable,"Hide",1);
		}
		else
		{
			SmartScriptTable rSmartScriptTable;
			GetISystem()->GetIScriptSystem()->GetGlobalValue("HUD",rSmartScriptTable);
			Script::CallMethod(rSmartScriptTable,"Hide",0);
		}

		if(s_pHUD)
		{
			if(bHideFlashHud)
			{
				s_pHUD->Show(false);
			}
			else
			{
				s_pHUD->Show(true);
			}
		}
	}
}

void CHUDCommon::SetHud(int version)
{
	bool bHideLuaHud = false;
	bool bHideFlashHud = false;
	switch(version)
	{
	case 0:
		bHideLuaHud = true;
		bHideFlashHud = true;
		break;
	case 1:
		bHideLuaHud = false;
		bHideFlashHud = true;
		break;
	case 2:
		bHideLuaHud = true;
		bHideFlashHud = false;
		break;
	default:
		break;
	}

	if(bHideLuaHud)
	{
		SmartScriptTable rSmartScriptTable;
		GetISystem()->GetIScriptSystem()->GetGlobalValue("HUD",rSmartScriptTable);
		Script::CallMethod(rSmartScriptTable,"Hide",1);
	}
	else
	{
		SmartScriptTable rSmartScriptTable;
		GetISystem()->GetIScriptSystem()->GetGlobalValue("HUD",rSmartScriptTable);
		Script::CallMethod(rSmartScriptTable,"Hide",0);
	}

	if(s_pHUD)
	{
		if(bHideFlashHud)
		{
			s_pHUD->Show(false);
		}
		else
		{
			s_pHUD->Show(true);
		}
	}
}

//-----------------------------------------------------------------------------------------------------
//-- ~ IConsoleArgs
//-----------------------------------------------------------------------------------------------------



//-----------------------------------------------------------------------------------------------------
//-- ISystemEventListener
//-----------------------------------------------------------------------------------------------------

void CHUDCommon::OnResize(int width, int height)
{
	// try to resize based on any width and height
	for(TGameFlashAnimationsList::iterator i=m_gameFlashAnimationsList.begin(); i!=m_gameFlashAnimationsList.end(); ++i)
	{
		RepositionFlashAnimation(*i, width, height);
	}

	m_width		= width;
	m_height	= height;
}

//-----------------------------------------------------------------------------------------------------
//-- ~ ISystemEventListener
//-----------------------------------------------------------------------------------------------------



CHUDCommon::CHUDCommon() 
{
	m_pHUDDraw = NULL;
	s_pHUD = this;

	m_godMode = 0;
	m_iDeaths = 0;

	strcpy(m_strGODMode,"");
	
	m_width					= 0;
	m_height				= 0;

	m_iCursorVisibilityCounter = 0;

	m_bShow = false;
}

//-----------------------------------------------------------------------------------------------------

CHUDCommon::~CHUDCommon()
{
	SAFE_DELETE(m_pHUDDraw);
	s_pHUD = NULL;
}

//-----------------------------------------------------------------------------------------------------

bool CHUDCommon::Init(IGameObject *pGameObject)
{
	SetGameObject(pGameObject);
	GetISystem()->GetIConsole()->AddCommand("hud",ConsoleCommandFunc);
	m_pHUDDraw = new CHUDDraw;
	CursorReset();
	GetISystem()->GetISystemEventDispatcher()->RegisterListener(this);

	return true;
}

//-----------------------------------------------------------------------------------------------------

CGameFlashAnimation * CHUDCommon::AddNewFlashAnimation(const char *strName, const char *filename, EGameFlashDock docking, bool setHandler)
{
	CGameFlashAnimation *newAnim = new CGameFlashAnimation;
	if(newAnim->Load(strName,filename))
	{
		newAnim->SetDock(docking);
		m_gameFlashAnimationsList.push_back(newAnim);
		if (setHandler) newAnim->GetFlashPlayer()->SetFSCommandHandler(this);
	} 
	else 
	{
		SAFE_DELETE(newAnim);
	}
	return newAnim;
}
//-----------------------------------------------------------------------------------------------------

void CHUDCommon::AddGotoAndStop(CGameFlashAnimation *pGameFlashAnimation,const char *strName,const char *strControl,const char *strToken,float fScale,float fOffset)
{
	CGFGotoAndStop *pGFGotoAndStop = new CGFGotoAndStop(pGameFlashAnimation);
	pGFGotoAndStop->Init(strName,strControl,strToken,fScale,fOffset);
	pGameFlashAnimation->AddGameFlashLogic(pGFGotoAndStop);
}

//-----------------------------------------------------------------------------------------------------

void CHUDCommon::AddVariable(CGameFlashAnimation *pGameFlashAnimation,const char *strName,const char *strControl,const char *strVariable,const char *strToken,float fScale,float fOffset)
{
	CGFVariable *pGFVariable = new CGFVariable(pGameFlashAnimation);
	pGFVariable->Init(strName,strControl,strVariable,strToken,fScale,fOffset);
	pGameFlashAnimation->AddGameFlashLogic(pGFVariable);
}

//-----------------------------------------------------------------------------------------------------

CWeapon *CHUDCommon::GetWeapon()
{
	CPlayer *pPlayer = static_cast<CPlayer *>(GetISystem()->GetIGame()->GetIGameFramework()->GetClientActor());
	if(pPlayer)
	{
		IGameObject *pGameObject = pPlayer->GetGameObject();
		if(pGameObject)
		{
			IInventory *pInventory = static_cast<IInventory *>(pGameObject->QueryExtension("Inventory"));
			if(pInventory)
			{
				EntityId uiItemId = pInventory->GetCurrentItem();
				if(uiItemId)
				{
					return pPlayer->GetWeapon(uiItemId);
				}
			}
		}
	}

	return NULL;
}

//-----------------------------------------------------------------------------------------------------

void CHUDCommon::Show(bool bShow)
{
	m_bShow = bShow;
}

//-----------------------------------------------------------------------------------------------------

void CHUDCommon::SetGODMode(uint8 ucGodMode, bool forceUpdate)
{
	if (forceUpdate || m_godMode != ucGodMode)
	{
		m_godMode = ucGodMode;

		if(0 == ucGodMode)
		{
			strcpy(m_strGODMode,"");
			m_iDeaths = 0;
		}
		else if(1 == ucGodMode)
		{
			strcpy(m_strGODMode,"GOD");
		}
		else if(2 == ucGodMode)
		{
			strcpy(m_strGODMode,"Team GOD");
		}
	}
}


//-----------------------------------------------------------------------------------------------------
//-- Cursor handling
//-----------------------------------------------------------------------------------------------------

void CHUDCommon::CursorReset()
{
	m_fCursorX = 399.5f;
	m_fCursorY = 299.5f;
}

//-----------------------------------------------------------------------------------------------------

void CHUDCommon::CursorIncrementCounter()
{
	m_iCursorVisibilityCounter++;
	assert(m_iCursorVisibilityCounter >= 0);

	if(1 == m_iCursorVisibilityCounter)
	{
		CursorReset();
		GetISystem()->GetIGame()->GetIGameFramework()->GetIActionMapManager()->EnableFilter("no_mouse",true);
	}
}

//-----------------------------------------------------------------------------------------------------

void CHUDCommon::CursorDecrementCounter()
{
	m_iCursorVisibilityCounter--;
	assert(m_iCursorVisibilityCounter >= 0);

	if(0 == m_iCursorVisibilityCounter)
	{
		GetISystem()->GetIGame()->GetIGameFramework()->GetIActionMapManager()->EnableFilter("no_mouse",false);
	}
}

//-----------------------------------------------------------------------------------------------------

int CHUDCommon::RepositionCursorXPos(CGameFlashAnimation *pAnimation, int x)
{
	// try to resize based on any width and height
	int width43 = m_height * 4 / 3;
	int offsetWidth = m_width - width43;

	int dock = pAnimation->GetDock();

	if (dock & eGFD_Right)
		return (x - offsetWidth);

	if (dock & eGFD_Middle)
		return (x - offsetWidth/2);

	return x;
}



//-----------------------------------------------------------------------------------------------------
//-- Positioning and scaling animations
//-----------------------------------------------------------------------------------------------------

void CHUDCommon::RepositionFlashAnimation(CGameFlashAnimation *pAnimation, int width, int height) const
{
	// try to resize based on any width and height
	int height43 = width * 3 / 4;
	int width43 = height * 4 / 3;
	int offsetHeight = height - height43;
	int offsetWidth = width - width43;

	float x = 0;
	float y = 0;
	float w = width;
	float h = height;

	int dock = pAnimation->GetDock();

	// FIXME: make this nicer
	if (dock & eGFD_Left)
	{
		x = 0;
		w = w-offsetWidth;
	}

	if (dock & eGFD_Right)
	{
		x = offsetWidth;
		w = w-offsetWidth;
	}

	if (dock & eGFD_Middle)
	{
		x = offsetWidth/2;
		w = w-offsetWidth;
	}

	// FIXME: top and bottom scaling is a bit ill defined
	if (dock & eGFD_Bottom)
	{
		y = offsetHeight;
		h = h-offsetHeight;
	}

	pAnimation->SetViewport((int)x, (int)y, (int)w, (int)h);
}
//-----------------------------------------------------------------------------------------------------

//-----------------------------------------------------------------------------------------------------
//-- Scaling data
//-----------------------------------------------------------------------------------------------------

float CHUDCommon::GetScaleX() const
{
	return 8.0f * 1024.0f / 800.0f;
}

//-----------------------------------------------------------------------------------------------------

float CHUDCommon::GetScaleY() const
{
	return 6.0f * 768.0f / 600.0f;
}


