#include "stdafx.h"
#include "UIRollText.h"

namespace DuiLib
{
	IMPLEMENT_DUICONTROL(CRollTextUI)

	CRollTextUI::CRollTextUI(void)
	{
		m_nScrollPos = 0;
		m_nText_W_H = 0;
		m_nStep = 5;
		m_bUseRoll = FALSE;
		m_nRollDirection = ROLLTEXT_LEFT;
	}

	CRollTextUI::~CRollTextUI(void)
	{
		m_pManager->KillTimer(this, ROLLTEXT_ROLL_END);
		m_pManager->KillTimer(this, ROLLTEXT_TIMERID);
	}

	LPCTSTR CRollTextUI::GetClass() const
	{
		return _T("RollTextUI");
	}

	LPVOID CRollTextUI::GetInterface(LPCTSTR pstrName)
	{
		if( _tcsicmp(pstrName, _T("RollText")) == 0 ) return static_cast<CRollTextUI*>(this);
		return CLabelUI::GetInterface(pstrName);
	}

	void CRollTextUI::BeginRoll(int nDirect, LONG lTimeSpan, LONG lMaxTimeLimited)
	{
		m_nRollDirection = nDirect;
		if (m_bUseRoll)
		{
			EndRoll();
		}
		m_nText_W_H = 0;
	
		m_pManager->KillTimer(this, ROLLTEXT_TIMERID);
		m_pManager->SetTimer(this, ROLLTEXT_TIMERID, lTimeSpan);
	
		m_pManager->KillTimer(this, ROLLTEXT_ROLL_END);
		m_pManager->SetTimer(this, ROLLTEXT_ROLL_END, lMaxTimeLimited*1000);

		m_bUseRoll = TRUE;
	}

	void CRollTextUI::EndRoll()
	{
		if (!m_bUseRoll) return;

		m_pManager->KillTimer(this, ROLLTEXT_ROLL_END);
		m_pManager->KillTimer(this, ROLLTEXT_TIMERID);
		
		m_bUseRoll = FALSE;
	}

	void CRollTextUI::SetPos(RECT rc)
	{
		CLabelUI::SetPos(rc);
		m_nText_W_H = 0;			//布局变化重新计算
	}

	void CRollTextUI::SetText( LPCTSTR pstrText )
	{
		CLabelUI::SetText(pstrText);
		m_nText_W_H = 0;			//文本变化重新计算
	}

	void CRollTextUI::DoEvent(TEventUI& event)
	{
		if (event.Type == UIEVENT_TIMER && event.wParam == ROLLTEXT_ROLL_END)
		{
			m_pManager->KillTimer(this, ROLLTEXT_ROLL_END);
			m_pManager->SendNotify(this, DUI_MSGTYPE_TEXTROLLEND);
		}
		else if( event.Type == UIEVENT_TIMER && event.wParam == ROLLTEXT_TIMERID ) 
		{
			Invalidate();
			return;
		}
		CLabelUI::DoEvent(event);
	}

	void CRollTextUI::PaintText(HDC hDC)
	{
		if( m_dwTextColor == 0 ) m_dwTextColor = m_pManager->GetDefaultFontColor();
		if( m_dwDisabledTextColor == 0 ) m_dwDisabledTextColor = m_pManager->GetDefaultDisabledColor();
		DWORD dwTextColor = IsEnabled() ? m_dwTextColor : m_dwDisabledTextColor;
		CDuiString sText = GetText();
		if( sText.IsEmpty() ) return;

		RECT rcTextPadding = GetTextPadding();
		CDuiRect  rcClient;
		rcClient = m_rcItem;
		rcClient.left += rcTextPadding.left;
		rcClient.right -= rcTextPadding.right;
		rcClient.top += rcTextPadding.top;
		rcClient.bottom -= rcTextPadding.bottom;

		if(m_nText_W_H > 0)
		{
			int nScrollRange = 0;

			if (m_nRollDirection == ROLLTEXT_LEFT || m_nRollDirection == ROLLTEXT_RIGHT) {	//左面移动
				nScrollRange = m_nText_W_H + rcClient.GetWidth();

				rcClient.Offset((m_nRollDirection == ROLLTEXT_LEFT?rcClient.GetWidth():-rcClient.GetWidth()), 0);
				rcClient.Offset((m_nRollDirection == ROLLTEXT_LEFT?-m_nScrollPos:m_nScrollPos), 0);
				rcClient.right += (m_nText_W_H - rcClient.GetWidth());
			}
			else {																		//上下移动
				nScrollRange = m_nText_W_H + rcClient.GetHeight();
				rcClient.Offset(0, (m_nRollDirection == ROLLTEXT_UP?rcClient.GetHeight():-rcClient.GetHeight()));
				rcClient.Offset(0, (m_nRollDirection == ROLLTEXT_UP?-m_nScrollPos:m_nScrollPos));
				rcClient.bottom += (m_nText_W_H - rcClient.GetHeight());
			}

			m_nScrollPos += m_nStep;
			if (m_nScrollPos > nScrollRange) {
				m_nScrollPos = 0;
			}
		}

		RECT rc = rcClient;
		UINT uTextStyle = DT_WORDBREAK | DT_EDITCONTROL;
		if(m_nText_W_H == 0) {
			uTextStyle |= DT_CALCRECT;				//第一次计算文本宽度或高度
			if (m_nRollDirection == ROLLTEXT_LEFT || m_nRollDirection == ROLLTEXT_RIGHT) {	//左面移动
				rc.right += 10000;
			}
			else {																		//上下移动
				rc.bottom += 10000;
			}
		}

		if( m_bShowHtml ) {
			int nLinks = 0;
			CRenderEngine::DrawHtmlText(hDC, m_pManager, rc, sText, dwTextColor, NULL, NULL, nLinks, m_iFont, uTextStyle);
		}
		else {
			CRenderEngine::DrawText(hDC, m_pManager, rc, sText, dwTextColor, m_iFont, uTextStyle);
		}

		if(m_nText_W_H == 0) {
			m_nText_W_H = (m_nRollDirection == ROLLTEXT_LEFT || m_nRollDirection == ROLLTEXT_RIGHT)?(rc.right - rc.left):(rc.bottom - rc.top);		//计算文本宽度或高度
		}
	}
}