#define _WIN32_WINNT 0x0500
#define _WIN32_WINDOWS 0x0400

#include <windows.h>
#include <mmsystem.h>
#include "ui.h"
#include "../xml/xmlui.h"
#include "../tools/getfontnamefromfile/getfontnamefromfile.h"

lua_State*				g_uiLuaState = NULL;

void UILuaRegisterBaseFunc(lua_State* L);

int	GetXmlType(int type);
int	GetXmlAnchorPoint(int point);
int	GetXmlLayer(int layer);
int GetXmlScriptType(int type);
RuFontWeight GetXmlRuFontWeight(int weight);
int	GetXmlFontJustifyVType(int type);
int	GetXmlFontJustifyHType(int type);
TextureAlphaMode GetXmlTextureAlphaMode(int alphaMode);

// ----------------------------------------------------------------------------------
void UILuaRegisterBaseFunc(lua_State* L)
{
	lua_getglobal(L, LUA_STRLIBNAME);
	lua_pushstring(L, "len");
	lua_gettable(L, -2);
	lua_setglobal(L, "strlen");
	lua_pushstring(L, "sub");
	lua_gettable(L, -2);
	lua_setglobal(L, "sub");
}

// ----------------------------------------------------------------------------------
CUi::CUi()
{
	m_lock.clear();

	m_luaState			= NULL;
	m_pRootFrame		= NULL;
	m_pCapture			= NULL;
	m_pKeyCapture		= NULL;
	m_pMouseOver		= NULL;
	m_pDragFrame		= NULL;
	m_pMouseFocus		= NULL;

	for ( int i = 0; i < MAX_MOUSE_BUTTON_NUM; i++ )
	{
		m_mouseDown[i] = NULL;
		m_lastmouseDown[i] = NULL;
		m_mouseDownTime[i] = 0.0f;
		m_lastmouseDownTime[i] = 0.0f;
	}

	m_captureKey		= 0;
	m_elapsedTime		= 0.0f;
	m_absoluteTime		= 0.0f;
	m_scale				= 1.0f;
	m_cursorPos.m_x		= 0.0f;
	m_cursorPos.m_y		= 0.0f;
	m_cursorOffset.m_x	= 0.0f;
	m_cursorOffset.m_y	= 0.0f;

	m_object.clear();
	m_userEvent.clear();
	m_xmlUi				= NULL;	

	// open lua
	m_luaState			= lua_open();
	if (m_luaState)
	{
		CUiLuaLayout::OpenLib(m_luaState);
		CUiLuaFontString::OpenLib(m_luaState);
		CUiLuaTexture::OpenLib(m_luaState);
		CUiLuaFrame::OpenLib(m_luaState);
		CUiLuaModel::OpenLib(m_luaState);
		CUiLuaButton::OpenLib(m_luaState);
		CUiLuaCheckButton::OpenLib(m_luaState);
		CUiLuaRadioButton::OpenLib(m_luaState);
		CUiLuaEditBox::OpenLib(m_luaState);
		CUiLuaListBox::OpenLib(m_luaState);
		CUiLuaSlider::OpenLib(m_luaState);
		CUiLuaStatusBar::OpenLib(m_luaState);
		CUiLuaMessageFrame::OpenLib(m_luaState);
		CUiLuaScrollFrame::OpenLib(m_luaState);
		CUiLuaTooltip::OpenLib(m_luaState);
		
		lua_baselibopen(m_luaState);
		lua_strlibopen(m_luaState);
		lua_tablibopen(m_luaState);
		lua_mathlibopen(m_luaState);

		UILuaRegisterBaseFunc(m_luaState);
	}

	//m_pRootFrame		= (CUiFrame*)CreateObject(CUiLayout::eUiType_Frame, "ui_system_root_frame", NULL);
	m_pRootFrame		= new CUiFrame("ui_system_root_frame", NULL, this);
}

// ----------------------------------------------------------------------------------
CUi::~CUi()
{
	UI_SAFE_DELETE(m_pRootFrame);
	UI_SAFE_DELETE(m_xmlUi);

	if (m_luaState)
		lua_close(m_luaState);
}

// ----------------------------------------------------------------------------------
void CUi::Update(float elapsedTime, InputState &state)
{
	// 清除目前鍵盤跟滑鼠焦點元件
	m_pKeyboardFocus = NULL;
	m_pMouseFocus = NULL;

	// 更新時間
	m_elapsedTime = elapsedTime;	

	// 更新輸入狀態
	m_cursorOffset.m_x	= (float)state.xPos - m_cursorPos.m_x;
	m_cursorOffset.m_y	= (float)state.yPos - m_cursorPos.m_y;
	m_cursorPos.m_x		= (float)state.xPos;
	m_cursorPos.m_y		= (float)state.yPos;
	m_input.UpdateState( state, elapsedTime );	

	// 取得第一個處理元件
	CUiFrame* first = (m_lock.empty()) ? m_pRootFrame : m_lock.back();
	
	// 鍵盤處理
	if (m_pKeyCapture)
	{
		if (!m_pKeyCapture->IsParentEnable())
			LockKeyboard(NULL);
		else if (m_pKeyCapture->HandleKeyboard(m_input))
			m_pKeyboardFocus = m_pKeyCapture;
	}	
	if (m_pKeyboardFocus == NULL && first)
	{
		CUiFrame* keyboardFocus = first->GetFrameAtKeyboard(NULL);
		if (keyboardFocus && keyboardFocus->HandleKeyboard(m_input))
			m_pKeyboardFocus = keyboardFocus;
	}	

	// 取得可接收滑鼠訊息最上層元件
	CUiFrame* mouseIn = NULL;
	if (first)
		mouseIn = first->GetFrameAtPoint(m_cursorPos, NULL);

	// 2006/07/07 修正避免 Capture 元件被鎖住
	// 是否有元件鎖住滑鼠訊息(拖曳中)
	if ( m_pCapture )
	{
		m_pMouseFocus = m_pCapture;
		if ( !m_pCapture->HandleMouse(m_input) )
			SetCapture(NULL, 0);
	}
	else if ( mouseIn && mouseIn->HandleMouse(m_input) )
		m_pMouseFocus = mouseIn;

	/*
	// 是否有元件鎖住滑鼠訊息(拖曳中)
	if ( m_pCapture )
	{
		m_pMouseFocus = m_pCapture;
		m_pCapture->HandleMouse(m_input);
	}
	else if ( mouseIn && mouseIn->HandleMouse(m_input) )
		m_pMouseFocus = mouseIn;
	*/

	// 檢查是否有滑鼠按鍵放開
	for ( int i = 0; i < MAX_MOUSE_BUTTON_NUM; i++ )
	{
		if ( m_input.GetButtonUp(i) )
		{
			if (m_mouseDown[i])
			{
				m_mouseDown[i]->OnMouseUp(m_cursorPos, i);
				SetMouseDown(i, NULL);
			}
		}
	}

	// 目前所在元件不同時
	if (m_pMouseOver != mouseIn)
	{
		if (m_pMouseOver)
			m_pMouseOver->OnMouseLeave(m_cursorPos);

		m_pMouseOver = mouseIn;

		if (m_pMouseOver)
			m_pMouseOver->OnMouseEnter(m_cursorPos);
	}

	// 若沒有元件接收滑鼠左鍵事件,是否要解除焦點元件
	if ( m_input.GetButtonDown(MOUSE_LBUTTON) )
	{
	}

	if (m_pRootFrame)
		m_pRootFrame->Update(elapsedTime);
}

