#include <windows.h>
#include "uimessageframe.h"

// ----------------------------------------------------------------------------------
CUiMessageFrame::CUiMessageFrame(const char* name, CUiLayout* pParent, CUi* pUi)
	: CUiFrame(name, pParent, pUi)
{
	m_uiType			= eUiType_MessageFrame;

	m_text				= NULL;
	m_fontString		= NULL;	
	m_maxLines			= 0;
	m_sizeLines			= 0;
	m_lastLine			= 0;
	m_fadeDuration		= 10.0f;
	m_displayDuration	= 120.0f;
}

// ----------------------------------------------------------------------------------
CUiMessageFrame::~CUiMessageFrame()
{
	UI_SAFE_DELETE(m_fontString);
	ReleaseText();
}

// ----------------------------------------------------------------------------------
void CUiMessageFrame::SetFontString(CUiFontString* fontString)
{
	UI_SAFE_DELETE(m_fontString);
	m_fontString = fontString;
	ClearTextItemFont();
	ResetTextItemTime();
}

// ----------------------------------------------------------------------------------
void CUiMessageFrame::ClearText()
{
	for ( int i = 0; i < m_sizeLines; i++ )
	{
		UI_SAFE_DELETE(m_text[i].font);
		UI_SAFE_DELETE_ARRAY(m_text[i].str);
	}
	m_sizeLines = 0;
	m_lastLine = 0;
}

// ----------------------------------------------------------------------------------
void CUiMessageFrame::ReleaseText()
{
	ClearText();
	UI_SAFE_DELETE_ARRAY(m_text);
	m_maxLines = 0;
}

// ----------------------------------------------------------------------------------
bool CUiMessageFrame::AddMessage(const WCHAR* text, DWORD color)
{
	if (text && m_fontString)
	{
		// pop front
		if ( m_sizeLines >= m_maxLines )
			PopItem();
		
		// push back
		PushItem(text, color);		
		return true;
	}
	return false;	
}

// ----------------------------------------------------------------------------------
void CUiMessageFrame::SetMaxLines(int maxLines)
{
	if (m_maxLines != maxLines)
	{
		ReleaseText();

		m_maxLines = maxLines;
		if (m_maxLines > 0)
		{
			m_text = new TextItem[m_maxLines];
			memset(m_text, 0, sizeof(TextItem)*m_maxLines);
		}
	}
}

// ----------------------------------------------------------------------------------
void CUiMessageFrame::SetLastLine(int line)
{	
	if ( line > 0 && line <= m_sizeLines && m_lastLine != line )
	{
		m_lastLine = line;
	}
}

// ----------------------------------------------------------------------------------
void CUiMessageFrame::PopItem()
{
	if (m_sizeLines > 0)
	{
		m_sizeLines--;
		UI_SAFE_DELETE(m_text[0].font);
		UI_SAFE_DELETE_ARRAY(m_text[0].str);
		memmove(m_text, m_text+1, sizeof(TextItem)*m_sizeLines);
		memset(m_text+m_sizeLines, 0, sizeof(TextItem) );
	}
}

// ----------------------------------------------------------------------------------
void CUiMessageFrame::PushItem(const WCHAR* text, DWORD color)
{
	if ( m_sizeLines < m_maxLines )
	{
		TextItem* item	= &m_text[m_sizeLines++];
		item->font		= NULL;
		item->color		= color;
		item->time		= 0.0f;
		item->alpha		= 1.0f;
		item->str		= new WCHAR[wcslen(text) + 1];
		wcscpy(item->str, text);
		
		if ( m_sizeLines == m_lastLine+1 )
			SetLastLine(m_sizeLines);
	}
}

// ----------------------------------------------------------------------------------
void CUiMessageFrame::ClearTextItemFont()
{
	for ( int i = 0; i < m_sizeLines; i++ )
	{
		UI_SAFE_DELETE(m_text[i].font);
	}
}

// ----------------------------------------------------------------------------------
void CUiMessageFrame::ResetTextItemTime()
{
	for ( int i = 0; i < m_sizeLines; i++ )
	{
		m_text[i].time = 0.0f;
		m_text[i].alpha = 1.0f;
	}
}

// ----------------------------------------------------------------------------------
void CUiMessageFrame::OnResize()
{
	ResetTextItemTime();
	ClearTextItemFont();
	CUiFrame::OnResize();
}

// ----------------------------------------------------------------------------------
void CUiMessageFrame::OnUpdate(float elapsedTime)
{
	if (m_displayDuration > 0.0f)
	{
		for ( int i = 0; i < m_sizeLines; i++ )
		{
			m_text[i].time += elapsedTime;
			if (m_text[i].time > m_displayDuration)
				m_text[i].alpha -= elapsedTime / m_fadeDuration;

			if (m_text[i].alpha < 0.0f)
				m_text[i].alpha = 0.0f;
		}
	}

	CUiFrame::OnUpdate(elapsedTime);
}

// ----------------------------------------------------------------------------------
void CUiMessageFrame::OnPaint(float alpha)
{
	// CUiFrame::OnPaint();

	if (m_fontString && alpha > 0.0f)
	{
		CUiSize size(m_size.m_x - m_textInset.m_right - m_textInset.m_left, m_size.m_y - m_textInset.m_bottom - m_textInset.m_top);
		CUiPoint screenPt = m_position;
		float y = screenPt.m_y + size.m_y;
		
		for ( int i = m_lastLine; i > 0; i-- )
		{
			TextItem* item = &m_text[i-1];
			if (item->alpha <= 0.0f)
				break;

			if (item->font == NULL)
			{
				CUiColor color(item->color);
				item->font = new CUiFontString(NULL, NULL, NULL);
				item->font->SetFontType(m_fontString->GetFontType());
				item->font->SetFontShadow(m_fontString->GetFontShadow());
				item->font->SetJustifyHType(m_fontString->GetJustifyHType());
				item->font->SetJustifyVType(m_fontString->GetJustifyVType());
				item->font->SetSpacing(m_fontString->GetSpacing());
				item->font->SetAnchorSize(CUiSize(size.m_x, 0.0f));
				item->font->SetColor(color.m_r, color.m_g, color.m_b);
				item->font->SetText(item->str);
			}
			
			CUiSize fontSize = item->font->GetSize();
			if (y - fontSize.m_y < screenPt.m_y)
				break;

			item->font->Render(alpha * item->alpha, screenPt.m_x + m_textInset.m_left, y - fontSize.m_y);
			y -= fontSize.m_y;
		}
	}
}