// 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/fxedit/include/fx_edit.h"
#include "fpdfsdk/pdfwindow/PWL_Label.h"
#include "fpdfsdk/pdfwindow/PWL_Utils.h"
#include "fpdfsdk/pdfwindow/PWL_Wnd.h"

CPWL_Label::CPWL_Label() : m_pEdit(NULL) {
  m_pEdit = IFX_Edit::NewEdit();
  ASSERT(m_pEdit);
}

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(CFX_FloatRect(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,
                                    CFX_Matrix* pUser2Device) {
  CPWL_Wnd::DrawThisAppearance(pDevice, pUser2Device);

  GetClientRect();

  CFX_FloatRect rcClip;
  CPVT_WordRange wrRange = m_pEdit->GetVisibleWordRange();
  CPVT_WordRange* pRange = NULL;

  if (!HasFlag(PES_TEXTOVERFLOW)) {
    rcClip = GetClientRect();
    pRange = &wrRange;
  }
  CFX_SystemHandler* pSysHandler = GetSystemHandler();
  IFX_Edit::DrawEdit(
      pDevice, pUser2Device, m_pEdit,
      CPWL_Utils::PWLColorToFXColor(GetTextColor(), GetTransparency()),
      CPWL_Utils::PWLColorToFXColor(GetTextStrokeColor(), GetTransparency()),
      rcClip, CFX_FloatPoint(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);
}

CFX_FloatRect CPWL_Label::GetContentRect() const {
  return m_pEdit->GetContentRect();
}

void CPWL_Label::GetThisAppearanceStream(CFX_ByteTextBuf& sAppStream) {
  CPWL_Wnd::GetThisAppearanceStream(sAppStream);

  sAppStream << GetTextAppearanceStream(CFX_FloatPoint(0.0f, 0.0f)).AsStringC();
}

CFX_ByteString CPWL_Label::GetTextAppearanceStream(
    const CFX_FloatPoint& 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()).AsStringC()
         << sEdit.AsStringC() << "ET\n";
  }

  return sRet.AsStringC();
}

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