// ----------------------------------------------------------------------------------
void CUi::Render2D()
{
	if (m_pRootFrame)
		m_pRootFrame->Render(1.0f);
}

// ----------------------------------------------------------------------------------
void CUi::Render3D()
{
	if (m_pRootFrame)
		m_pRootFrame->Render3D(1.0f);
}

// ----------------------------------------------------------------------------------
bool CUi::MsgProc(UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	bool keyboard = false;

	switch ( uMsg )
	{
	case WM_CHAR:
#ifndef _UNICODE
		{
			static char tmpStr[2];
			static INT count = 0;

			if ( count )
			{
				tmpStr[count] = (char)wParam;
				MultiByteToWideChar( CP_ACP, 0, tmpStr, 2, (LPWSTR)&wParam, 1 );
				count = 0;
			}
			else if ( wParam & 0x80 )
			{
				tmpStr[count++] = (char)wParam;
				return true;
			}			
		}
#endif
		break;
	}

	// 鍵盤處理
	if (m_pKeyCapture && m_pKeyCapture->HandleMsgProc(uMsg, wParam, lParam))
		keyboard = true;
	else
	{
		CUiFrame* first = (m_lock.empty()) ? m_pRootFrame : m_lock.back();
		if (first)
		{
			CUiFrame* keyboardFocus = first->GetFrameAtKeyboard(NULL);
			if (keyboardFocus && keyboardFocus->HandleMsgProc(uMsg, wParam, lParam))
				keyboard = true;
		}
	}
	
	return keyboard;
}

// ----------------------------------------------------------------------------------
void CUi::SetScale(float scale)
{
	if ( m_scale = scale )
	{
		m_scale = scale;
		m_pRootFrame->SetScale(m_scale);
	}
}

// ----------------------------------------------------------------------------------
void CUi::SetCapture(CUiFrame* pUiFrame, int key)
{
	if (m_pCapture != pUiFrame)
	{
		m_pCapture = pUiFrame;
		m_captureKey = key;

		// 提高處理順序
		if (m_pCapture)
			m_pCapture->AdjustFrameLevel();
	}
}

// ----------------------------------------------------------------------------------
void CUi::OnReceiveDrag(CUiPoint& pt, CUiFrame* pExclude)
{
	CUiFrame* first = (m_lock.empty()) ? m_pRootFrame : m_lock.back();
	if (first)
	{
		CUiFrame* pUiFrame = first->GetFrameAtPoint(pt, pExclude);
		if (pUiFrame)
			pUiFrame->OnReceiveDrag();
	}
}

// ----------------------------------------------------------------------------------
void CUi::SetMouseDown(int key, CUiFrame* pUiFrame)
{
	if ( key >= 0 && key < MAX_MOUSE_BUTTON_NUM )
	{
		float time = timeGetTime() / 1000.0f;
		if ( pUiFrame && m_lastmouseDown[key] == pUiFrame && (time - m_lastmouseDownTime[key]) < 0.5f )
		{			
			if ( pUiFrame->GetClicksSet() & (0x01 << key) )
				pUiFrame->OnDoubleClick(CUiPoint((float)m_input.GetXPos(), (float)m_input.GetYPos()), key);
		}

		m_lastmouseDown[key] = m_mouseDown[key];
		m_lastmouseDownTime[key] = m_mouseDownTime[key];
		m_mouseDown[key] = pUiFrame;
		m_mouseDownTime[key] = time;
	}
}

// ----------------------------------------------------------------------------------
CUiFrame* CUi::GetMouseDown(int key)
{
	if ( key >= 0 && key < MAX_MOUSE_BUTTON_NUM )
		return m_mouseDown[key];
	return NULL;
}

// ----------------------------------------------------------------------------------
void CUi::LoadScriptFile(const char* filename)
{
	if (m_luaState && strlen(filename) > 0)
	{
		if ( luaL_loadfile(m_luaState, filename) != 0 || lua_resume(m_luaState, 0) != 0 )
		{
			const char* err = lua_tostring(m_luaState, -1);
			UiOuputError(err);
			lua_pop(m_luaState, 1);
		}
	}
}

// ----------------------------------------------------------------------------------
void CUi::LoadScript(const char* script)
{
	if (m_luaState && strlen(script) > 0)
	{
		if ( luaL_loadbuffer(m_luaState, script, strlen(script), 0) != 0 || lua_resume(m_luaState, 0) != 0 )
		{
			const char* err = lua_tostring(m_luaState, -1);
			UiOuputError(err);
			lua_pop(m_luaState, 1);
		}
	}
}

// ----------------------------------------------------------------------------------
void CUi::OpenTocFile(const char* filename, const char* resourcePath)
{
	if (m_xmlUi == NULL)
		m_xmlUi = new CXmlUi;

	m_resourcePath.empty();
	if ( resourcePath )
	{
		m_resourcePath = resourcePath;
	}
	m_xmlUi->OpenToc(filename);
}

// ----------------------------------------------------------------------------------
void CUi::BuildFrames()
{
	if ( m_xmlUi == NULL )
		return;	

	// 載入 xml nodes
	for ( vector<CXmlFile*>::iterator iter = m_xmlUi->m_files.begin(); iter != m_xmlUi->m_files.end(); iter++ )
	{
		LoadXmlFile(*iter);		
	}

	UI_SAFE_DELETE(m_xmlUi);
}

