#include "../WorldFrames/ItemClipboard.h"
#include "../WorldFrames/ChatEdit.h"
#include "MacroFrame.h"

CMacroFrame*				g_pMacroFrame = NULL;

int	LuaFunc_GetMacroInfo(lua_State* L);
int	LuaFunc_GetNumMacros(lua_State* L);
int	LuaFunc_GetNumMacroIcons(lua_State* L);
int	LuaFunc_GetMacroIconInfo(lua_State* L);
int	LuaFunc_CreateMacro(lua_State* L);
int	LuaFunc_EditMacro(lua_State* L);
int	LuaFunc_DeleteMacro(lua_State* L);
int	LuaFunc_PickupMacroItem(lua_State* L);

// ----------------------------------------------------------------------------
CMacroFrame::CMacroFrame(CInterface* object)
	: CInterfaceBase(object)
{
	g_pMacroFrame = this;
	m_icons.clear();
	m_macro.clear();

	SearchIcons();
}

// ----------------------------------------------------------------------------
CMacroFrame::~CMacroFrame()
{
	Save();

	g_pMacroFrame = NULL;
	m_icons.clear();
	m_macro.clear();
}

// ----------------------------------------------------------------------------
void CMacroFrame::SearchIcons()
{
	m_icons.push_back( "Interface\\Icons\\ability_ambush" );
	m_icons.push_back( "Interface\\Icons\\ability_backstab" );
	m_icons.push_back( "Interface\\Icons\\ability_bullrush" );
	m_icons.push_back( "Interface\\Icons\\ability_cheapshot" );
	m_icons.push_back( "Interface\\Icons\\ability_criticalstrike" );
	m_icons.push_back( "Interface\\Icons\\ability_defend" );
	m_icons.push_back( "Interface\\Icons\\ability_devour" );
	m_icons.push_back( "Interface\\Icons\\ability_druid_aquaticform" );
	m_icons.push_back( "Interface\\Icons\\ability_druid_bash" );
	m_icons.push_back( "Interface\\Icons\\ability_druid_catform" );
	m_icons.push_back( "Interface\\Icons\\ability_druid_catformattack" );
	m_icons.push_back( "Interface\\Icons\\ability_druid_challangingroar" );
	m_icons.push_back( "Interface\\Icons\\ability_druid_cower" );
	m_icons.push_back( "Interface\\Icons\\ability_druid_dash" );
	m_icons.push_back( "Interface\\Icons\\ability_druid_demoralizingroar" );
	m_icons.push_back( "Interface\\Icons\\ability_druid_disembowel" );
	m_icons.push_back( "Interface\\Icons\\ability_druid_enrage" );
	m_icons.push_back( "Interface\\Icons\\ability_druid_ferociousbite" );
	m_icons.push_back( "Interface\\Icons\\ability_druid_mangle" );
	m_icons.push_back( "Interface\\Icons\\ability_druid_maul" );
	// m_icons.push_back( "Interface\\Icons\\ability_druid_rake" );
}

// ----------------------------------------------------------------------------
void CMacroFrame::RegisterFunc()
{
	lua_State* L = GetLuaStateWorld();
	if (L)
	{
		lua_register( L, "GetMacroInfo",			LuaFunc_GetMacroInfo );
		lua_register( L, "GetNumMacros",			LuaFunc_GetNumMacros );
		lua_register( L, "GetNumMacroIcons",		LuaFunc_GetNumMacroIcons );
		lua_register( L, "GetMacroIconInfo",		LuaFunc_GetMacroIconInfo );
		lua_register( L, "CreateMacro",				LuaFunc_CreateMacro );
		lua_register( L, "EditMacro",				LuaFunc_EditMacro );
		lua_register( L, "DeleteMacro",				LuaFunc_DeleteMacro );
		lua_register( L, "PickupMacroItem",			LuaFunc_PickupMacroItem );
	}
}

// ----------------------------------------------------------------------------
int CMacroFrame::CreateMacro(const char* name, int iconId, const char* text)
{
	int serial = 0;
	bool loop;

	do {
		loop = false;		
		for ( vector<MacroItem>::iterator iter = m_macro.begin(); iter != m_macro.end(); iter++ )
		{
			if ( (*iter).id == serial )
			{
				loop = true;
				serial++;
				break;
			}
		}
	} while( loop );

	MacroItem item;
	memset(&item, 0, sizeof(item));

	item.id		= serial;
	item.icon	= iconId;

	if ( name )
		strcpy( item.name, name );
	if ( text )
		strcpy( item.text, text );

	m_macro.push_back( item );
	return m_macro.size() - 1;
}

// ----------------------------------------------------------------------------
void CMacroFrame::EditMacro(int index, const char* name, int iconId, const char* text)
{
	MacroItem* item = GetMacroItem(index);
	if ( item )
	{
		if ( name )
			strcpy( item->name, name );
		if ( iconId != -1)
			item->icon = iconId;
		if ( text )
			strcpy( item->text, text );
	}
}

// ----------------------------------------------------------------------------
void CMacroFrame::DeleteMacro(int index)
{
	m_macro.erase( m_macro.begin() + index );
}

// ----------------------------------------------------------------------------
MacroItem* CMacroFrame::GetMacroItem(int index)
{
	if ( (unsigned int)index < (unsigned int)m_macro.size() )
		return &m_macro[index];
	return NULL;
}

// ----------------------------------------------------------------------------
const char* CMacroFrame::GetMacroIcon(int index)
{
	if ( (unsigned int)index < (unsigned int)m_icons.size() )
		return m_icons[index].c_str();
	return NULL;
}

