#include "ListBox.h"
#include "MenuManager.h"

ListBox::ListBox(MenuManager* const pManager, const DWORD id) : GUIElement(pManager, id)
{
	m_pBox = new Panel(GetManager(), 0);
	AddChild(m_pBox);

	m_pSel = new Image(GetManager(), 0);
	AddChild(m_pSel);

	m_SelectionIndex = -1;
	m_ItemHeight = 20;

	m_pFont = NULL;
	m_TextColor = D3DXCOLOR(0, 0, 0, 1);
	m_TextSelColor = D3DXCOLOR(1, 1, 1, 1);
	m_TextAlign = AL_LEFTCENTER;
	m_ClientBorder = 0;
	m_bHightlightMouseItem = false;

	m_pSel->SetVisible(false);
}

ListBox::~ListBox(void)
{
}

void ListBox::OnUpdate(void)
{
	if (IsEnable())
	{
		if(m_bHightlightMouseItem)
		{
			int i = 0;
			bool hl = false;
			FOREACH(item, m_lItems, Label)
			{
				if (item->GetInfo()->IsMouseOver())
				{
					m_pSel->SetVisible(true);
					m_pSel->SetPosition(m_ClientBorder, m_ClientBorder + i * m_ItemHeight);
					item->GetInfo()->SetColor(m_TextSelColor);
					hl = true;
				}
				else
				{
					item->GetInfo()->SetColor(m_TextColor);
				}
				i++;
			}
			if (!hl)
				m_pSel->SetVisible(false);
		}
	}
}

void ListBox::SetSize(const float xl, const float yl)
{
	GUIElement::SetSize(xl, yl);

	m_pBox->SetSize(xl, yl);
	m_pSel->SetSize(xl, m_ItemHeight);
}

void ListBox::SetItemHeight(const float height)
{
	m_ItemHeight = height;

	float y = m_ClientBorder;
	FOREACH(item, m_lItems, Label)
	{
		item->GetInfo()->SetPosition(m_ClientBorder, y);
		item->GetInfo()->SetSize(item->GetInfo()->GetXl() - m_ClientBorder * 2, m_ItemHeight-1);
		y += m_ItemHeight;
	}

	m_pSel->SetSize(m_pSel->GetXl(), m_ItemHeight);
}

void ListBox::SetSelectedIndex(const int index)
{
	if (m_SelectionIndex != index)
	{
		if (m_SelectionIndex >= 0 && m_SelectionIndex < m_lItems.GetElementCount())
			m_lItems[m_SelectionIndex]->GetInfo()->SetColor(m_TextColor);

		m_SelectionIndex = index;

		if (m_SelectionIndex >= 0 && m_SelectionIndex < m_lItems.GetElementCount())
		{
			m_lItems[m_SelectionIndex]->GetInfo()->SetColor(m_TextSelColor);
			m_pSel->SetVisible(true);
		}
		else
		{
			m_pSel->SetVisible(false);
		}

		m_pSel->SetPosition(m_ClientBorder, m_ClientBorder + m_SelectionIndex * m_ItemHeight);

		HandleEvent(GE_VALUECHANGED, 0);
	}
}

void ListBox::AddItem(const XString& item)
{
	Label* l = new Label(GetManager(), 0);

	l->SetText(item);
	l->SetSize(GetXl() - m_ClientBorder * 2, m_ItemHeight-1);
	l->SetTextAlign(m_TextAlign);
	l->SetColor(m_TextColor);
	l->SetPosition(m_ClientBorder, m_ClientBorder + m_lItems.GetElementCount() * m_ItemHeight);
	//if (m_pFont)
	//	m_pFont->IncRefCount();
	l->SetFont(m_pFont);
	l->SetEventHandler(GE_BUTTONCLICK, OnItemClick);

	m_lItems.AddTail(l, 0);
	AddChild(l);
}

void ListBox::DeleteItem(const int index)
{
	ListElement<Label>* l = m_lItems[index];
	if (l)
	{
		GetManager()->DeleteElement(l->GetInfo());
		l->Unlink();
		delete l;
	}
}

void ListBox::SetFont(Font* const pFont)
{
	m_pFont = pFont;
	FOREACH(item, m_lItems, Label)
	{
		//if (m_pFont)
		//	m_pFont->IncRefCount();
		item->GetInfo()->SetFont(m_pFont);
	}
}

void ListBox::SetClientBorder(const float border)
{
	m_ClientBorder = border;
	m_pSel->SetSize(GetXl() - m_ClientBorder * 2, m_ItemHeight);
	m_pSel->SetPosition(m_ClientBorder, m_ClientBorder + m_SelectionIndex * m_ItemHeight);
	
	SetItemHeight(m_ItemHeight);
}

void ListBox::SetTextColor(const D3DXCOLOR color, const D3DXCOLOR selcolor)
{
	m_TextColor = color;
	m_TextSelColor = selcolor;
	int i = 0;
	FOREACH(item, m_lItems, Label)
	{
		if (i == m_SelectionIndex)
			item->GetInfo()->SetColor(m_TextSelColor);
		else
			item->GetInfo()->SetColor(m_TextColor);
					
		i++;
	}
}

void ListBox::SetTextAlign(const ALIGNMENT align)
{
	m_TextAlign = align;
	FOREACH(item, m_lItems, Label)
	{
		item->GetInfo()->SetTextAlign(m_TextAlign);
	}
}


void ListBox::SetTexture(DXTexture* const box, DXTexture* const sel, const bool alphablend, const int fixedborder)
{ 
	m_pBox->SetTexture(box); 
	m_pBox->SetFixedBorder(fixedborder);
	m_pBox->SetAlphaBlend(alphablend); 

	m_pSel->SetTexture(sel); 
	m_pSel->SetAlphaBlend(alphablend);
}

void ListBox::OnItemClick(GUIElement* const sender, const GUIEVENT evnt, void* pData)
{
	if (MBTN_LEFT == static_cast<MOUSEBUTTON>((unsigned)pData))
	{
		ListBox* lb = dynamic_cast<ListBox*>(sender->GetParent());
		Label* item = dynamic_cast<Label*>(sender);

		if (lb)
		{
			lb->SetSelectedIndex(lb->m_lItems.GetIndexOf(item));
		}
	}
}