// ----------------------------------------------------------------------------------
CUiLayout* CUi::CreateObject(int type, const char* name, CUiLayout* pParent)
{
	CUiLayout* layout = NULL;

	if (pParent == NULL)
		pParent = m_pRootFrame;

	switch(type)
	{
	case CUiLayout::eUiType_FontString:
		layout = new CUiFontString(name, pParent, this);
		break;

	case CUiLayout::eUiType_Texture:
		layout = new CUiTexture(name, pParent, this);		
		break;

	case CUiLayout::eUiType_Frame:
		layout = new CUiFrame(name, pParent, this);		
		break;

	case CUiLayout::eUiType_Model:
		layout = new CUiModel(name, pParent, this);		
		break;

	case CUiLayout::eUiType_Button:
		layout = new CUiButton(name, pParent, this);		
		break;

	case CUiLayout::eUiType_CheckButton:
		layout = new CUiCheckButton(name, pParent, this);		
		break;

	case CUiLayout::eUiType_RadioButton:
		layout = new CUiRadioButton(name, pParent, this);		
		break;

	case CUiLayout::eUiType_EditBox:
		layout = new CUiEditBox(name, pParent, this);		
		break;

	case CUiLayout::eUiType_ListBox:
		layout = new CUiListBox(name, pParent, this);		
		break;

	case CUiLayout::eUiType_Slider:
		layout = new CUiSlider(name, pParent, this);		
		break;

	case CUiLayout::eUiType_StatusBar:
		layout = new CUiStatusBar(name, pParent, this);		
		break;

	case CUiLayout::eUiType_MessageFrame:
		layout = new CUiMessageFrame(name, pParent, this);
		break;

	case CUiLayout::eUiType_ScrollFrame:
		layout = new CUiScrollFrame(name, pParent, this);
		break;

	case CUiLayout::eUiType_Tooltip:
		layout = new CUiTooltip(name, pParent, this);
		break;
	}

	if (layout)
	{
		// 建立 Lua Table
		if (m_luaState)
		{
			assert(CUiLuaLayout::NewTable(m_luaState, layout));
			layout->SetLuaMetaTable(m_luaState);
			lua_pop(m_luaState, 1);
		}

		const char* layout_name = layout->GetName();
		if (layout_name && layout_name[0])
		{
			if (m_luaState)
			{
				CUiLuaLayout::PushLayoutTable(m_luaState, layout);
				if (!lua_isnil(m_luaState, -1))
					lua_setglobal(m_luaState, layout_name);			// Set table name
				else
					lua_pop(m_luaState, 1);							// Pop nil value
			}
		}
	}	

	return layout;
}

// ----------------------------------------------------------------------------------
CUiLayout* CUi::FindObject(const char* name)
{
	if (name)
	{
		map<const char*, CUiLayout*, ltstr>::iterator iter = m_object.find(name);
		if (iter != m_object.end())
			return iter->second;
	}
	return NULL;
}

// ----------------------------------------------------------------------------------
void CUi::RegisterEvent(const char* event, CUiFrame* pUiFrame)
{
	if (event == NULL || pUiFrame == NULL)
		return;

	map< string, vector<CUiFrame*> >::iterator iter = m_userEvent.find(event);
	if (iter != m_userEvent.end())
	{
		vector<CUiFrame*>& vec = iter->second;
		for (vector<CUiFrame*>::iterator i = vec.begin(); i != vec.end(); i++ )
		{
			if (*i == pUiFrame)
				return;
		}

		vec.push_back(pUiFrame);
	}
	else
	{
		vector<CUiFrame*> vec;
		vec.push_back(pUiFrame);
		m_userEvent.insert(make_pair(event, vec));
	}
}

// ----------------------------------------------------------------------------------
void CUi::UnregisterEvent(const char* event, CUiFrame* pUiFrame)
{
	if (event == NULL || pUiFrame == NULL)
		return;

	map< string, vector<CUiFrame*> >::iterator iter = m_userEvent.find(event);
	if (iter != m_userEvent.end())
	{
		vector<CUiFrame*>& vec = iter->second;
		for (vector<CUiFrame*>::iterator i = vec.begin(); i != vec.end(); i++ )
		{
			if (*i == pUiFrame)
			{
				vec.erase(i);
				return;
			}
		}
	}
}

// ----------------------------------------------------------------------------------
bool CUi::SendEvent(const char* event)
{
	if (event)
	{
		map< string, vector<CUiFrame*> >::iterator iter = m_userEvent.find(event);
		if (iter != m_userEvent.end())
		{
			vector<CUiFrame*>& vec = iter->second;
			for (vector<CUiFrame*>::iterator i = vec.begin(); i != vec.end(); i++ )
				(*i)->OnEvent(event);

			return true;
		}
	}
	return false;
}

// ----------------------------------------------------------------------------------
void CUi::InsertObject(CUiLayout* layout)
{
	const char* layout_name = layout->GetName();
	if (layout_name && layout_name[0])
	{
		if (m_luaState)
		{
			CUiLuaLayout::PushLayoutTable(m_luaState, layout);
			if (!lua_isnil(m_luaState, -1))
				lua_setglobal(m_luaState, layout_name);			// Set table name
			else
				lua_pop(m_luaState, 1);							// Pop nil value
		}
		m_object.insert(make_pair(layout_name, layout));
	}
}

// ----------------------------------------------------------------------------------
void CUi::DeleteObject(CUiLayout* layout)
{
	if (layout)
	{
		const char* name = layout->GetName();
		if (name)
			m_object.erase(name);

		if (m_luaState)
		{
			CUiLuaLayout::DeleteTable(m_luaState, layout);
		}

		// 檢查元件是否有註冊事件
		map< string, vector<CUiFrame*> >::iterator iter;
		for (iter = m_userEvent.begin(); iter != m_userEvent.end(); iter++)
		{
			vector<CUiFrame*>& vec = iter->second;
			for (vector<CUiFrame*>::iterator i = vec.begin(); i != vec.end(); i++ )
			{
				if (*i == layout)
				{
					vec.erase(i);
					break;
				}
			}
		}
	}
}

// ----------------------------------------------------------------------------------
void CUi::LoadXmlFile(CXmlFile* pXmlFile)
{
	for ( vector<CXmlNode*>::iterator iter = pXmlFile->m_nodes.begin(); iter != pXmlFile->m_nodes.end(); iter++ )
	{
		CXmlNode* pXmlNode = *iter;
		if ( pXmlNode->GetType() == eXmlUiType_Script )
		{
			LoadXmlScript(pXmlNode);
		}
		else
		{
			CXmlLayout* pXmlLayout = (CXmlLayout*)pXmlNode;
			if (!pXmlLayout->IsVirtual())
			{
				const char* parentName = (pXmlLayout->m_parent) ? pXmlLayout->m_parent->m_name.c_str() : "";
				LoadXmlFrames(FindObject(parentName), pXmlLayout);
			}
		}
	}
}

// ----------------------------------------------------------------------------------
void CUi::LoadXmlScript(CXmlNode* pXmlNode)
{
	CXmlScript* pXmlScript = (CXmlScript*)pXmlNode;

	LoadScriptFile(pXmlScript->m_file.c_str());
	LoadScript(pXmlScript->m_content.c_str());
}