// ----------------------------------------------------------------------------
int	CMacroFrame::GetMacroIndexById(int id)
{
	int index = 0;
	for ( vector<MacroItem>::iterator iter = m_macro.begin(); iter != m_macro.end(); iter++, index++ )
	{
		if ( (*iter).id == id )
			return index;
	}
	return -1;
}

// ----------------------------------------------------------------------------
void CMacroFrame::PickupMacroItem(int index)
{
	MacroItem* item = GetMacroItem( index );
	if ( item )
	{
		g_pItemClipboard->Clear();			// 清除資料		

		g_pItemClipboard->SetName( item->name );
		g_pItemClipboard->SetFile( GetMacroIcon(item->icon) );
		g_pItemClipboard->PickupMacro( this, item->id );
	}
}

// ----------------------------------------------------------------------------
void CMacroFrame::UseMacro(int id)
{
	MacroItem* item = GetMacroItem( GetMacroIndexById(id) );
	if ( item )
	{
		lua_State* L = GetLuaStateWorld();
		if (L)
		{
			lua_getglobal(L, "ExecuteMacroText");
			lua_pushstring(L, item->text);
			lua_call(L, 1, 0);
		}
	}
}

// ----------------------------------------------------------------------------
void CMacroFrame::Save()
{
	char globalName[MAX_PATH];
	char localName[MAX_PATH];
	FILE* fptr = NULL;

	GetGlobalPath("Macro", globalName, MAX_PATH);
	GetLocalPath("Macro", localName, MAX_PATH);

	// 儲存共用資料	

	// 儲存本地資料
	if ( (fptr = fopen(localName, "wb")) != NULL )
	{
		// 記錄資料
		int size = (int)m_macro.size();
		fwrite( &size, sizeof(int), 1, fptr );						// 記錄筆數

		if ( size > 0 )
			fwrite( &m_macro[0], sizeof(MacroItem), size, fptr );	// 記錄總筆數

		// 關閉檔案
		fclose(fptr);
	}
}

// ----------------------------------------------------------------------------
void CMacroFrame::Load()
{
	char globalName[MAX_PATH];
	char localName[MAX_PATH];
	FILE* fptr = NULL;

	GetGlobalPath("Macro", globalName, MAX_PATH);
	GetLocalPath("Macro", localName, MAX_PATH);

	// 讀取共用資料
	if ( (fptr = fopen(localName, "rb")) != NULL )
	{
		// 讀取資料
		int size;
		fread( &size, sizeof(size), 1, fptr );

		for ( int i = 0; i < size; i++ )
		{
			MacroItem item;
			fread( &item, sizeof(item), 1, fptr );
			m_macro.push_back(item);
		}

		// 關閉檔案
		fclose(fptr);
	}
}

// ----------------------------------------------------------------------------
int	LuaFunc_GetMacroInfo(lua_State* L)
{
	MacroItem* item = g_pMacroFrame->GetMacroItem( luaL_checkint(L, 1) - 1 );
	if ( item )
	{
		lua_pushstring(L, item->name);
		lua_pushstring(L, g_pMacroFrame->GetMacroIcon(item->icon));
		lua_pushstring(L, item->text);
		return 3;
	}
	return 0;
}

// ----------------------------------------------------------------------------
int	LuaFunc_GetNumMacros(lua_State* L)
{
	lua_pushnumber( L, g_pMacroFrame->GetNumMacros() );
	return 1;
}

// ----------------------------------------------------------------------------
int LuaFunc_GetNumMacroIcons(lua_State* L)
{
	lua_pushnumber( L, g_pMacroFrame->GetNumMacroIcons() );
	return 1;
}

// ----------------------------------------------------------------------------
int	LuaFunc_GetMacroIconInfo(lua_State* L)
{
	lua_pushstring( L, g_pMacroFrame->GetMacroIcon(luaL_checkint(L, 1) - 1) );
	return 1;
}

// ----------------------------------------------------------------------------
int	LuaFunc_CreateMacro(lua_State* L)
{
	int icon = 0;
	const char* name = NULL;
	const char* text = NULL;
	
	if ( lua_type(L, 1) == LUA_TSTRING )
		name = lua_tostring(L, 1);
	if ( lua_type(L, 2) == LUA_TNUMBER )
		icon = (int)lua_tonumber(L, 2) - 1;
	if ( lua_type(L, 3) == LUA_TSTRING )
		text = lua_tostring(L, 3);

	lua_pushnumber( L, g_pMacroFrame->CreateMacro( name, icon, text ) + 1);
	return 1;
}

// ----------------------------------------------------------------------------
int	LuaFunc_EditMacro(lua_State* L)
{
	int index = luaL_checkint(L, 1) - 1;
	int icon = -1;
	const char* name = NULL;
	const char* text = NULL;

	for ( int i = 2; i <= lua_gettop(L); i++ )
	{
		switch (i)
		{
		case 2:		// name			
			if ( lua_type(L, 2) == LUA_TSTRING )
				name = lua_tostring(L, 2);
			break;
			
		case 3:		// icon
			if ( lua_type(L, 3) == LUA_TNUMBER )
				icon = (int)lua_tonumber(L, 3) - 1;
			break;

		case 4:		// text
			if ( lua_type(L, 4) == LUA_TSTRING )
				text = lua_tostring(L, 4);
			break;
		}
	}
	g_pMacroFrame->EditMacro(index, name, icon, text);
	return 0;
}

// ----------------------------------------------------------------------------
int	LuaFunc_DeleteMacro(lua_State* L)
{
	g_pMacroFrame->DeleteMacro(luaL_checkint(L, 1) - 1);
	return 0;
}

// ----------------------------------------------------------------------------
int	LuaFunc_PickupMacroItem(lua_State* L)
{
	g_pMacroFrame->PickupMacroItem(luaL_checkint(L, 1) - 1);
	return 0;
}