// Copyright 2014 PDFium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
 
// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com

#include "../../include/pdfwindow/PDFWindow.h"
#include "../../include/pdfwindow/PWL_Wnd.h"
#include "../../include/pdfwindow/PWL_Label.h"
#include "../../include/pdfwindow/PWL_Utils.h"

/* ---------------------------- CPWL_Label ------------------------------ */

CPWL_Label::CPWL_Label() : m_pEdit(NULL)
{
	m_pEdit = IFX_Edit::NewEdit();

	ASSERT(m_pEdit != NULL);
}

CPWL_Label::~CPWL_Label()
{
	IFX_Edit::DelEdit(m_pEdit);
}

CFX_ByteString CPWL_Label::GetClassName() const
{
	return "CPWL_Label";
}

void CPWL_Label::OnCreated()
{
	SetParamByFlag();
	SetFontSize(this->GetCreationParam().fFontSize);

	m_pEdit->SetFontMap(this->GetFontMap());
	m_pEdit->Initialize();

	if (HasFlag(PES_TEXTOVERFLOW))
	{
		SetClipRect(CPDF_Rect(0.0f,0.0f,0.0f,0.0f));
		m_pEdit->SetTextOverflow(TRUE);
	}
}

void CPWL_Label::SetText(FX_LPCWSTR csText)
{
	m_pEdit->SetText(csText);
}

void CPWL_Label::RePosChildWnd()
{
	m_pEdit->SetPlateRect(GetClientRect());
}

void CPWL_Label::SetFontSize(FX_FLOAT fFontSize)
{
	m_pEdit->SetFontSize(fFontSize);
}

FX_FLOAT CPWL_Label::GetFontSize() const
{
	return m_pEdit->GetFontSize();
}

void CPWL_Label::SetParamByFlag()
{	
	if (HasFlag(PES_LEFT))
	{
		m_pEdit->SetAlignmentH(0);
	}
	else if (HasFlag(PES_MIDDLE))
	{
		m_pEdit->SetAlignmentH(1);
	}
	else if (HasFlag(PES_RIGHT))
	{
		m_pEdit->SetAlignmentH(2);
	}
	else
	{
		m_pEdit->SetAlignmentH(0);
	}

	if (HasFlag(PES_TOP))
	{
		m_pEdit->SetAlignmentV(0);
	}
	else if (HasFlag(PES_CENTER))
	{
		m_pEdit->SetAlignmentV(1);
	}
	else if (HasFlag(PES_BOTTOM))
	{
		m_pEdit->SetAlignmentV(2);
	}
	else
	{
		m_pEdit->SetAlignmentV(0);
	}

	if (HasFlag(PES_PASSWORD))
	{
		m_pEdit->SetPasswordChar('*');
	}

	m_pEdit->SetMultiLine(HasFlag(PES_MULTILINE));
	m_pEdit->SetAutoReturn(HasFlag(PES_AUTORETURN));
	m_pEdit->SetAutoFontSize(HasFlag(PWS_AUTOFONTSIZE));
	m_pEdit->SetAutoScroll(HasFlag(PES_AUTOSCROLL));
}

void CPWL_Label::DrawThisAppearance(CFX_RenderDevice* pDevice, CPDF_Matrix* pUser2Device)
{
	CPWL_Wnd::DrawThisAppearance(pDevice,pUser2Device);

	GetClientRect();

	CPDF_Rect rcClip;
	CPVT_WordRange wrRange = m_pEdit->GetVisibleWordRange();
	CPVT_WordRange* pRange = NULL;

	if (!HasFlag(PES_TEXTOVERFLOW))
	{
		rcClip = GetClientRect();
		pRange = &wrRange;
	}
IFX_SystemHandler* pSysHandler = GetSystemHandler();
	IFX_Edit::DrawEdit(pDevice, pUser2Device, m_pEdit,
		CPWL_Utils::PWLColorToFXColor(GetTextColor(), this->GetTransparency()),
		CPWL_Utils::PWLColorToFXColor(GetTextStrokeColor(), this->GetTransparency()),
		rcClip, CPDF_Point(0.0f,0.0f), pRange,pSysHandler, NULL);
}

void CPWL_Label::SetHorzScale(FX_INT32 nHorzScale)
{
	m_pEdit->SetHorzScale(nHorzScale);
}

void CPWL_Label::SetCharSpace(FX_FLOAT fCharSpace)
{
	m_pEdit->SetCharSpace(fCharSpace);
}

CPDF_Rect CPWL_Label::GetContentRect() const
{
	return m_pEdit->GetContentRect();
}

void CPWL_Label::GetThisAppearanceStream(CFX_ByteTextBuf & sAppStream)
{
	CPWL_Wnd::GetThisAppearanceStream(sAppStream);

	sAppStream << GetTextAppearanceStream(CPDF_Point(0.0f, 0.0f));
}

CFX_ByteString CPWL_Label::GetTextAppearanceStream(const CPDF_Point & ptOffset) const
{
	CFX_ByteTextBuf sRet;
	CFX_ByteString sEdit = CPWL_Utils::GetEditAppStream(m_pEdit,ptOffset);
	
	if (sEdit.GetLength() > 0)
	{
		sRet << "BT\n" << CPWL_Utils::GetColorAppStream(GetTextColor()) << sEdit << "ET\n";
	}

	return sRet.GetByteString();
}

CFX_WideString CPWL_Label::GetText() const
{
	return m_pEdit->GetText();
}

void CPWL_Label::SetLimitChar(FX_INT32 nLimitChar)
{
	m_pEdit->SetLimitChar(nLimitChar);
}

FX_INT32 CPWL_Label::GetTotalWords()
{
	if (m_pEdit)
		return m_pEdit->GetTotalWords();

	return 0;
}