// ----------------------------------------------------------------------------------
CUiFrame* CUi::LoadXmlFrames(CUiLayout* pUiParent, CXmlLayout* pXmlLayout)
{
	CUiFrame* pUiFrame = NULL;

	if (pXmlLayout == NULL)
		return NULL;

	const char* name = pXmlLayout->GetName();
	switch (pXmlLayout->GetType())
	{
	case eXmlUiType_Frame:
		pUiFrame = (CUiFrame*)CreateObject(CUiLayout::eUiType_Frame, name, pUiParent);
		LoadXmlFrame(pUiFrame, pXmlLayout);
		break;

	case eXmlUiType_Model:
		pUiFrame = (CUiFrame*)CreateObject(CUiLayout::eUiType_Model, name, pUiParent);
		LoadXmlModel(pUiFrame, pXmlLayout);
		break;

	case eXmlUiType_Button:
		pUiFrame = (CUiFrame*)CreateObject(CUiLayout::eUiType_Button, name, pUiParent);
		LoadXmlButton(pUiFrame, pXmlLayout);
		break;

	case eXmlUiType_CheckButton:
		pUiFrame = (CUiFrame*)CreateObject(CUiLayout::eUiType_CheckButton, name, pUiParent);
		LoadXmlCheckButton(pUiFrame, pXmlLayout);
		break;

	case eXmlUiType_RadioButton:
		pUiFrame = (CUiFrame*)CreateObject(CUiLayout::eUiType_RadioButton, name, pUiParent);
		LoadXmlRadioButton(pUiFrame, pXmlLayout);
		break;

	case eXmlUiType_Slider:
		pUiFrame = (CUiFrame*)CreateObject(CUiLayout::eUiType_Slider, name, pUiParent);
		LoadXmlSlider(pUiFrame, pXmlLayout);
		break;

	case eXmlUiType_StatusBar:
		pUiFrame = (CUiFrame*)CreateObject(CUiLayout::eUiType_StatusBar, name, pUiParent);
		LoadXmlStatusBar(pUiFrame, pXmlLayout);
		break;

	case eXmlUiType_EditBox:
		pUiFrame = (CUiFrame*)CreateObject(CUiLayout::eUiType_EditBox, name, pUiParent);
		LoadXmlEditBox(pUiFrame, pXmlLayout);
		break;

	case eXmlUiType_ListBox:
		pUiFrame = (CUiFrame*)CreateObject(CUiLayout::eUiType_ListBox, name, pUiParent);
		LoadXmlListBox(pUiFrame, pXmlLayout);
		break;

	case eXmlUiType_MessageFrame:
		pUiFrame = (CUiFrame*)CreateObject(CUiLayout::eUiType_MessageFrame, name, pUiParent);
		LoadXmlMessageFrame(pUiFrame, pXmlLayout);
		break;

	case eXmlUiType_ScrollFrame:
		pUiFrame = (CUiFrame*)CreateObject(CUiLayout::eUiType_ScrollFrame, name, pUiParent);
		LoadXmlScrollFrame(pUiFrame, pXmlLayout);
		break;

	case eXmlUiType_Tooltip:
		pUiFrame = (CUiFrame*)CreateObject(CUiLayout::eUiType_Tooltip, name, pUiParent);
		LoadXmlTooltip(pUiFrame, pXmlLayout);
		break;
	}

	if (pUiFrame)
		pUiFrame->OnLoad();

	return pUiFrame;
}

// ----------------------------------------------------------------------------------
CUiLayout* CUi::LoadXmlLayers(CUiLayout* pUiParent, CXmlLayout* pXmlLayout)
{
	CUiLayout* pUiLayout = NULL;

	if (pXmlLayout == NULL)
		return NULL;

	const char* name = pXmlLayout->GetName();
	switch (pXmlLayout->GetType())
	{
	case eXmlUiType_FontString:
		pUiLayout = CreateObject(CUiLayout::eUiType_FontString, name, pUiParent);
		LoadXmlFontString((CUiFontString*)pUiLayout, (CXmlFontString*)pXmlLayout);
		break;

	case eXmlUiType_Texture:
		pUiLayout = CreateObject(CUiLayout::eUiType_Texture, name, pUiParent);
		LoadXmlTexture((CUiTexture*)pUiLayout, (CXmlTexture*)pXmlLayout);
		break;
	}

	return pUiLayout;
}

// ----------------------------------------------------------------------------------
void CUi::LoadXmlLayout(CUiLayout* pUiLayout, CXmlLayout* pXmlLayout)
{
	pUiLayout->SetVisible(pXmlLayout->m_isVisible);
	// pUiLayout->SetSize(CUiSize(pXmlLayout->m_size.m_x, pXmlLayout->m_size.m_y));
	pUiLayout->SetAnchorSize(CUiSize(pXmlLayout->m_size.m_x, pXmlLayout->m_size.m_y));	
	
	// Set Anchors
	vector<CUiAnchor> anchors;
	vector<CXmlAnchor>& vec = pXmlLayout->m_anchors.m_vector;
	for (vector<CXmlAnchor>::iterator iter = vec.begin(); iter != vec.end(); iter++)
	{
		CUiAnchor anchor;
		anchor.m_offset.m_x		= (*iter).m_offset.m_x;
		anchor.m_offset.m_y		= (*iter).m_offset.m_y;
		anchor.m_point			= GetXmlAnchorPoint((*iter).m_point);
		anchor.m_relativePoint	= GetXmlAnchorPoint((*iter).m_relativePoint);

		if ((*iter).m_relativeTo.empty())
			anchor.m_relativeTo	= pUiLayout->GetParent();
		else
		{
			const char* name = (*iter).m_relativeTo.c_str();
			anchor.m_relativeTo = FindObject((*iter).m_relativeTo.c_str());
			// 關連元件不存在
			assert(anchor.m_relativeTo);
		}
		anchors.push_back(anchor);
	}

	// 最少有一組關連(父元件)
	if (anchors.empty())
		anchors.push_back(CUiAnchor());

	pUiLayout->ClearAllAnchors();
	for (vector<CUiAnchor>::iterator iter = anchors.begin(); iter != anchors.end(); iter++)
		pUiLayout->SetAnchor(*iter);
}

// ----------------------------------------------------------------------------------
void CUi::LoadXmlFontString(CUiLayout* pUiLayout, CXmlLayout* pXmlLayout)
{
	LoadXmlLayout(pUiLayout, pXmlLayout);

	CUiFontString* pUiFontString = dynamic_cast<CUiFontString*>(pUiLayout);
	CXmlFontString* pXmlFontString = dynamic_cast<CXmlFontString*>(pXmlLayout);

	if (pUiFontString == NULL || pXmlFontString == NULL)
		return;	

	string fullname = m_resourcePath + pXmlFontString->m_font;
	if ( fullname.empty() || AddFontResourceEx( fullname.c_str(), FR_PRIVATE, 0 ) == 0 )
		return;

	string fontname = GetFontNameFromFile( fullname.c_str() );
	if ( fontname.empty() )
		return;

	// 
	CRuFontType* pFontType = CRuFontType::GetFontType(fontname.c_str(),
												  (int)pXmlFontString->m_height.m_val,
                                                  GetXmlRuFontWeight(pXmlFontString->m_weight),
												  ruFONTOUTLINE_NORMAL);

	// 字型錯誤
	assert(pFontType);
	pUiFontString->SetFontType(pFontType);

	// 顏色
	pUiFontString->SetColor(pXmlFontString->m_color.m_r, pXmlFontString->m_color.m_g, pXmlFontString->m_color.m_b);
	pUiFontString->SetAlpha(pXmlFontString->m_color.m_a);
	pUiFontString->SetBytes(pXmlFontString->m_bytes);
	pUiFontString->SetJustifyVType(GetXmlFontJustifyVType(pXmlFontString->m_justifyV));
	pUiFontString->SetJustifyHType(GetXmlFontJustifyHType(pXmlFontString->m_justifyH));
	pUiFontString->SetSpacing(pXmlFontString->m_spacing);

	// 背景色
	if (pXmlFontString->m_pShadow)
	{
		RuFontShadow shadow;
		CUiColor tmpColor;
		tmpColor.m_r	= pXmlFontString->m_pShadow->m_color.m_r;
		tmpColor.m_g	= pXmlFontString->m_pShadow->m_color.m_g;
		tmpColor.m_b	= pXmlFontString->m_pShadow->m_color.m_b;
		tmpColor.m_a	= pXmlFontString->m_pShadow->m_color.m_a;
		shadow.color	= tmpColor.GetColor();
		shadow.x		= (short)pXmlFontString->m_pShadow->m_offset.m_x;
		shadow.y		= (short)pXmlFontString->m_pShadow->m_offset.m_y;
		pUiFontString->SetFontShadow(&shadow);
	}

	const WCHAR* text = TransToWChar(pXmlFontString->m_text.c_str());
	pUiFontString->SetText(text);
	UI_SAFE_DELETE_ARRAY(text);
}

