// 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;
}

