// 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(GetCreationParam().fFontSize);

  m_pEdit->SetFontMap(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(const FX_WCHAR* 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(), GetTransparency()),
      CPWL_Utils::PWLColorToFXColor(GetTextStrokeColor(), GetTransparency()),
      rcClip, CPDF_Point(0.0f, 0.0f), pRange, pSysHandler, NULL);
}

void CPWL_Label::SetHorzScale(int32_t 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(int32_t nLimitChar) {
  m_pEdit->SetLimitChar(nLimitChar);
}

int32_t CPWL_Label::GetTotalWords() {
  if (m_pEdit)
    return m_pEdit->GetTotalWords();

  return 0;
}