// ----------------------------------------------------------------------------------
void CUi::LoadXmlTexture(CUiLayout* pUiLayout, CXmlLayout* pXmlLayout)
{
	LoadXmlLayout(pUiLayout, pXmlLayout);	

	CUiTexture* pUiTexture = dynamic_cast<CUiTexture*>(pUiLayout);
	CXmlTexture* pXmlTexture = dynamic_cast<CXmlTexture*>(pXmlLayout);

	if (pUiTexture == NULL || pXmlTexture == NULL)
		return;

	pUiTexture->SetFile(pXmlTexture->m_file.c_str());
	pUiTexture->SetColor(pXmlTexture->m_color.m_r, pXmlTexture->m_color.m_g, pXmlTexture->m_color.m_b);
	pUiTexture->SetAlpha(pXmlTexture->m_color.m_a);
	pUiTexture->SetAlphaMode(GetXmlTextureAlphaMode(pXmlTexture->m_alphaMode));
	pUiTexture->SetAnimationSpeed(pXmlTexture->m_animationSpeed);

	vector<CRuRectangle> texCoords;
	for(vector<CXmlTexCoords>::iterator iter = pXmlTexture->m_texCoords.begin(); iter != pXmlTexture->m_texCoords.end(); iter++)
	{
		CRuRectangle rc;
		rc.m_left	= (*iter).m_left;
		rc.m_right	= (*iter).m_right;
		rc.m_top	= (*iter).m_top;
		rc.m_bottom	= (*iter).m_bottom;	
		texCoords.push_back(rc);
	}

	if (texCoords.empty())
		pUiTexture->SetTexCoords(0, NULL);
	else
		pUiTexture->SetTexCoords(texCoords.size(), &texCoords[0]);
}

// ----------------------------------------------------------------------------------
void CUi::LoadXmlFrame(CUiLayout* pUiLayout, CXmlLayout* pXmlLayout)
{
	LoadXmlLayout(pUiLayout, pXmlLayout);

	CUiFrame* pUiFrame = dynamic_cast<CUiFrame*>(pUiLayout);
	CXmlFrame* pXmlFrame = dynamic_cast<CXmlFrame*>(pXmlLayout);

	if (pUiFrame == NULL || pXmlFrame == NULL)
		return;

	switch (pXmlFrame->m_frameStrata)
	{
	case CXmlFrame::eStrata_Background:
		pUiFrame->SetFrameStrata(eUIFrame_Strata_Background);
		break;

	case CXmlFrame::eStrata_Low:
		pUiFrame->SetFrameStrata(eUIFrame_Strata_Low);
		break;

	case CXmlFrame::eStrata_Medium:
		pUiFrame->SetFrameStrata(eUIFrame_Strata_Medium);
		break;

	case CXmlFrame::eStrata_High:
		pUiFrame->SetFrameStrata(eUIFrame_Strata_High);
		break;

	case CXmlFrame::eStrata_Dialog:
		pUiFrame->SetFrameStrata(eUIFrame_Strata_Dialog);
		break;

	case CXmlFrame::eStrata_Tooltip:
		pUiFrame->SetFrameStrata(eUIFrame_Strata_Tooltip);
		break;
	}

	pUiFrame->SetID(pXmlFrame->m_id);	
	pUiFrame->SetFrameLevel(pXmlFrame->m_frameLevel);
	pUiFrame->SetTopLevel(pXmlFrame->m_topLevel);
	pUiFrame->SetAlpha(pXmlFrame->m_alpha);
	pUiFrame->SetKeyboardEnable(pXmlFrame->m_isEnableKeyboard);
	pUiFrame->SetMouseEnable(pXmlFrame->m_isEnableMouse);
	pUiFrame->SetMovable(pXmlFrame->m_isMovable);

	CUiRectangle inset;
	inset.m_left	= pXmlFrame->m_hitRectInsets.m_left;
	inset.m_right	= pXmlFrame->m_hitRectInsets.m_right;
	inset.m_top		= pXmlFrame->m_hitRectInsets.m_top;
	inset.m_bottom	= pXmlFrame->m_hitRectInsets.m_bottom;
	pUiFrame->SetHitRectInsets(inset);
	
	if (pXmlFrame->m_resizeBounds.m_maxBounds)
	{
		CUiSize size;
		size.m_x = pXmlFrame->m_resizeBounds.m_maxBounds->m_x;
		size.m_y = pXmlFrame->m_resizeBounds.m_maxBounds->m_y;
		pUiFrame->SetMaxResizeBounds(size);
	}
	if (pXmlFrame->m_resizeBounds.m_minBounds)
	{
		CUiSize size;
		size.m_x = pXmlFrame->m_resizeBounds.m_minBounds->m_x;
		size.m_y = pXmlFrame->m_resizeBounds.m_minBounds->m_y;
		pUiFrame->SetMinResizeBounds(size);
	}

	if (pXmlFrame->m_pBackdrop)
	{
		CTextureBackdrop backdrop;
		CRuRectangle rc;
		rc.m_left	= pXmlFrame->m_pBackdrop->m_bgInsets.m_left;
		rc.m_right	= pXmlFrame->m_pBackdrop->m_bgInsets.m_right;
		rc.m_top	= pXmlFrame->m_pBackdrop->m_bgInsets.m_top;
		rc.m_bottom	= pXmlFrame->m_pBackdrop->m_bgInsets.m_bottom;

		backdrop.SetEdgeFileName(pXmlFrame->m_pBackdrop->m_edgeFile.c_str());
		backdrop.SetTileFileName(pXmlFrame->m_pBackdrop->m_tileFile.c_str());
		backdrop.SetEdgeSize(pXmlFrame->m_pBackdrop->m_edgeSize.m_val);
		backdrop.SetTileSize(pXmlFrame->m_pBackdrop->m_tileSize.m_val);
		backdrop.SetBackgroundOffset(rc);

		pUiFrame->SetBackdrop(&backdrop);
	}

	// Layers
	for (multimap<int, CXmlLayout*>::iterator iter = pXmlFrame->m_layers.begin(); iter != pXmlFrame->m_layers.end(); iter++)
		pUiFrame->SetLayers(GetXmlLayer(iter->first), LoadXmlLayers(pUiFrame, iter->second));

	// Frames
	for (vector<CXmlFrame*>::iterator iter = pXmlFrame->m_frames.begin(); iter != pXmlFrame->m_frames.end(); iter++)
		LoadXmlFrames(pUiFrame, *iter);	

	// Scripts
	for (map<int, string>::iterator iter = pXmlFrame->m_scripts.begin(); iter != pXmlFrame->m_scripts.end(); iter++)
		pUiFrame->SetScripts(GetXmlScriptType(iter->first), (iter->second).c_str(), NULL);
}

