// 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 "fpdfsdk/include/pdfwindow/PDFWindow.h"
#include "fpdfsdk/include/pdfwindow/PWL_Label.h"
#include "fpdfsdk/include/pdfwindow/PWL_Utils.h"
#include "fpdfsdk/include/pdfwindow/PWL_Wnd.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;
}