// ----------------------------------------------------------------------------------
void CUi::LoadXmlModel(CUiLayout* pUiLayout, CXmlLayout* pXmlLayout)
{
	LoadXmlFrame(pUiLayout, pXmlLayout);
}

// ----------------------------------------------------------------------------------
void CUi::LoadXmlButton(CUiLayout* pUiLayout, CXmlLayout* pXmlLayout)
{
	LoadXmlFrame(pUiLayout, pXmlLayout);

	CUiButton* pUiButton = dynamic_cast<CUiButton*>(pUiLayout);
	CXmlButton* pXmlButton = dynamic_cast<CXmlButton*>(pXmlLayout);
	if (pUiButton == NULL || pXmlButton == NULL)
		return;

	if (pXmlButton->m_normalTexture)
		pUiButton->SetNormalTexture((CUiTexture*)LoadXmlLayers(pUiButton, pXmlButton->m_normalTexture));
	if (pXmlButton->m_pushedTexture)
		pUiButton->SetPushedTexture((CUiTexture*)LoadXmlLayers(pUiButton, pXmlButton->m_pushedTexture));
	if (pXmlButton->m_disabledTexture)
		pUiButton->SetDisabledTexture((CUiTexture*)LoadXmlLayers(pUiButton, pXmlButton->m_disabledTexture));
	if (pXmlButton->m_highlightTexture)
		pUiButton->SetHighlightTexture((CUiTexture*)LoadXmlLayers(pUiButton, pXmlButton->m_highlightTexture));
	if (pXmlButton->m_normalText)
		pUiButton->SetNormalText((CUiFontString*)LoadXmlLayers(pUiButton, pXmlButton->m_normalText));
	if (pXmlButton->m_disabledText)
		pUiButton->SetDisabledText((CUiFontString*)LoadXmlLayers(pUiButton, pXmlButton->m_disabledText));
	if (pXmlButton->m_highlightText)
		pUiButton->SetHighlightText((CUiFontString*)LoadXmlLayers(pUiButton, pXmlButton->m_highlightText));

	CUiPoint offset;
	offset.m_x	= pXmlButton->m_pushedTextOffset.m_x;
	offset.m_y	= pXmlButton->m_pushedTextOffset.m_y;
	pUiButton->SetPushTextOffset(offset);

	const WCHAR* text = TransToWChar(pXmlButton->m_text.c_str());
	pUiButton->SetText(text);
	UI_SAFE_DELETE_ARRAY(text);
}

// ----------------------------------------------------------------------------------
void CUi::LoadXmlCheckButton(CUiLayout* pUiLayout, CXmlLayout* pXmlLayout)
{
	LoadXmlButton(pUiLayout, pXmlLayout);

	CUiCheckButton* pUiCheckButton = dynamic_cast<CUiCheckButton*>(pUiLayout);
	CXmlCheckButton* pXmlCheckButton = dynamic_cast<CXmlCheckButton*>(pXmlLayout);
	if (pUiCheckButton == NULL || pXmlCheckButton == NULL)
		return;

	if (pXmlCheckButton->m_checkedTexture)
		pUiCheckButton->SetCheckedTexture((CUiTexture*)LoadXmlLayers(pUiCheckButton, pXmlCheckButton->m_checkedTexture));
	if (pXmlCheckButton->m_disabledCheckedTexture)
		pUiCheckButton->SetDisabledCheckedTexture((CUiTexture*)LoadXmlLayers(pUiCheckButton, pXmlCheckButton->m_disabledCheckedTexture));

	pUiCheckButton->SetChecked(pXmlCheckButton->m_checked);
	pUiCheckButton->SetAutoChecked(pXmlCheckButton->m_autoChecked);
}

// ----------------------------------------------------------------------------------
void CUi::LoadXmlRadioButton(CUiLayout* pUiLayout, CXmlLayout* pXmlLayout)
{
	LoadXmlCheckButton(pUiLayout, pXmlLayout);

	CUiRadioButton* pUiRadioButton = dynamic_cast<CUiRadioButton*>(pUiLayout);
	CXmlRadioButton* pXmlRadioButton = dynamic_cast<CXmlRadioButton*>(pXmlLayout);
	if (pUiRadioButton == NULL || pXmlRadioButton ==NULL)
		return;

	pUiRadioButton->SetGroupId(pXmlRadioButton->m_groupId);
}

// ----------------------------------------------------------------------------------
void CUi::LoadXmlSlider(CUiLayout* pUiLayout, CXmlLayout* pXmlLayout)
{
	LoadXmlFrame(pUiLayout, pXmlLayout);

	CUiSlider* pUiSlider = dynamic_cast<CUiSlider*>(pUiLayout);
	CXmlSlider* pXmlSlider = dynamic_cast<CXmlSlider*>(pXmlLayout);
	if (pUiSlider == NULL || pXmlSlider == NULL)
		return;

	switch (pXmlSlider->m_orientation)
	{
	case CXmlSlider::eOrientation_Vertical:
		pUiSlider->SetOrientation(CUiSlider::eOrientation_Vertical);
		break;
	case CXmlSlider::eOrientation_Horizontal:
		pUiSlider->SetOrientation(CUiSlider::eOrientation_Horizontal);
		break;
	}

	pUiSlider->SetMaxValue(pXmlSlider->m_maxValue);
	pUiSlider->SetMinValue(pXmlSlider->m_minValue);
	pUiSlider->SetValue(pXmlSlider->m_defaultValue);	

	if (pXmlSlider->m_thumbTexture)
		pUiSlider->SetThumbTexture((CUiTexture*)LoadXmlLayers(pUiSlider, pXmlSlider->m_thumbTexture));
}

// ----------------------------------------------------------------------------------
void CUi::LoadXmlStatusBar(CUiLayout* pUiLayout, CXmlLayout* pXmlLayout)
{
	LoadXmlFrame(pUiLayout, pXmlLayout);

	CUiStatusBar* pUiStatusBar = dynamic_cast<CUiStatusBar*>(pUiLayout);
	CXmlStatusBar* pXmlStatusBar = dynamic_cast<CXmlStatusBar*>(pXmlLayout);
	if (pUiStatusBar == NULL || pXmlStatusBar == NULL)
		return;

	pUiStatusBar->SetMaxValue(pXmlStatusBar->m_maxValue);
	pUiStatusBar->SetMinValue(pXmlStatusBar->m_minValue);
	pUiStatusBar->SetValue(pXmlStatusBar->m_defaultValue);

	CUiColor color;
	color.m_r = pXmlStatusBar->m_barColor.m_r;
	color.m_g = pXmlStatusBar->m_barColor.m_g;
	color.m_b = pXmlStatusBar->m_barColor.m_b;
	color.m_a = pXmlStatusBar->m_barColor.m_a;
	pUiStatusBar->SetBarColor(color);

	if (pXmlStatusBar->m_barTexture)
		pUiStatusBar->SetBarTexture((CUiTexture*)LoadXmlLayers(pUiStatusBar, pXmlStatusBar->m_barTexture));
}

// ----------------------------------------------------------------------------------
void CUi::LoadXmlEditBox(CUiLayout* pUiLayout, CXmlLayout* pXmlLayout)
{
	LoadXmlFrame(pUiLayout, pXmlLayout);

	CUiEditBox* pUiEditBox = dynamic_cast<CUiEditBox*>(pUiLayout);
	CXmlEditBox* pXmlEditBox = dynamic_cast<CXmlEditBox*>(pXmlLayout);
	if (pUiEditBox == NULL || pXmlEditBox == NULL)
		return;

	pUiEditBox->SetHistoryLines(pXmlEditBox->m_historyLines);
	pUiEditBox->SetLetters(pXmlEditBox->m_letters);
	pUiEditBox->SetNumeric(pXmlEditBox->m_isNumeric);
	pUiEditBox->SetPassword(pXmlEditBox->m_isPassword);
	pUiEditBox->SetMultiMode(pXmlEditBox->m_isMultiLine);

	CUiColor color;
	color.m_r = pXmlEditBox->m_highlightColor.m_r;
	color.m_g = pXmlEditBox->m_highlightColor.m_g;
	color.m_b = pXmlEditBox->m_highlightColor.m_b;
	color.m_a = pXmlEditBox->m_highlightColor.m_a;
	pUiEditBox->SetHighlightColor(color.GetColor());

	CUiRectangle inset;
	inset.m_left	= pXmlEditBox->m_textInsets.m_left;
	inset.m_right	= pXmlEditBox->m_textInsets.m_right;
	inset.m_top		= pXmlEditBox->m_textInsets.m_top;
	inset.m_bottom	= pXmlEditBox->m_textInsets.m_bottom;
	pUiEditBox->SetTextInset(inset);

	if (pXmlEditBox->m_fontString)
		pUiEditBox->SetFontString((CUiFontString*)LoadXmlLayers(pUiEditBox, pXmlEditBox->m_fontString));
}

// ----------------------------------------------------------------------------------
void CUi::LoadXmlListBox(CUiLayout* pUiLayout, CXmlLayout* pXmlLayout)
{
	LoadXmlFrame(pUiLayout, pXmlLayout);

	CUiListBox* pUiListBox = dynamic_cast<CUiListBox*>(pUiLayout);
	CXmlListBox* pXmlListBox = dynamic_cast<CXmlListBox*>(pXmlLayout);
	if (pUiListBox == NULL || pXmlListBox == NULL)
		return;

	CUiRectangle inset;
	inset.m_left	= pXmlListBox->m_textInsets.m_left;
	inset.m_right	= pXmlListBox->m_textInsets.m_right;
	inset.m_top		= pXmlListBox->m_textInsets.m_top;
	inset.m_bottom	= pXmlListBox->m_textInsets.m_bottom;
	pUiListBox->SetTextInset(inset);

	if (pXmlListBox->m_fontString)
		pUiListBox->SetFontString((CUiFontString*)LoadXmlLayers(pUiListBox, pXmlListBox->m_fontString));
}

// ----------------------------------------------------------------------------------
void CUi::LoadXmlMessageFrame(CUiLayout* pUiLayout, CXmlLayout* pXmlLayout)
{
	LoadXmlFrame(pUiLayout, pXmlLayout);

	CUiMessageFrame* pUiMessageFrame = dynamic_cast<CUiMessageFrame*>(pUiLayout);
	CXmlMessageFrame* pXmlMessageFrame = dynamic_cast<CXmlMessageFrame*>(pXmlLayout);
	if (pUiMessageFrame == NULL || pXmlMessageFrame == NULL)
		return;

	if (pXmlMessageFrame->m_fontString)
		pUiMessageFrame->SetFontString((CUiFontString*)LoadXmlLayers(pUiMessageFrame, pXmlMessageFrame->m_fontString));

	CUiRectangle inset;
	inset.m_left	= pXmlMessageFrame->m_textInsets.m_left;
	inset.m_right	= pXmlMessageFrame->m_textInsets.m_right;
	inset.m_top		= pXmlMessageFrame->m_textInsets.m_top;
	inset.m_bottom	= pXmlMessageFrame->m_textInsets.m_bottom;
	pUiMessageFrame->SetTextInset(inset);

	pUiMessageFrame->SetMaxLines(pXmlMessageFrame->m_maxLines);
	pUiMessageFrame->SetFadeDuration(pXmlMessageFrame->m_fadeDuration);
	pUiMessageFrame->SetDisplayDuration(pXmlMessageFrame->m_displayDuration);
}

// ----------------------------------------------------------------------------------
void CUi::LoadXmlScrollFrame(CUiLayout* pUiLayout, CXmlLayout* pXmlLayout)
{
	LoadXmlFrame(pUiLayout, pXmlLayout);
}

// ----------------------------------------------------------------------------------
void CUi::LoadXmlTooltip(CUiLayout* pUiLayout, CXmlLayout* pXmlLayout)
{
	LoadXmlFrame(pUiLayout, pXmlLayout);
}

// ----------------------------------------------------------------------------------
int	GetXmlType(int type)
{
	switch (type)
	{
	case eXmlUiType_Layout:
		return CUiLayout::eUiType_Layout;

	case eXmlUiType_FontString:
		return CUiLayout::eUiType_FontString;

	case eXmlUiType_Texture:
		return CUiLayout::eUiType_Texture;

	case eXmlUiType_Frame:
		return CUiLayout::eUiType_Frame;

	case eXmlUiType_Model:
		return CUiLayout::eUiType_Model;

	case eXmlUiType_Button:
		return CUiLayout::eUiType_Button;

	case eXmlUiType_CheckButton:
		return CUiLayout::eUiType_CheckButton;

	case eXmlUiType_RadioButton:
		return CUiLayout::eUiType_RadioButton;

	case eXmlUiType_StatusBar:
		return CUiLayout::eUiType_StatusBar;

	case eXmlUiType_Slider:
		return CUiLayout::eUiType_Slider;

	case eXmlUiType_EditBox:
		return CUiLayout::eUiType_EditBox;

	case eXmlUiType_ListBox:
		return CUiLayout::eUiType_ListBox;

	case eXmlUiType_MessageFrame:
		return CUiLayout::eUiType_MessageFrame;

	case eXmlUiType_ScrollFrame:
		return CUiLayout::eUiType_ScrollFrame;
	}

	return -1;
}

// ----------------------------------------------------------------------------------
int	GetXmlAnchorPoint(int point)
{
	switch (point)
	{
	case CXmlAnchor::eAnchor_TopLeft:
		return CUiAnchor::eAnchor_TopLeft;

	case CXmlAnchor::eAnchor_Top:
		return CUiAnchor::eAnchor_Top;

	case CXmlAnchor::eAnchor_TopRight:
		return CUiAnchor::eAnchor_TopRight;

	case CXmlAnchor::eAnchor_Left:
		return CUiAnchor::eAnchor_Left;

	case CXmlAnchor::eAnchor_Center:
		return CUiAnchor::eAnchor_Center;

	case CXmlAnchor::eAnchor_Right:
		return CUiAnchor::eAnchor_Right;

	case CXmlAnchor::eAnchor_BottomLeft:
		return CUiAnchor::eAnchor_BottomLeft;

	case CXmlAnchor::eAnchor_Bottom:
		return CUiAnchor::eAnchor_Bottom;

	case CXmlAnchor::eAnchor_BottomRight:
		return CUiAnchor::eAnchor_BottomRight;
	}

	return CUiAnchor::eAnchor_Null;
}

// ----------------------------------------------------------------------------------
int	GetXmlLayer(int layer)
{
	switch(layer)
	{
	case CXmlFrame::eLayer_Background:
		return CUiFrame::eLayerType_Background;
	case CXmlFrame::eLayer_Border:
		return CUiFrame::eLayerType_Border;
	case CXmlFrame::eLayer_Artwork:
		return CUiFrame::eLayerType_Artwork;
	case CXmlFrame::eLayer_Overlay:
		return CUiFrame::eLayerType_Overlay;
	case CXmlFrame::eLayer_Highlight:
		return CUiFrame::eLayerType_Highlight;
	}
	return -1;
}

// ----------------------------------------------------------------------------------
int GetXmlScriptType(int type)
{
	switch(type)
	{
	case CXmlFrame::eOn_Load:
		return CUiFrame::eEventType_Load;

	case CXmlFrame::eOn_Update:
		return CUiFrame::eEventType_Update;

	case CXmlFrame::eOn_Resize:
		return CUiFrame::eEventType_Resize;

	case CXmlFrame::eOn_Show:
		return CUiFrame::eEventType_Show;

	case CXmlFrame::eOn_Hide:
		return CUiFrame::eEventType_Hide;

	case CXmlFrame::eOn_TabPressed:
		return CUiFrame::eEventType_TabPressed;

	case CXmlFrame::eOn_EnterPressed:
		return CUiFrame::eEventType_EnterPressed;

	case CXmlFrame::eOn_EscapePressed:
		return CUiFrame::eEventType_EscapePressed;

	case CXmlFrame::eOn_SpacePressed:
		return CUiFrame::eEventType_SpacePressed;

	case CXmlFrame::eOn_ArrowUpPressed:
		return CUiFrame::eEventType_ArrowUpPressed;

	case CXmlFrame::eOn_ArrowDownPressed:
		return CUiFrame::eEventType_ArrowDownPressed;

	case CXmlFrame::eOn_KeyDown:
		return CUiFrame::eEventType_KeyDown;

	case CXmlFrame::eOn_KeyUp:
		return CUiFrame::eEventType_KeyUp;

	case CXmlFrame::eOn_Char:
		return CUiFrame::eEventType_Char;

	case CXmlFrame::eOn_MouseDown:
		return CUiFrame::eEventType_MouseDown;

	case CXmlFrame::eOn_MouseUp:
		return CUiFrame::eEventType_MouseUp;

	case CXmlFrame::eOn_Click:
		return CUiFrame::eEventType_Click;

	case CXmlFrame::eOn_DoublebClick:
		return CUiFrame::eEventType_DoubleClick;

	case CXmlFrame::eOn_MouseWheel:
		return CUiFrame::eEventType_MouseWheel;

	case CXmlFrame::eOn_MouseEnter:
		return CUiFrame::eEventType_MouseEnter;

	case CXmlFrame::eOn_MouseLeave:
		return CUiFrame::eEventType_MouseLeave;

	case CXmlFrame::eOn_DragStart:
		return CUiFrame::eEventType_DragBegin;

	case CXmlFrame::eOn_DragStop:
		return CUiFrame::eEventType_DragStop;

	case CXmlFrame::eOn_ReceiveDrag:
		return CUiFrame::eEventType_ReceiveDrag;

	case CXmlFrame::eOn_ValueChanged:
		return CUiFrame::eEventType_ValueChanged;

	case CXmlFrame::eOn_TextChanged:
		return CUiFrame::eEventType_TextChanged;

	case CXmlFrame::eOn_VerticalScroll:
		return CUiFrame::eEventType_VerticalScroll;

	case CXmlFrame::eOn_HorizontalScroll:
		return CUiFrame::eEventType_HorizontalScroll;

	case CXmlFrame::eOn_ScrollRangeChanged:
		return CUiFrame::eEventType_ScrollRangeChanged;

	case CXmlFrame::eOn_Event:
		return CUiFrame::eEventType_Event;
	}

	return -1;
}

// ----------------------------------------------------------------------------------
RuFontWeight GetXmlRuFontWeight(int weight)
{
	switch(weight)
	{
	case CXmlFontString::eFontWeight_Thin:
		return ruFONTWEIGHT_THIN;
	case CXmlFontString::eFontWeight_Normal:
		return ruFONTWEIGHT_NORMAL;
	case CXmlFontString::eFontWeight_Bold:
		return ruFONTWEIGHT_BOLD;
	}
	return ruFONTWEIGHT_NORMAL;
}

// ----------------------------------------------------------------------------------
int	GetXmlFontJustifyVType(int type)
{
	switch(type)
	{
	case CXmlFontString::eJustifyVType_Top:
		return CUiFontString::eJustifyV_Top;
	case CXmlFontString::eJustifyVType_Middle:
		return CUiFontString::eJustifyV_Middle;
	case CXmlFontString::eJustifyVType_Bottom:
		return CUiFontString::eJustifyV_Bottom;
	}
	return CUiFontString::eJustifyV_Top;
}

// ----------------------------------------------------------------------------------
int	GetXmlFontJustifyHType(int type)
{
	switch(type)
	{
	case CXmlFontString::eJustifyHType_Left:
		return CUiFontString::eJustifyH_Left;
	case CXmlFontString::eJustifyHType_Center:
		return CUiFontString::eJustifyH_Center;
	case CXmlFontString::eJustifyHType_Right:
		return CUiFontString::eJustifyH_Right;
	}
	return CUiFontString::eJustifyH_Left;
}

// ----------------------------------------------------------------------------------
TextureAlphaMode GetXmlTextureAlphaMode(int alphaMode)
{
	switch(alphaMode)
	{
	case CXmlTexture::eAlphaMode_Disable:
		return ALPHA_MODE_DISABLE;
	case CXmlTexture::eAlphaMode_Blend:
		return ALPHA_MODE_BLEND;
	case CXmlTexture::eAlphaMode_Add:
		return ALPHA_MODE_ADD;
	}

	return ALPHA_MODE_BLEND;
}