// 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/formfiller/FFL_FormFiller.h"
#include "fpdfsdk/include/fsdk_actionhandler.h"
#include "fpdfsdk/include/fsdk_baseannot.h"
#include "fpdfsdk/include/fsdk_baseform.h"
#include "fpdfsdk/include/fsdk_define.h"
#include "fpdfsdk/include/fsdk_mgr.h"
#include "fpdfsdk/include/javascript/IJavaScript.h"
#include "third_party/base/nonstd_unique_ptr.h"

#define IsFloatZero(f) ((f) < 0.01 && (f) > -0.01)
#define IsFloatBigger(fa, fb) ((fa) > (fb) && !IsFloatZero((fa) - (fb)))
#define IsFloatSmaller(fa, fb) ((fa) < (fb) && !IsFloatZero((fa) - (fb)))
#define IsFloatEqual(fa, fb) IsFloatZero((fa) - (fb))

CPDFSDK_Widget::CPDFSDK_Widget(CPDF_Annot* pAnnot,
                               CPDFSDK_PageView* pPageView,
                               CPDFSDK_InterForm* pInterForm)
    : CPDFSDK_BAAnnot(pAnnot, pPageView),
      m_pInterForm(pInterForm),
      m_nAppAge(0),
      m_nValueAge(0) {
  ASSERT(m_pInterForm != NULL);
}

CPDFSDK_Widget::~CPDFSDK_Widget() {}

FX_BOOL CPDFSDK_Widget::IsWidgetAppearanceValid(
    CPDF_Annot::AppearanceMode mode) {
  CPDF_Dictionary* pAP = m_pAnnot->GetAnnotDict()->GetDict("AP");
  if (!pAP)
    return FALSE;

  // Choose the right sub-ap
  const FX_CHAR* ap_entry = "N";
  if (mode == CPDF_Annot::Down)
    ap_entry = "D";
  else if (mode == CPDF_Annot::Rollover)
    ap_entry = "R";
  if (!pAP->KeyExist(ap_entry))
    ap_entry = "N";

  // Get the AP stream or subdirectory
  CPDF_Object* psub = pAP->GetElementValue(ap_entry);
  if (!psub)
    return FALSE;

  int nFieldType = GetFieldType();
  switch (nFieldType) {
    case FIELDTYPE_PUSHBUTTON:
    case FIELDTYPE_COMBOBOX:
    case FIELDTYPE_LISTBOX:
    case FIELDTYPE_TEXTFIELD:
    case FIELDTYPE_SIGNATURE:
      return psub->IsStream();
    case FIELDTYPE_CHECKBOX:
    case FIELDTYPE_RADIOBUTTON:
      if (CPDF_Dictionary* pSubDict = psub->AsDictionary()) {
        return pSubDict->GetStream(GetAppState()) != NULL;
      }
      return FALSE;
  }
  return TRUE;
}

int CPDFSDK_Widget::GetFieldType() const {
  CPDF_FormField* pField = GetFormField();
  ASSERT(pField != NULL);

  return pField->GetFieldType();
}

FX_BOOL CPDFSDK_Widget::IsAppearanceValid() {
  return CPDFSDK_BAAnnot::IsAppearanceValid();
}

int CPDFSDK_Widget::GetFieldFlags() const {
  CPDF_InterForm* pPDFInterForm = m_pInterForm->GetInterForm();
  ASSERT(pPDFInterForm != NULL);

  CPDF_FormControl* pFormControl =
      pPDFInterForm->GetControlByDict(m_pAnnot->GetAnnotDict());
  CPDF_FormField* pFormField = pFormControl->GetField();
  return pFormField->GetFieldFlags();
}

CFX_ByteString CPDFSDK_Widget::GetSubType() const {
  int nType = GetFieldType();

  if (nType == FIELDTYPE_SIGNATURE)
    return BFFT_SIGNATURE;
  return CPDFSDK_Annot::GetSubType();
}

CPDF_FormField* CPDFSDK_Widget::GetFormField() const {
  return GetFormControl()->GetField();
}

CPDF_FormControl* CPDFSDK_Widget::GetFormControl() const {
  CPDF_InterForm* pPDFInterForm = m_pInterForm->GetInterForm();
  return pPDFInterForm->GetControlByDict(GetAnnotDict());
}

CPDF_FormControl* CPDFSDK_Widget::GetFormControl(
    CPDF_InterForm* pInterForm,
    const CPDF_Dictionary* pAnnotDict) {
  ASSERT(pAnnotDict != NULL);
  return pInterForm->GetControlByDict(pAnnotDict);
}

int CPDFSDK_Widget::GetRotate() const {
  CPDF_FormControl* pCtrl = GetFormControl();
  return pCtrl->GetRotation() % 360;
}

FX_BOOL CPDFSDK_Widget::GetFillColor(FX_COLORREF& color) const {
  CPDF_FormControl* pFormCtrl = GetFormControl();
  ASSERT(pFormCtrl != NULL);

  int iColorType = 0;
  color = FX_ARGBTOCOLORREF(pFormCtrl->GetBackgroundColor(iColorType));

  return iColorType != COLORTYPE_TRANSPARENT;
}

FX_BOOL CPDFSDK_Widget::GetBorderColor(FX_COLORREF& color) const {
  CPDF_FormControl* pFormCtrl = GetFormControl();
  ASSERT(pFormCtrl != NULL);

  int iColorType = 0;
  color = FX_ARGBTOCOLORREF(pFormCtrl->GetBorderColor(iColorType));

  return iColorType != COLORTYPE_TRANSPARENT;
}

FX_BOOL CPDFSDK_Widget::GetTextColor(FX_COLORREF& color) const {
  CPDF_FormControl* pFormCtrl = GetFormControl();
  ASSERT(pFormCtrl != NULL);

  CPDF_DefaultAppearance da = pFormCtrl->GetDefaultAppearance();
  if (da.HasColor()) {
    FX_ARGB argb;
    int iColorType = COLORTYPE_TRANSPARENT;
    da.GetColor(argb, iColorType);
    color = FX_ARGBTOCOLORREF(argb);

    return iColorType != COLORTYPE_TRANSPARENT;
  }

  return FALSE;
}

FX_FLOAT CPDFSDK_Widget::GetFontSize() const {
  CPDF_FormControl* pFormCtrl = GetFormControl();
  ASSERT(pFormCtrl != NULL);

  CPDF_DefaultAppearance pDa = pFormCtrl->GetDefaultAppearance();
  CFX_ByteString csFont = "";
  FX_FLOAT fFontSize = 0.0f;
  pDa.GetFont(csFont, fFontSize);

  return fFontSize;
}

int CPDFSDK_Widget::GetSelectedIndex(int nIndex) const {
  CPDF_FormField* pFormField = GetFormField();
  return pFormField->GetSelectedIndex(nIndex);
}

CFX_WideString CPDFSDK_Widget::GetValue() const {
  CPDF_FormField* pFormField = GetFormField();
  return pFormField->GetValue();
}

CFX_WideString CPDFSDK_Widget::GetDefaultValue() const {
  CPDF_FormField* pFormField = GetFormField();
  ASSERT(pFormField != NULL);

  return pFormField->GetDefaultValue();
}

CFX_WideString CPDFSDK_Widget::GetOptionLabel(int nIndex) const {
  CPDF_FormField* pFormField = GetFormField();
  ASSERT(pFormField != NULL);

  return pFormField->GetOptionLabel(nIndex);
}

int CPDFSDK_Widget::CountOptions() const {
  CPDF_FormField* pFormField = GetFormField();
  ASSERT(pFormField != NULL);

  return pFormField->CountOptions();
}

FX_BOOL CPDFSDK_Widget::IsOptionSelected(int nIndex) const {
  CPDF_FormField* pFormField = GetFormField();
  return pFormField->IsItemSelected(nIndex);
}

int CPDFSDK_Widget::GetTopVisibleIndex() const {
  CPDF_FormField* pFormField = GetFormField();
  return pFormField->GetTopVisibleIndex();
}

FX_BOOL CPDFSDK_Widget::IsChecked() const {
  CPDF_FormControl* pFormCtrl = GetFormControl();
  return pFormCtrl->IsChecked();
}

int CPDFSDK_Widget::GetAlignment() const {
  CPDF_FormControl* pFormCtrl = GetFormControl();
  ASSERT(pFormCtrl != NULL);

  return pFormCtrl->GetControlAlignment();
}

int CPDFSDK_Widget::GetMaxLen() const {
  CPDF_FormField* pFormField = GetFormField();
  ASSERT(pFormField != NULL);

  return pFormField->GetMaxLen();
}

void CPDFSDK_Widget::SetCheck(FX_BOOL bChecked, FX_BOOL bNotify) {
  CPDF_FormControl* pFormCtrl = GetFormControl();
  ASSERT(pFormCtrl != NULL);

  CPDF_FormField* pFormField = pFormCtrl->GetField();
  ASSERT(pFormField != NULL);

  pFormField->CheckControl(pFormField->GetControlIndex(pFormCtrl), bChecked,
                           bNotify);
}

void CPDFSDK_Widget::SetValue(const CFX_WideString& sValue, FX_BOOL bNotify) {
  CPDF_FormField* pFormField = GetFormField();
  ASSERT(pFormField != NULL);

  pFormField->SetValue(sValue, bNotify);
}

void CPDFSDK_Widget::SetDefaultValue(const CFX_WideString& sValue) {}
void CPDFSDK_Widget::SetOptionSelection(int index,
                                        FX_BOOL bSelected,
                                        FX_BOOL bNotify) {
  CPDF_FormField* pFormField = GetFormField();
  ASSERT(pFormField != NULL);

  pFormField->SetItemSelection(index, bSelected, bNotify);
}

void CPDFSDK_Widget::ClearSelection(FX_BOOL bNotify) {
  CPDF_FormField* pFormField = GetFormField();
  ASSERT(pFormField != NULL);

  pFormField->ClearSelection(bNotify);
}

void CPDFSDK_Widget::SetTopVisibleIndex(int index) {}

void CPDFSDK_Widget::SetAppModified() {
  m_bAppModified = TRUE;
}

void CPDFSDK_Widget::ClearAppModified() {
  m_bAppModified = FALSE;
}

FX_BOOL CPDFSDK_Widget::IsAppModified() const {
  return m_bAppModified;
}

void CPDFSDK_Widget::ResetAppearance(const FX_WCHAR* sValue,
                                     FX_BOOL bValueChanged) {
  SetAppModified();

  m_nAppAge++;
  if (m_nAppAge > 999999)
    m_nAppAge = 0;
  if (bValueChanged)
    m_nValueAge++;

  int nFieldType = GetFieldType();

  switch (nFieldType) {
    case FIELDTYPE_PUSHBUTTON:
      ResetAppearance_PushButton();
      break;
    case FIELDTYPE_CHECKBOX:
      ResetAppearance_CheckBox();
      break;
    case FIELDTYPE_RADIOBUTTON:
      ResetAppearance_RadioButton();
      break;
    case FIELDTYPE_COMBOBOX:
      ResetAppearance_ComboBox(sValue);
      break;
    case FIELDTYPE_LISTBOX:
      ResetAppearance_ListBox();
      break;
    case FIELDTYPE_TEXTFIELD:
      ResetAppearance_TextField(sValue);
      break;
  }

  ASSERT(m_pAnnot != NULL);
  m_pAnnot->ClearCachedAP();
}

CFX_WideString CPDFSDK_Widget::OnFormat(FX_BOOL& bFormated) {
  CPDF_FormField* pFormField = GetFormField();
  ASSERT(pFormField != NULL);
  return m_pInterForm->OnFormat(pFormField, bFormated);
}

void CPDFSDK_Widget::ResetFieldAppearance(FX_BOOL bValueChanged) {
  CPDF_FormField* pFormField = GetFormField();
  ASSERT(pFormField != NULL);

  ASSERT(m_pInterForm != NULL);

  m_pInterForm->ResetFieldAppearance(pFormField, NULL, bValueChanged);
}

void CPDFSDK_Widget::DrawAppearance(CFX_RenderDevice* pDevice,
                                    const CFX_Matrix* pUser2Device,
                                    CPDF_Annot::AppearanceMode mode,
                                    const CPDF_RenderOptions* pOptions) {
  int nFieldType = GetFieldType();

  if ((nFieldType == FIELDTYPE_CHECKBOX ||
       nFieldType == FIELDTYPE_RADIOBUTTON) &&
      mode == CPDF_Annot::Normal &&
      !IsWidgetAppearanceValid(CPDF_Annot::Normal)) {
    CFX_PathData pathData;

    CPDF_Rect rcAnnot = GetRect();

    pathData.AppendRect(rcAnnot.left, rcAnnot.bottom, rcAnnot.right,
                        rcAnnot.top);

    CFX_GraphStateData gsd;
    gsd.m_LineWidth = 0.0f;

    pDevice->DrawPath(&pathData, pUser2Device, &gsd, 0, 0xFFAAAAAA,
                      FXFILL_ALTERNATE);
  } else {
    CPDFSDK_BAAnnot::DrawAppearance(pDevice, pUser2Device, mode, pOptions);
  }
}

void CPDFSDK_Widget::UpdateField() {
  CPDF_FormField* pFormField = GetFormField();
  ASSERT(pFormField != NULL);

  ASSERT(m_pInterForm != NULL);
  m_pInterForm->UpdateField(pFormField);
}

void CPDFSDK_Widget::DrawShadow(CFX_RenderDevice* pDevice,
                                CPDFSDK_PageView* pPageView) {
  ASSERT(m_pInterForm != NULL);

  int nFieldType = GetFieldType();
  if (m_pInterForm->IsNeedHighLight(nFieldType)) {
    CPDF_Rect rc = GetRect();
    FX_COLORREF color = m_pInterForm->GetHighlightColor(nFieldType);
    uint8_t alpha = m_pInterForm->GetHighlightAlpha();

    CFX_FloatRect rcDevice;
    ASSERT(m_pInterForm->GetDocument());
    CPDFDoc_Environment* pEnv = m_pInterForm->GetDocument()->GetEnv();
    if (!pEnv)
      return;
    CFX_Matrix page2device;
    pPageView->GetCurrentMatrix(page2device);
    page2device.Transform(((FX_FLOAT)rc.left), ((FX_FLOAT)rc.bottom),
                          rcDevice.left, rcDevice.bottom);
    page2device.Transform(((FX_FLOAT)rc.right), ((FX_FLOAT)rc.top),
                          rcDevice.right, rcDevice.top);

    rcDevice.Normalize();

    FX_ARGB argb = ArgbEncode((int)alpha, color);
    FX_RECT rcDev((int)rcDevice.left, (int)rcDevice.top, (int)rcDevice.right,
                  (int)rcDevice.bottom);
    pDevice->FillRect(&rcDev, argb);
  }
}

void CPDFSDK_Widget::ResetAppearance_PushButton() {
  CPDF_FormControl* pControl = GetFormControl();
  ASSERT(pControl != NULL);

  CPDF_Rect rcWindow = GetRotatedRect();

  int32_t nLayout = 0;

  switch (pControl->GetTextPosition()) {
    case TEXTPOS_ICON:
      nLayout = PPBL_ICON;
      break;
    case TEXTPOS_BELOW:
      nLayout = PPBL_ICONTOPLABELBOTTOM;
      break;
    case TEXTPOS_ABOVE:
      nLayout = PPBL_LABELTOPICONBOTTOM;
      break;
    case TEXTPOS_RIGHT:
      nLayout = PPBL_ICONLEFTLABELRIGHT;
      break;
    case TEXTPOS_LEFT:
      nLayout = PPBL_LABELLEFTICONRIGHT;
      break;
    case TEXTPOS_OVERLAID:
      nLayout = PPBL_LABELOVERICON;
      break;
    default:
      nLayout = PPBL_LABEL;
      break;
  }

  CPWL_Color crBackground, crBorder;

  int iColorType;
  FX_FLOAT fc[4];

  pControl->GetOriginalBackgroundColor(iColorType, fc);
  if (iColorType > 0)
    crBackground = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);

  pControl->GetOriginalBorderColor(iColorType, fc);
  if (iColorType > 0)
    crBorder = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);

  FX_FLOAT fBorderWidth = (FX_FLOAT)GetBorderWidth();
  int32_t nBorderStyle = 0;
  CPWL_Dash dsBorder(3, 0, 0);
  CPWL_Color crLeftTop, crRightBottom;

  switch (GetBorderStyle()) {
    case BBS_DASH:
      nBorderStyle = PBS_DASH;
      dsBorder = CPWL_Dash(3, 3, 0);
      break;
    case BBS_BEVELED:
      nBorderStyle = PBS_BEVELED;
      fBorderWidth *= 2;
      crLeftTop = CPWL_Color(COLORTYPE_GRAY, 1);
      crRightBottom = CPWL_Utils::DevideColor(crBackground, 2);
      break;
    case BBS_INSET:
      nBorderStyle = PBS_INSET;
      fBorderWidth *= 2;
      crLeftTop = CPWL_Color(COLORTYPE_GRAY, 0.5);
      crRightBottom = CPWL_Color(COLORTYPE_GRAY, 0.75);
      break;
    case BBS_UNDERLINE:
      nBorderStyle = PBS_UNDERLINED;
      break;
    default:
      nBorderStyle = PBS_SOLID;
      break;
  }

  CPDF_Rect rcClient = CPWL_Utils::DeflateRect(rcWindow, fBorderWidth);

  CPWL_Color crText(COLORTYPE_GRAY, 0);

  FX_FLOAT fFontSize = 12.0f;
  CFX_ByteString csNameTag;

  CPDF_DefaultAppearance da = pControl->GetDefaultAppearance();
  if (da.HasColor()) {
    da.GetColor(iColorType, fc);
    crText = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
  }

  if (da.HasFont())
    da.GetFont(csNameTag, fFontSize);

  CFX_WideString csWCaption;
  CFX_WideString csNormalCaption, csRolloverCaption, csDownCaption;

  if (pControl->HasMKEntry("CA")) {
    csNormalCaption = pControl->GetNormalCaption();
  }
  if (pControl->HasMKEntry("RC")) {
    csRolloverCaption = pControl->GetRolloverCaption();
  }
  if (pControl->HasMKEntry("AC")) {
    csDownCaption = pControl->GetDownCaption();
  }

  CPDF_Stream* pNormalIcon = NULL;
  CPDF_Stream* pRolloverIcon = NULL;
  CPDF_Stream* pDownIcon = NULL;

  if (pControl->HasMKEntry("I")) {
    pNormalIcon = pControl->GetNormalIcon();
  }
  if (pControl->HasMKEntry("RI")) {
    pRolloverIcon = pControl->GetRolloverIcon();
  }
  if (pControl->HasMKEntry("IX")) {
    pDownIcon = pControl->GetDownIcon();
  }

  if (pNormalIcon) {
    if (CPDF_Dictionary* pImageDict = pNormalIcon->GetDict()) {
      if (pImageDict->GetString("Name").IsEmpty())
        pImageDict->SetAtString("Name", "ImgA");
    }
  }

  if (pRolloverIcon) {
    if (CPDF_Dictionary* pImageDict = pRolloverIcon->GetDict()) {
      if (pImageDict->GetString("Name").IsEmpty())
        pImageDict->SetAtString("Name", "ImgB");
    }
  }

  if (pDownIcon) {
    if (CPDF_Dictionary* pImageDict = pDownIcon->GetDict()) {
      if (pImageDict->GetString("Name").IsEmpty())
        pImageDict->SetAtString("Name", "ImgC");
    }
  }

  CPDF_IconFit iconFit = pControl->GetIconFit();

  CPDFSDK_Document* pDoc = m_pInterForm->GetDocument();
  ASSERT(pDoc != NULL);
  CPDFDoc_Environment* pEnv = pDoc->GetEnv();

  CBA_FontMap FontMap(this, pEnv->GetSysHandler());
  FontMap.Initial();

  FontMap.SetAPType("N");

  CFX_ByteString csAP =
      CPWL_Utils::GetRectFillAppStream(rcWindow, crBackground) +
      CPWL_Utils::GetBorderAppStream(rcWindow, fBorderWidth, crBorder,
                                     crLeftTop, crRightBottom, nBorderStyle,
                                     dsBorder) +
      CPWL_Utils::GetPushButtonAppStream(
          iconFit.GetFittingBounds() ? rcWindow : rcClient, &FontMap,
          pNormalIcon, iconFit, csNormalCaption, crText, fFontSize, nLayout);

  WriteAppearance("N", GetRotatedRect(), GetMatrix(), csAP);
  if (pNormalIcon)
    AddImageToAppearance("N", pNormalIcon);

  CPDF_FormControl::HighlightingMode eHLM = pControl->GetHighlightingMode();
  if (eHLM == CPDF_FormControl::Push || eHLM == CPDF_FormControl::Toggle) {
    if (csRolloverCaption.IsEmpty() && !pRolloverIcon) {
      csRolloverCaption = csNormalCaption;
      pRolloverIcon = pNormalIcon;
    }

    FontMap.SetAPType("R");

    csAP = CPWL_Utils::GetRectFillAppStream(rcWindow, crBackground) +
           CPWL_Utils::GetBorderAppStream(rcWindow, fBorderWidth, crBorder,
                                          crLeftTop, crRightBottom,
                                          nBorderStyle, dsBorder) +
           CPWL_Utils::GetPushButtonAppStream(
               iconFit.GetFittingBounds() ? rcWindow : rcClient, &FontMap,
               pRolloverIcon, iconFit, csRolloverCaption, crText, fFontSize,
               nLayout);

    WriteAppearance("R", GetRotatedRect(), GetMatrix(), csAP);
    if (pRolloverIcon)
      AddImageToAppearance("R", pRolloverIcon);

    if (csDownCaption.IsEmpty() && !pDownIcon) {
      csDownCaption = csNormalCaption;
      pDownIcon = pNormalIcon;
    }

    switch (nBorderStyle) {
      case PBS_BEVELED: {
        CPWL_Color crTemp = crLeftTop;
        crLeftTop = crRightBottom;
        crRightBottom = crTemp;
      } break;
      case PBS_INSET:
        crLeftTop = CPWL_Color(COLORTYPE_GRAY, 0);
        crRightBottom = CPWL_Color(COLORTYPE_GRAY, 1);
        break;
    }

    FontMap.SetAPType("D");

    csAP = CPWL_Utils::GetRectFillAppStream(
               rcWindow, CPWL_Utils::SubstractColor(crBackground, 0.25f)) +
           CPWL_Utils::GetBorderAppStream(rcWindow, fBorderWidth, crBorder,
                                          crLeftTop, crRightBottom,
                                          nBorderStyle, dsBorder) +
           CPWL_Utils::GetPushButtonAppStream(
               iconFit.GetFittingBounds() ? rcWindow : rcClient, &FontMap,
               pDownIcon, iconFit, csDownCaption, crText, fFontSize, nLayout);

    WriteAppearance("D", GetRotatedRect(), GetMatrix(), csAP);
    if (pDownIcon)
      AddImageToAppearance("D", pDownIcon);
  } else {
    RemoveAppearance("D");
    RemoveAppearance("R");
  }
}

void CPDFSDK_Widget::ResetAppearance_CheckBox() {
  CPDF_FormControl* pControl = GetFormControl();
  ASSERT(pControl != NULL);

  CPWL_Color crBackground, crBorder, crText;

  int iColorType;
  FX_FLOAT fc[4];

  pControl->GetOriginalBackgroundColor(iColorType, fc);
  if (iColorType > 0)
    crBackground = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);

  pControl->GetOriginalBorderColor(iColorType, fc);
  if (iColorType > 0)
    crBorder = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);

  FX_FLOAT fBorderWidth = (FX_FLOAT)GetBorderWidth();
  int32_t nBorderStyle = 0;
  CPWL_Dash dsBorder(3, 0, 0);
  CPWL_Color crLeftTop, crRightBottom;

  switch (GetBorderStyle()) {
    case BBS_DASH:
      nBorderStyle = PBS_DASH;
      dsBorder = CPWL_Dash(3, 3, 0);
      break;
    case BBS_BEVELED:
      nBorderStyle = PBS_BEVELED;
      fBorderWidth *= 2;
      crLeftTop = CPWL_Color(COLORTYPE_GRAY, 1);
      crRightBottom = CPWL_Utils::DevideColor(crBackground, 2);
      break;
    case BBS_INSET:
      nBorderStyle = PBS_INSET;
      fBorderWidth *= 2;
      crLeftTop = CPWL_Color(COLORTYPE_GRAY, 0.5);
      crRightBottom = CPWL_Color(COLORTYPE_GRAY, 0.75);
      break;
    case BBS_UNDERLINE:
      nBorderStyle = PBS_UNDERLINED;
      break;
    default:
      nBorderStyle = PBS_SOLID;
      break;
  }

  CPDF_Rect rcWindow = GetRotatedRect();
  CPDF_Rect rcClient = CPWL_Utils::DeflateRect(rcWindow, fBorderWidth);

  CPDF_DefaultAppearance da = pControl->GetDefaultAppearance();
  if (da.HasColor()) {
    da.GetColor(iColorType, fc);
    crText = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
  }

  int32_t nStyle = 0;

  CFX_WideString csWCaption = pControl->GetNormalCaption();
  if (csWCaption.GetLength() > 0) {
    switch (csWCaption[0]) {
      case L'l':
        nStyle = PCS_CIRCLE;
        break;
      case L'8':
        nStyle = PCS_CROSS;
        break;
      case L'u':
        nStyle = PCS_DIAMOND;
        break;
      case L'n':
        nStyle = PCS_SQUARE;
        break;
      case L'H':
        nStyle = PCS_STAR;
        break;
      default:  // L'4'
        nStyle = PCS_CHECK;
        break;
    }
  } else {
    nStyle = PCS_CHECK;
  }

  CFX_ByteString csAP_N_ON =
      CPWL_Utils::GetRectFillAppStream(rcWindow, crBackground) +
      CPWL_Utils::GetBorderAppStream(rcWindow, fBorderWidth, crBorder,
                                     crLeftTop, crRightBottom, nBorderStyle,
                                     dsBorder);

  CFX_ByteString csAP_N_OFF = csAP_N_ON;

  switch (nBorderStyle) {
    case PBS_BEVELED: {
      CPWL_Color crTemp = crLeftTop;
      crLeftTop = crRightBottom;
      crRightBottom = crTemp;
    } break;
    case PBS_INSET:
      crLeftTop = CPWL_Color(COLORTYPE_GRAY, 0);
      crRightBottom = CPWL_Color(COLORTYPE_GRAY, 1);
      break;
  }

  CFX_ByteString csAP_D_ON =
      CPWL_Utils::GetRectFillAppStream(
          rcWindow, CPWL_Utils::SubstractColor(crBackground, 0.25f)) +
      CPWL_Utils::GetBorderAppStream(rcWindow, fBorderWidth, crBorder,
                                     crLeftTop, crRightBottom, nBorderStyle,
                                     dsBorder);

  CFX_ByteString csAP_D_OFF = csAP_D_ON;

  csAP_N_ON += CPWL_Utils::GetCheckBoxAppStream(rcClient, nStyle, crText);
  csAP_D_ON += CPWL_Utils::GetCheckBoxAppStream(rcClient, nStyle, crText);

  WriteAppearance("N", GetRotatedRect(), GetMatrix(), csAP_N_ON,
                  pControl->GetCheckedAPState());
  WriteAppearance("N", GetRotatedRect(), GetMatrix(), csAP_N_OFF, "Off");

  WriteAppearance("D", GetRotatedRect(), GetMatrix(), csAP_D_ON,
                  pControl->GetCheckedAPState());
  WriteAppearance("D", GetRotatedRect(), GetMatrix(), csAP_D_OFF, "Off");

  CFX_ByteString csAS = GetAppState();
  if (csAS.IsEmpty())
    SetAppState("Off");
}

void CPDFSDK_Widget::ResetAppearance_RadioButton() {
  CPDF_FormControl* pControl = GetFormControl();
  ASSERT(pControl != NULL);

  CPWL_Color crBackground, crBorder, crText;

  int iColorType;
  FX_FLOAT fc[4];

  pControl->GetOriginalBackgroundColor(iColorType, fc);
  if (iColorType > 0)
    crBackground = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);

  pControl->GetOriginalBorderColor(iColorType, fc);
  if (iColorType > 0)
    crBorder = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);

  FX_FLOAT fBorderWidth = (FX_FLOAT)GetBorderWidth();
  int32_t nBorderStyle = 0;
  CPWL_Dash dsBorder(3, 0, 0);
  CPWL_Color crLeftTop, crRightBottom;

  switch (GetBorderStyle()) {
    case BBS_DASH:
      nBorderStyle = PBS_DASH;
      dsBorder = CPWL_Dash(3, 3, 0);
      break;
    case BBS_BEVELED:
      nBorderStyle = PBS_BEVELED;
      fBorderWidth *= 2;
      crLeftTop = CPWL_Color(COLORTYPE_GRAY, 1);
      crRightBottom = CPWL_Utils::DevideColor(crBackground, 2);
      break;
    case BBS_INSET:
      nBorderStyle = PBS_INSET;
      fBorderWidth *= 2;
      crLeftTop = CPWL_Color(COLORTYPE_GRAY, 0.5);
      crRightBottom = CPWL_Color(COLORTYPE_GRAY, 0.75);
      break;
    case BBS_UNDERLINE:
      nBorderStyle = PBS_UNDERLINED;
      break;
    default:
      nBorderStyle = PBS_SOLID;
      break;
  }

  CPDF_Rect rcWindow = GetRotatedRect();
  CPDF_Rect rcClient = CPWL_Utils::DeflateRect(rcWindow, fBorderWidth);

  CPDF_DefaultAppearance da = pControl->GetDefaultAppearance();
  if (da.HasColor()) {
    da.GetColor(iColorType, fc);
    crText = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
  }

  int32_t nStyle = 0;

  CFX_WideString csWCaption = pControl->GetNormalCaption();
  if (csWCaption.GetLength() > 0) {
    switch (csWCaption[0]) {
      default:  // L'l':
        nStyle = PCS_CIRCLE;
        break;
      case L'8':
        nStyle = PCS_CROSS;
        break;
      case L'u':
        nStyle = PCS_DIAMOND;
        break;
      case L'n':
        nStyle = PCS_SQUARE;
        break;
      case L'H':
        nStyle = PCS_STAR;
        break;
      case L'4':
        nStyle = PCS_CHECK;
        break;
    }
  } else {
    nStyle = PCS_CIRCLE;
  }

  CFX_ByteString csAP_N_ON;

  CPDF_Rect rcCenter =
      CPWL_Utils::DeflateRect(CPWL_Utils::GetCenterSquare(rcWindow), 1.0f);

  if (nStyle == PCS_CIRCLE) {
    if (nBorderStyle == PBS_BEVELED) {
      crLeftTop = CPWL_Color(COLORTYPE_GRAY, 1);
      crRightBottom = CPWL_Utils::SubstractColor(crBackground, 0.25f);
    } else if (nBorderStyle == PBS_INSET) {
      crLeftTop = CPWL_Color(COLORTYPE_GRAY, 0.5f);
      crRightBottom = CPWL_Color(COLORTYPE_GRAY, 0.75f);
    }

    csAP_N_ON = CPWL_Utils::GetCircleFillAppStream(rcCenter, crBackground) +
                CPWL_Utils::GetCircleBorderAppStream(
                    rcCenter, fBorderWidth, crBorder, crLeftTop, crRightBottom,
                    nBorderStyle, dsBorder);
  } else {
    csAP_N_ON = CPWL_Utils::GetRectFillAppStream(rcWindow, crBackground) +
                CPWL_Utils::GetBorderAppStream(rcWindow, fBorderWidth, crBorder,
                                               crLeftTop, crRightBottom,
                                               nBorderStyle, dsBorder);
  }

  CFX_ByteString csAP_N_OFF = csAP_N_ON;

  switch (nBorderStyle) {
    case PBS_BEVELED: {
      CPWL_Color crTemp = crLeftTop;
      crLeftTop = crRightBottom;
      crRightBottom = crTemp;
    } break;
    case PBS_INSET:
      crLeftTop = CPWL_Color(COLORTYPE_GRAY, 0);
      crRightBottom = CPWL_Color(COLORTYPE_GRAY, 1);
      break;
  }

  CFX_ByteString csAP_D_ON;

  if (nStyle == PCS_CIRCLE) {
    CPWL_Color crBK = CPWL_Utils::SubstractColor(crBackground, 0.25f);
    if (nBorderStyle == PBS_BEVELED) {
      crLeftTop = CPWL_Utils::SubstractColor(crBackground, 0.25f);
      crRightBottom = CPWL_Color(COLORTYPE_GRAY, 1);
      crBK = crBackground;
    } else if (nBorderStyle == PBS_INSET) {
      crLeftTop = CPWL_Color(COLORTYPE_GRAY, 0);
      crRightBottom = CPWL_Color(COLORTYPE_GRAY, 1);
    }

    csAP_D_ON = CPWL_Utils::GetCircleFillAppStream(rcCenter, crBK) +
                CPWL_Utils::GetCircleBorderAppStream(
                    rcCenter, fBorderWidth, crBorder, crLeftTop, crRightBottom,
                    nBorderStyle, dsBorder);
  } else {
    csAP_D_ON = CPWL_Utils::GetRectFillAppStream(
                    rcWindow, CPWL_Utils::SubstractColor(crBackground, 0.25f)) +
                CPWL_Utils::GetBorderAppStream(rcWindow, fBorderWidth, crBorder,
                                               crLeftTop, crRightBottom,
                                               nBorderStyle, dsBorder);
  }

  CFX_ByteString csAP_D_OFF = csAP_D_ON;

  csAP_N_ON += CPWL_Utils::GetRadioButtonAppStream(rcClient, nStyle, crText);
  csAP_D_ON += CPWL_Utils::GetRadioButtonAppStream(rcClient, nStyle, crText);

  WriteAppearance("N", GetRotatedRect(), GetMatrix(), csAP_N_ON,
                  pControl->GetCheckedAPState());
  WriteAppearance("N", GetRotatedRect(), GetMatrix(), csAP_N_OFF, "Off");

  WriteAppearance("D", GetRotatedRect(), GetMatrix(), csAP_D_ON,
                  pControl->GetCheckedAPState());
  WriteAppearance("D", GetRotatedRect(), GetMatrix(), csAP_D_OFF, "Off");

  CFX_ByteString csAS = GetAppState();
  if (csAS.IsEmpty())
    SetAppState("Off");
}

void CPDFSDK_Widget::ResetAppearance_ComboBox(const FX_WCHAR* sValue) {
  CPDF_FormControl* pControl = GetFormControl();
  ASSERT(pControl != NULL);
  CPDF_FormField* pField = pControl->GetField();
  ASSERT(pField != NULL);

  CFX_ByteTextBuf sBody, sLines;

  CPDF_Rect rcClient = GetClientRect();
  CPDF_Rect rcButton = rcClient;
  rcButton.left = rcButton.right - 13;
  rcButton.Normalize();

  if (IFX_Edit* pEdit = IFX_Edit::NewEdit()) {
    pEdit->EnableRefresh(FALSE);

    CPDFSDK_Document* pDoc = m_pInterForm->GetDocument();
    ASSERT(pDoc != NULL);
    CPDFDoc_Environment* pEnv = pDoc->GetEnv();
    CBA_FontMap FontMap(this, pEnv->GetSysHandler());
    FontMap.Initial();
    pEdit->SetFontMap(&FontMap);

    CPDF_Rect rcEdit = rcClient;
    rcEdit.right = rcButton.left;
    rcEdit.Normalize();

    pEdit->SetPlateRect(rcEdit);
    pEdit->SetAlignmentV(1);

    FX_FLOAT fFontSize = GetFontSize();
    if (IsFloatZero(fFontSize))
      pEdit->SetAutoFontSize(TRUE);
    else
      pEdit->SetFontSize(fFontSize);

    pEdit->Initialize();

    if (sValue) {
      pEdit->SetText(sValue);
    } else {
      int32_t nCurSel = pField->GetSelectedIndex(0);

      if (nCurSel < 0)
        pEdit->SetText(pField->GetValue().c_str());
      else
        pEdit->SetText(pField->GetOptionLabel(nCurSel).c_str());
    }

    CPDF_Rect rcContent = pEdit->GetContentRect();

    CFX_ByteString sEdit =
        CPWL_Utils::GetEditAppStream(pEdit, CPDF_Point(0.0f, 0.0f));
    if (sEdit.GetLength() > 0) {
      sBody << "/Tx BMC\n"
            << "q\n";
      if (rcContent.Width() > rcEdit.Width() ||
          rcContent.Height() > rcEdit.Height()) {
        sBody << rcEdit.left << " " << rcEdit.bottom << " " << rcEdit.Width()
              << " " << rcEdit.Height() << " re\nW\nn\n";
      }

      CPWL_Color crText = GetTextPWLColor();
      sBody << "BT\n" << CPWL_Utils::GetColorAppStream(crText) << sEdit
            << "ET\n"
            << "Q\nEMC\n";
    }

    IFX_Edit::DelEdit(pEdit);
  }

  sBody << CPWL_Utils::GetDropButtonAppStream(rcButton);

  CFX_ByteString sAP = GetBackgroundAppStream() + GetBorderAppStream() +
                       sLines.GetByteString() + sBody.GetByteString();

  WriteAppearance("N", GetRotatedRect(), GetMatrix(), sAP);
}

void CPDFSDK_Widget::ResetAppearance_ListBox() {
  CPDF_FormControl* pControl = GetFormControl();
  ASSERT(pControl != NULL);
  CPDF_FormField* pField = pControl->GetField();
  ASSERT(pField != NULL);

  CPDF_Rect rcClient = GetClientRect();

  CFX_ByteTextBuf sBody, sLines;

  if (IFX_Edit* pEdit = IFX_Edit::NewEdit()) {
    pEdit->EnableRefresh(FALSE);

    CPDFSDK_Document* pDoc = m_pInterForm->GetDocument();
    ASSERT(pDoc != NULL);
    CPDFDoc_Environment* pEnv = pDoc->GetEnv();

    CBA_FontMap FontMap(this, pEnv->GetSysHandler());
    FontMap.Initial();
    pEdit->SetFontMap(&FontMap);

    pEdit->SetPlateRect(CPDF_Rect(rcClient.left, 0.0f, rcClient.right, 0.0f));

    FX_FLOAT fFontSize = GetFontSize();

    if (IsFloatZero(fFontSize))
      pEdit->SetFontSize(12.0f);
    else
      pEdit->SetFontSize(fFontSize);

    pEdit->Initialize();

    CFX_ByteTextBuf sList;
    FX_FLOAT fy = rcClient.top;

    int32_t nTop = pField->GetTopVisibleIndex();
    int32_t nCount = pField->CountOptions();
    int32_t nSelCount = pField->CountSelectedItems();

    for (int32_t i = nTop; i < nCount; i++) {
      FX_BOOL bSelected = FALSE;
      for (int32_t j = 0; j < nSelCount; j++) {
        if (pField->GetSelectedIndex(j) == i) {
          bSelected = TRUE;
          break;
        }
      }

      pEdit->SetText(pField->GetOptionLabel(i).c_str());

      CPDF_Rect rcContent = pEdit->GetContentRect();
      FX_FLOAT fItemHeight = rcContent.Height();

      if (bSelected) {
        CPDF_Rect rcItem =
            CPDF_Rect(rcClient.left, fy - fItemHeight, rcClient.right, fy);
        sList << "q\n" << CPWL_Utils::GetColorAppStream(
                              CPWL_Color(COLORTYPE_RGB, 0, 51.0f / 255.0f,
                                         113.0f / 255.0f),
                              TRUE)
              << rcItem.left << " " << rcItem.bottom << " " << rcItem.Width()
              << " " << rcItem.Height() << " re f\n"
              << "Q\n";

        sList << "BT\n" << CPWL_Utils::GetColorAppStream(
                               CPWL_Color(COLORTYPE_GRAY, 1), TRUE)
              << CPWL_Utils::GetEditAppStream(pEdit, CPDF_Point(0.0f, fy))
              << "ET\n";
      } else {
        CPWL_Color crText = GetTextPWLColor();
        sList << "BT\n" << CPWL_Utils::GetColorAppStream(crText, TRUE)
              << CPWL_Utils::GetEditAppStream(pEdit, CPDF_Point(0.0f, fy))
              << "ET\n";
      }

      fy -= fItemHeight;
    }

    if (sList.GetSize() > 0) {
      sBody << "/Tx BMC\n"
            << "q\n" << rcClient.left << " " << rcClient.bottom << " "
            << rcClient.Width() << " " << rcClient.Height() << " re\nW\nn\n";
      sBody << sList << "Q\nEMC\n";
    }

    IFX_Edit::DelEdit(pEdit);
  }

  CFX_ByteString sAP = GetBackgroundAppStream() + GetBorderAppStream() +
                       sLines.GetByteString() + sBody.GetByteString();

  WriteAppearance("N", GetRotatedRect(), GetMatrix(), sAP);
}

void CPDFSDK_Widget::ResetAppearance_TextField(const FX_WCHAR* sValue) {
  CPDF_FormControl* pControl = GetFormControl();
  ASSERT(pControl != NULL);
  CPDF_FormField* pField = pControl->GetField();
  ASSERT(pField != NULL);

  CFX_ByteTextBuf sBody, sLines;

  if (IFX_Edit* pEdit = IFX_Edit::NewEdit()) {
    pEdit->EnableRefresh(FALSE);

    CPDFSDK_Document* pDoc = m_pInterForm->GetDocument();
    ASSERT(pDoc != NULL);
    CPDFDoc_Environment* pEnv = pDoc->GetEnv();

    CBA_FontMap FontMap(this, pEnv->GetSysHandler());
    FontMap.Initial();
    pEdit->SetFontMap(&FontMap);

    CPDF_Rect rcClient = GetClientRect();
    pEdit->SetPlateRect(rcClient);
    pEdit->SetAlignmentH(pControl->GetControlAlignment());

    FX_DWORD dwFieldFlags = pField->GetFieldFlags();
    FX_BOOL bMultiLine = (dwFieldFlags >> 12) & 1;

    if (bMultiLine) {
      pEdit->SetMultiLine(TRUE);
      pEdit->SetAutoReturn(TRUE);
    } else {
      pEdit->SetAlignmentV(1);
    }

    FX_WORD subWord = 0;
    if ((dwFieldFlags >> 13) & 1) {
      subWord = '*';
      pEdit->SetPasswordChar(subWord);
    }

    int nMaxLen = pField->GetMaxLen();
    FX_BOOL bCharArray = (dwFieldFlags >> 24) & 1;
    FX_FLOAT fFontSize = GetFontSize();

    if (nMaxLen > 0) {
      if (bCharArray) {
        pEdit->SetCharArray(nMaxLen);

        if (IsFloatZero(fFontSize)) {
          fFontSize = CPWL_Edit::GetCharArrayAutoFontSize(FontMap.GetPDFFont(0),
                                                          rcClient, nMaxLen);
        }
      } else {
        if (sValue)
          nMaxLen = wcslen((const wchar_t*)sValue);
        pEdit->SetLimitChar(nMaxLen);
      }
    }

    if (IsFloatZero(fFontSize))
      pEdit->SetAutoFontSize(TRUE);
    else
      pEdit->SetFontSize(fFontSize);

    pEdit->Initialize();

    if (sValue)
      pEdit->SetText(sValue);
    else
      pEdit->SetText(pField->GetValue().c_str());

    CPDF_Rect rcContent = pEdit->GetContentRect();

    CFX_ByteString sEdit = CPWL_Utils::GetEditAppStream(
        pEdit, CPDF_Point(0.0f, 0.0f), NULL, !bCharArray, subWord);

    if (sEdit.GetLength() > 0) {
      sBody << "/Tx BMC\n"
            << "q\n";
      if (rcContent.Width() > rcClient.Width() ||
          rcContent.Height() > rcClient.Height()) {
        sBody << rcClient.left << " " << rcClient.bottom << " "
              << rcClient.Width() << " " << rcClient.Height() << " re\nW\nn\n";
      }
      CPWL_Color crText = GetTextPWLColor();
      sBody << "BT\n" << CPWL_Utils::GetColorAppStream(crText) << sEdit
            << "ET\n"
            << "Q\nEMC\n";
    }

    if (bCharArray) {
      switch (GetBorderStyle()) {
        case BBS_SOLID: {
          CFX_ByteString sColor =
              CPWL_Utils::GetColorAppStream(GetBorderPWLColor(), FALSE);
          if (sColor.GetLength() > 0) {
            sLines << "q\n" << GetBorderWidth() << " w\n"
                   << CPWL_Utils::GetColorAppStream(GetBorderPWLColor(), FALSE)
                   << " 2 J 0 j\n";

            for (int32_t i = 1; i < nMaxLen; i++) {
              sLines << rcClient.left +
                            ((rcClient.right - rcClient.left) / nMaxLen) * i
                     << " " << rcClient.bottom << " m\n"
                     << rcClient.left +
                            ((rcClient.right - rcClient.left) / nMaxLen) * i
                     << " " << rcClient.top << " l S\n";
            }

            sLines << "Q\n";
          }
        } break;
        case BBS_DASH: {
          CFX_ByteString sColor =
              CPWL_Utils::GetColorAppStream(GetBorderPWLColor(), FALSE);
          if (sColor.GetLength() > 0) {
            CPWL_Dash dsBorder = CPWL_Dash(3, 3, 0);

            sLines << "q\n" << GetBorderWidth() << " w\n"
                   << CPWL_Utils::GetColorAppStream(GetBorderPWLColor(), FALSE)
                   << "[" << dsBorder.nDash << " " << dsBorder.nGap << "] "
                   << dsBorder.nPhase << " d\n";

            for (int32_t i = 1; i < nMaxLen; i++) {
              sLines << rcClient.left +
                            ((rcClient.right - rcClient.left) / nMaxLen) * i
                     << " " << rcClient.bottom << " m\n"
                     << rcClient.left +
                            ((rcClient.right - rcClient.left) / nMaxLen) * i
                     << " " << rcClient.top << " l S\n";
            }

            sLines << "Q\n";
          }
        } break;
      }
    }

    IFX_Edit::DelEdit(pEdit);
  }

  CFX_ByteString sAP = GetBackgroundAppStream() + GetBorderAppStream() +
                       sLines.GetByteString() + sBody.GetByteString();
  WriteAppearance("N", GetRotatedRect(), GetMatrix(), sAP);
}

CPDF_Rect CPDFSDK_Widget::GetClientRect() const {
  CPDF_Rect rcWindow = GetRotatedRect();
  FX_FLOAT fBorderWidth = (FX_FLOAT)GetBorderWidth();
  switch (GetBorderStyle()) {
    case BBS_BEVELED:
    case BBS_INSET:
      fBorderWidth *= 2.0f;
      break;
  }

  return CPWL_Utils::DeflateRect(rcWindow, fBorderWidth);
}

CPDF_Rect CPDFSDK_Widget::GetRotatedRect() const {
  CPDF_Rect rectAnnot = GetRect();
  FX_FLOAT fWidth = rectAnnot.right - rectAnnot.left;
  FX_FLOAT fHeight = rectAnnot.top - rectAnnot.bottom;

  CPDF_FormControl* pControl = GetFormControl();
  CPDF_Rect rcPDFWindow;
  switch (abs(pControl->GetRotation() % 360)) {
    case 0:
    case 180:
    default:
      rcPDFWindow = CPDF_Rect(0, 0, fWidth, fHeight);
      break;
    case 90:
    case 270:
      rcPDFWindow = CPDF_Rect(0, 0, fHeight, fWidth);
      break;
  }

  return rcPDFWindow;
}

CFX_ByteString CPDFSDK_Widget::GetBackgroundAppStream() const {
  CPWL_Color crBackground = GetFillPWLColor();
  if (crBackground.nColorType != COLORTYPE_TRANSPARENT) {
    return CPWL_Utils::GetRectFillAppStream(GetRotatedRect(), crBackground);
  }
  return "";
}

CFX_ByteString CPDFSDK_Widget::GetBorderAppStream() const {
  CPDF_Rect rcWindow = GetRotatedRect();
  CPWL_Color crBorder = GetBorderPWLColor();
  CPWL_Color crBackground = GetFillPWLColor();
  CPWL_Color crLeftTop, crRightBottom;

  FX_FLOAT fBorderWidth = (FX_FLOAT)GetBorderWidth();
  int32_t nBorderStyle = 0;
  CPWL_Dash dsBorder(3, 0, 0);

  switch (GetBorderStyle()) {
    case BBS_DASH:
      nBorderStyle = PBS_DASH;
      dsBorder = CPWL_Dash(3, 3, 0);
      break;
    case BBS_BEVELED:
      nBorderStyle = PBS_BEVELED;
      fBorderWidth *= 2;
      crLeftTop = CPWL_Color(COLORTYPE_GRAY, 1);
      crRightBottom = CPWL_Utils::DevideColor(crBackground, 2);
      break;
    case BBS_INSET:
      nBorderStyle = PBS_INSET;
      fBorderWidth *= 2;
      crLeftTop = CPWL_Color(COLORTYPE_GRAY, 0.5);
      crRightBottom = CPWL_Color(COLORTYPE_GRAY, 0.75);
      break;
    case BBS_UNDERLINE:
      nBorderStyle = PBS_UNDERLINED;
      break;
    default:
      nBorderStyle = PBS_SOLID;
      break;
  }

  return CPWL_Utils::GetBorderAppStream(rcWindow, fBorderWidth, crBorder,
                                        crLeftTop, crRightBottom, nBorderStyle,
                                        dsBorder);
}

CFX_Matrix CPDFSDK_Widget::GetMatrix() const {
  CFX_Matrix mt;
  CPDF_FormControl* pControl = GetFormControl();
  ASSERT(pControl != NULL);

  CPDF_Rect rcAnnot = GetRect();
  FX_FLOAT fWidth = rcAnnot.right - rcAnnot.left;
  FX_FLOAT fHeight = rcAnnot.top - rcAnnot.bottom;

  switch (abs(pControl->GetRotation() % 360)) {
    case 0:
    default:
      mt = CFX_Matrix(1, 0, 0, 1, 0, 0);
      break;
    case 90:
      mt = CFX_Matrix(0, 1, -1, 0, fWidth, 0);
      break;
    case 180:
      mt = CFX_Matrix(-1, 0, 0, -1, fWidth, fHeight);
      break;
    case 270:
      mt = CFX_Matrix(0, -1, 1, 0, 0, fHeight);
      break;
  }

  return mt;
}

CPWL_Color CPDFSDK_Widget::GetTextPWLColor() const {
  CPWL_Color crText = CPWL_Color(COLORTYPE_GRAY, 0);

  CPDF_FormControl* pFormCtrl = GetFormControl();
  ASSERT(pFormCtrl != NULL);

  CPDF_DefaultAppearance da = pFormCtrl->GetDefaultAppearance();
  if (da.HasColor()) {
    int32_t iColorType;
    FX_FLOAT fc[4];
    da.GetColor(iColorType, fc);
    crText = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
  }

  return crText;
}

CPWL_Color CPDFSDK_Widget::GetBorderPWLColor() const {
  CPWL_Color crBorder;

  CPDF_FormControl* pFormCtrl = GetFormControl();
  ASSERT(pFormCtrl != NULL);

  int32_t iColorType;
  FX_FLOAT fc[4];
  pFormCtrl->GetOriginalBorderColor(iColorType, fc);
  if (iColorType > 0)
    crBorder = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);

  return crBorder;
}

CPWL_Color CPDFSDK_Widget::GetFillPWLColor() const {
  CPWL_Color crFill;

  CPDF_FormControl* pFormCtrl = GetFormControl();
  ASSERT(pFormCtrl != NULL);

  int32_t iColorType;
  FX_FLOAT fc[4];
  pFormCtrl->GetOriginalBackgroundColor(iColorType, fc);
  if (iColorType > 0)
    crFill = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);

  return crFill;
}

void CPDFSDK_Widget::AddImageToAppearance(const CFX_ByteString& sAPType,
                                          CPDF_Stream* pImage) {
  ASSERT(pImage != NULL);

  CPDF_Document* pDoc = m_pPageView->GetPDFDocument();
  ASSERT(pDoc != NULL);

  CPDF_Dictionary* pAPDict = m_pAnnot->GetAnnotDict()->GetDict("AP");
  ASSERT(pAPDict != NULL);

  CPDF_Stream* pStream = pAPDict->GetStream(sAPType);
  ASSERT(pStream != NULL);

  CPDF_Dictionary* pStreamDict = pStream->GetDict();
  ASSERT(pStreamDict != NULL);

  CFX_ByteString sImageAlias = "IMG";

  if (CPDF_Dictionary* pImageDict = pImage->GetDict()) {
    sImageAlias = pImageDict->GetString("Name");
    if (sImageAlias.IsEmpty())
      sImageAlias = "IMG";
  }

  CPDF_Dictionary* pStreamResList = pStreamDict->GetDict("Resources");
  if (!pStreamResList) {
    pStreamResList = new CPDF_Dictionary();
    pStreamDict->SetAt("Resources", pStreamResList);
  }

  if (pStreamResList) {
    CPDF_Dictionary* pXObject = new CPDF_Dictionary;
    pXObject->SetAtReference(sImageAlias, pDoc, pImage);
    pStreamResList->SetAt("XObject", pXObject);
  }
}

void CPDFSDK_Widget::RemoveAppearance(const CFX_ByteString& sAPType) {
  if (CPDF_Dictionary* pAPDict = m_pAnnot->GetAnnotDict()->GetDict("AP")) {
    pAPDict->RemoveAt(sAPType);
  }
}

FX_BOOL CPDFSDK_Widget::OnAAction(CPDF_AAction::AActionType type,
                                  PDFSDK_FieldAction& data,
                                  CPDFSDK_PageView* pPageView) {
  CPDFSDK_Document* pDocument = pPageView->GetSDKDocument();
  CPDFDoc_Environment* pEnv = pDocument->GetEnv();
  CPDF_Action action = GetAAction(type);

  if (action && action.GetType() != CPDF_Action::Unknown) {
    CPDFSDK_ActionHandler* pActionHandler = pEnv->GetActionHander();
    return pActionHandler->DoAction_Field(action, type, pDocument,
                                          GetFormField(), data);
  }
  return FALSE;
}

CPDF_Action CPDFSDK_Widget::GetAAction(CPDF_AAction::AActionType eAAT) {
  switch (eAAT) {
    case CPDF_AAction::CursorEnter:
    case CPDF_AAction::CursorExit:
    case CPDF_AAction::ButtonDown:
    case CPDF_AAction::ButtonUp:
    case CPDF_AAction::GetFocus:
    case CPDF_AAction::LoseFocus:
    case CPDF_AAction::PageOpen:
    case CPDF_AAction::PageClose:
    case CPDF_AAction::PageVisible:
    case CPDF_AAction::PageInvisible:
      return CPDFSDK_BAAnnot::GetAAction(eAAT);

    case CPDF_AAction::KeyStroke:
    case CPDF_AAction::Format:
    case CPDF_AAction::Validate:
    case CPDF_AAction::Calculate: {
      CPDF_FormField* pField = GetFormField();
      if (CPDF_AAction aa = pField->GetAdditionalAction())
        return aa.GetAction(eAAT);
      return CPDFSDK_BAAnnot::GetAAction(eAAT);
    }
    default:
      break;
  }

  return CPDF_Action();
}

CFX_WideString CPDFSDK_Widget::GetAlternateName() const {
  CPDF_FormField* pFormField = GetFormField();
  ASSERT(pFormField != NULL);

  return pFormField->GetAlternateName();
}

int32_t CPDFSDK_Widget::GetAppearanceAge() const {
  return m_nAppAge;
}

int32_t CPDFSDK_Widget::GetValueAge() const {
  return m_nValueAge;
}

FX_BOOL CPDFSDK_Widget::HitTest(FX_FLOAT pageX, FX_FLOAT pageY) {
  CPDF_Annot* pAnnot = GetPDFAnnot();
  CFX_FloatRect annotRect;
  pAnnot->GetRect(annotRect);
  if (annotRect.Contains(pageX, pageY)) {
    if (!IsVisible())
      return FALSE;

    int nFieldFlags = GetFieldFlags();
    if ((nFieldFlags & FIELDFLAG_READONLY) == FIELDFLAG_READONLY)
      return FALSE;

    return TRUE;
  }
  return FALSE;
}

CPDFSDK_InterForm::CPDFSDK_InterForm(CPDFSDK_Document* pDocument)
    : m_pDocument(pDocument),
      m_pInterForm(NULL),
      m_bCalculate(TRUE),
      m_bBusy(FALSE) {
  m_pInterForm = new CPDF_InterForm(m_pDocument->GetPDFDocument(), FALSE);
  m_pInterForm->SetFormNotify(this);

  for (int i = 0; i < kNumFieldTypes; ++i)
    m_bNeedHightlight[i] = FALSE;
  m_iHighlightAlpha = 0;
}

CPDFSDK_InterForm::~CPDFSDK_InterForm() {
  delete m_pInterForm;
  m_pInterForm = nullptr;
  m_Map.clear();
}

FX_BOOL CPDFSDK_InterForm::HighlightWidgets() {
  return FALSE;
}

CPDFSDK_Widget* CPDFSDK_InterForm::GetSibling(CPDFSDK_Widget* pWidget,
                                              FX_BOOL bNext) const {
  nonstd::unique_ptr<CBA_AnnotIterator> pIterator(
      new CBA_AnnotIterator(pWidget->GetPageView(), "Widget", ""));

  if (bNext) {
    return (CPDFSDK_Widget*)pIterator->GetNextAnnot(pWidget);
  }
  return (CPDFSDK_Widget*)pIterator->GetPrevAnnot(pWidget);
}

CPDFSDK_Widget* CPDFSDK_InterForm::GetWidget(CPDF_FormControl* pControl) const {
  if (!pControl || !m_pInterForm)
    return nullptr;

  CPDFSDK_Widget* pWidget = nullptr;
  const auto it = m_Map.find(pControl);
  if (it != m_Map.end())
    pWidget = it->second;

  if (pWidget)
    return pWidget;

  CPDF_Dictionary* pControlDict = pControl->GetWidget();
  CPDF_Document* pDocument = m_pDocument->GetPDFDocument();
  CPDFSDK_PageView* pPage = nullptr;

  if (CPDF_Dictionary* pPageDict = pControlDict->GetDict("P")) {
    int nPageIndex = pDocument->GetPageIndex(pPageDict->GetObjNum());
    if (nPageIndex >= 0) {
      pPage = m_pDocument->GetPageView(nPageIndex);
    }
  }

  if (!pPage) {
    int nPageIndex = GetPageIndexByAnnotDict(pDocument, pControlDict);
    if (nPageIndex >= 0) {
      pPage = m_pDocument->GetPageView(nPageIndex);
    }
  }

  if (!pPage)
    return nullptr;
  return (CPDFSDK_Widget*)pPage->GetAnnotByDict(pControlDict);
}

void CPDFSDK_InterForm::GetWidgets(
    const CFX_WideString& sFieldName,
    std::vector<CPDFSDK_Widget*>* widgets) const {
  for (int i = 0, sz = m_pInterForm->CountFields(sFieldName); i < sz; ++i) {
    CPDF_FormField* pFormField = m_pInterForm->GetField(i, sFieldName);
    ASSERT(pFormField);
    GetWidgets(pFormField, widgets);
  }
}

void CPDFSDK_InterForm::GetWidgets(
    CPDF_FormField* pField,
    std::vector<CPDFSDK_Widget*>* widgets) const {
  for (int i = 0, sz = pField->CountControls(); i < sz; ++i) {
    CPDF_FormControl* pFormCtrl = pField->GetControl(i);
    ASSERT(pFormCtrl);
    CPDFSDK_Widget* pWidget = GetWidget(pFormCtrl);
    if (pWidget)
      widgets->push_back(pWidget);
  }
}

int CPDFSDK_InterForm::GetPageIndexByAnnotDict(
    CPDF_Document* pDocument,
    CPDF_Dictionary* pAnnotDict) const {
  ASSERT(pDocument != NULL);
  ASSERT(pAnnotDict != NULL);

  for (int i = 0, sz = pDocument->GetPageCount(); i < sz; i++) {
    if (CPDF_Dictionary* pPageDict = pDocument->GetPage(i)) {
      if (CPDF_Array* pAnnots = pPageDict->GetArray("Annots")) {
        for (int j = 0, jsz = pAnnots->GetCount(); j < jsz; j++) {
          CPDF_Object* pDict = pAnnots->GetElementValue(j);
          if (pAnnotDict == pDict) {
            return i;
          }
        }
      }
    }
  }

  return -1;
}

void CPDFSDK_InterForm::AddMap(CPDF_FormControl* pControl,
                               CPDFSDK_Widget* pWidget) {
  m_Map[pControl] = pWidget;
}

void CPDFSDK_InterForm::RemoveMap(CPDF_FormControl* pControl) {
  m_Map.erase(pControl);
}

void CPDFSDK_InterForm::EnableCalculate(FX_BOOL bEnabled) {
  m_bCalculate = bEnabled;
}

FX_BOOL CPDFSDK_InterForm::IsCalculateEnabled() const {
  return m_bCalculate;
}

#ifdef _WIN32
CPDF_Stream* CPDFSDK_InterForm::LoadImageFromFile(const CFX_WideString& sFile) {
  CPDF_Document* pDocument = m_pDocument->GetPDFDocument();
  CPDF_Stream* pRetStream = NULL;

  if (CFX_DIBitmap* pBmp = CFX_WindowsDIB::LoadFromFile(sFile.c_str())) {
    int nWidth = pBmp->GetWidth();
    int nHeight = pBmp->GetHeight();

    CPDF_Image Image(pDocument);
    Image.SetImage(pBmp, FALSE);
    CPDF_Stream* pImageStream = Image.GetStream();
    if (pImageStream) {
      if (pImageStream->GetObjNum() == 0)
        pDocument->AddIndirectObject(pImageStream);

      CPDF_Dictionary* pStreamDict = new CPDF_Dictionary();
      pStreamDict->SetAtName("Subtype", "Form");
      pStreamDict->SetAtName("Name", "IMG");
      CPDF_Array* pMatrix = new CPDF_Array();
      pStreamDict->SetAt("Matrix", pMatrix);
      pMatrix->AddInteger(1);
      pMatrix->AddInteger(0);
      pMatrix->AddInteger(0);
      pMatrix->AddInteger(1);
      pMatrix->AddInteger(-nWidth / 2);
      pMatrix->AddInteger(-nHeight / 2);
      CPDF_Dictionary* pResource = new CPDF_Dictionary();
      pStreamDict->SetAt("Resources", pResource);
      CPDF_Dictionary* pXObject = new CPDF_Dictionary();
      pResource->SetAt("XObject", pXObject);
      pXObject->SetAtReference("Img", pDocument, pImageStream);
      CPDF_Array* pProcSet = new CPDF_Array();
      pResource->SetAt("ProcSet", pProcSet);
      pProcSet->AddName("PDF");
      pProcSet->AddName("ImageC");
      pStreamDict->SetAtName("Type", "XObject");
      CPDF_Array* pBBox = new CPDF_Array();
      pStreamDict->SetAt("BBox", pBBox);
      pBBox->AddInteger(0);
      pBBox->AddInteger(0);
      pBBox->AddInteger(nWidth);
      pBBox->AddInteger(nHeight);
      pStreamDict->SetAtInteger("FormType", 1);

      pRetStream = new CPDF_Stream(NULL, 0, NULL);
      CFX_ByteString csStream;
      csStream.Format("q\n%d 0 0 %d 0 0 cm\n/Img Do\nQ", nWidth, nHeight);
      pRetStream->InitStream((uint8_t*)csStream.c_str(), csStream.GetLength(),
                             pStreamDict);
      pDocument->AddIndirectObject(pRetStream);
    }

    delete pBmp;
  }

  return pRetStream;
}
#endif

void CPDFSDK_InterForm::OnCalculate(CPDF_FormField* pFormField) {
  ASSERT(m_pDocument != NULL);
  CPDFDoc_Environment* pEnv = m_pDocument->GetEnv();
  ASSERT(pEnv);
  if (!pEnv->IsJSInitiated())
    return;

  if (m_bBusy)
    return;

  m_bBusy = TRUE;

  if (IsCalculateEnabled()) {
    IJS_Runtime* pRuntime = m_pDocument->GetJsRuntime();
    ASSERT(pRuntime != NULL);

    pRuntime->SetReaderDocument(m_pDocument);

    int nSize = m_pInterForm->CountFieldsInCalculationOrder();
    for (int i = 0; i < nSize; i++) {
      if (CPDF_FormField* pField =
              m_pInterForm->GetFieldInCalculationOrder(i)) {
        int nType = pField->GetFieldType();
        if (nType == FIELDTYPE_COMBOBOX || nType == FIELDTYPE_TEXTFIELD) {
          CPDF_AAction aAction = pField->GetAdditionalAction();
          if (aAction && aAction.ActionExist(CPDF_AAction::Calculate)) {
            CPDF_Action action = aAction.GetAction(CPDF_AAction::Calculate);
            if (action) {
              CFX_WideString csJS = action.GetJavaScript();
              if (!csJS.IsEmpty()) {
                IJS_Context* pContext = pRuntime->NewContext();
                ASSERT(pContext != NULL);

                CFX_WideString sOldValue = pField->GetValue();
                CFX_WideString sValue = sOldValue;
                FX_BOOL bRC = TRUE;
                pContext->OnField_Calculate(pFormField, pField, sValue, bRC);

                CFX_WideString sInfo;
                FX_BOOL bRet = pContext->RunScript(csJS, &sInfo);
                pRuntime->ReleaseContext(pContext);

                if (bRet) {
                  if (bRC) {
                    if (sValue.Compare(sOldValue) != 0)
                      pField->SetValue(sValue, TRUE);
                  }
                }
              }
            }
          }
        }
      }
    }
  }

  m_bBusy = FALSE;
}

CFX_WideString CPDFSDK_InterForm::OnFormat(CPDF_FormField* pFormField,
                                           FX_BOOL& bFormated) {
  ASSERT(m_pDocument != NULL);
  ASSERT(pFormField != NULL);

  CFX_WideString sValue = pFormField->GetValue();
  CPDFDoc_Environment* pEnv = m_pDocument->GetEnv();
  ASSERT(pEnv);
  if (!pEnv->IsJSInitiated()) {
    bFormated = FALSE;
    return sValue;
  }

  IJS_Runtime* pRuntime = m_pDocument->GetJsRuntime();
  ASSERT(pRuntime != NULL);

  pRuntime->SetReaderDocument(m_pDocument);

  if (pFormField->GetFieldType() == FIELDTYPE_COMBOBOX) {
    if (pFormField->CountSelectedItems() > 0) {
      int index = pFormField->GetSelectedIndex(0);
      if (index >= 0)
        sValue = pFormField->GetOptionLabel(index);
    }
  }

  bFormated = FALSE;

  CPDF_AAction aAction = pFormField->GetAdditionalAction();
  if (aAction && aAction.ActionExist(CPDF_AAction::Format)) {
    CPDF_Action action = aAction.GetAction(CPDF_AAction::Format);
    if (action) {
      CFX_WideString script = action.GetJavaScript();
      if (!script.IsEmpty()) {
        CFX_WideString Value = sValue;

        IJS_Context* pContext = pRuntime->NewContext();
        ASSERT(pContext != NULL);

        pContext->OnField_Format(pFormField, Value, TRUE);

        CFX_WideString sInfo;
        FX_BOOL bRet = pContext->RunScript(script, &sInfo);
        pRuntime->ReleaseContext(pContext);

        if (bRet) {
          sValue = Value;
          bFormated = TRUE;
        }
      }
    }
  }

  return sValue;
}

void CPDFSDK_InterForm::ResetFieldAppearance(CPDF_FormField* pFormField,
                                             const FX_WCHAR* sValue,
                                             FX_BOOL bValueChanged) {
  ASSERT(pFormField != NULL);

  for (int i = 0, sz = pFormField->CountControls(); i < sz; i++) {
    CPDF_FormControl* pFormCtrl = pFormField->GetControl(i);
    ASSERT(pFormCtrl != NULL);

    ASSERT(m_pInterForm != NULL);
    if (CPDFSDK_Widget* pWidget = GetWidget(pFormCtrl))
      pWidget->ResetAppearance(sValue, bValueChanged);
  }
}

void CPDFSDK_InterForm::UpdateField(CPDF_FormField* pFormField) {
  for (int i = 0, sz = pFormField->CountControls(); i < sz; i++) {
    CPDF_FormControl* pFormCtrl = pFormField->GetControl(i);
    ASSERT(pFormCtrl != NULL);

    if (CPDFSDK_Widget* pWidget = GetWidget(pFormCtrl)) {
      CPDFDoc_Environment* pEnv = m_pDocument->GetEnv();
      CFFL_IFormFiller* pIFormFiller = pEnv->GetIFormFiller();
      UnderlyingPageType* pPage = pWidget->GetUnderlyingPage();
      CPDFSDK_PageView* pPageView = m_pDocument->GetPageView(pPage, FALSE);
      FX_RECT rcBBox = pIFormFiller->GetViewBBox(pPageView, pWidget);

      pEnv->FFI_Invalidate(pPage, rcBBox.left, rcBBox.top, rcBBox.right,
                           rcBBox.bottom);
    }
  }
}

void CPDFSDK_InterForm::OnKeyStrokeCommit(CPDF_FormField* pFormField,
                                          CFX_WideString& csValue,
                                          FX_BOOL& bRC) {
  ASSERT(pFormField != NULL);

  CPDF_AAction aAction = pFormField->GetAdditionalAction();
  if (aAction && aAction.ActionExist(CPDF_AAction::KeyStroke)) {
    CPDF_Action action = aAction.GetAction(CPDF_AAction::KeyStroke);
    if (action) {
      ASSERT(m_pDocument != NULL);
      CPDFDoc_Environment* pEnv = m_pDocument->GetEnv();
      ASSERT(pEnv != NULL);

      CPDFSDK_ActionHandler* pActionHandler = pEnv->GetActionHander();
      ASSERT(pActionHandler != NULL);

      PDFSDK_FieldAction fa;
      fa.bModifier = pEnv->FFI_IsCTRLKeyDown(0);
      fa.bShift = pEnv->FFI_IsSHIFTKeyDown(0);
      fa.sValue = csValue;

      pActionHandler->DoAction_FieldJavaScript(action, CPDF_AAction::KeyStroke,
                                               m_pDocument, pFormField, fa);
      bRC = fa.bRC;
    }
  }
}

void CPDFSDK_InterForm::OnValidate(CPDF_FormField* pFormField,
                                   CFX_WideString& csValue,
                                   FX_BOOL& bRC) {
  ASSERT(pFormField != NULL);

  CPDF_AAction aAction = pFormField->GetAdditionalAction();
  if (aAction && aAction.ActionExist(CPDF_AAction::Validate)) {
    CPDF_Action action = aAction.GetAction(CPDF_AAction::Validate);
    if (action) {
      ASSERT(m_pDocument != NULL);
      CPDFDoc_Environment* pEnv = m_pDocument->GetEnv();
      ASSERT(pEnv != NULL);

      CPDFSDK_ActionHandler* pActionHandler = pEnv->GetActionHander();
      ASSERT(pActionHandler != NULL);

      PDFSDK_FieldAction fa;
      fa.bModifier = pEnv->FFI_IsCTRLKeyDown(0);
      fa.bShift = pEnv->FFI_IsSHIFTKeyDown(0);
      fa.sValue = csValue;

      pActionHandler->DoAction_FieldJavaScript(action, CPDF_AAction::Validate,
                                               m_pDocument, pFormField, fa);
      bRC = fa.bRC;
    }
  }
}

/* ----------------------------- action ----------------------------- */

FX_BOOL CPDFSDK_InterForm::DoAction_Hide(const CPDF_Action& action) {
  ASSERT(action);

  CPDF_ActionFields af = action.GetWidgets();
  std::vector<CPDF_Object*> fieldObjects = af.GetAllFields();
  std::vector<CPDF_FormField*> fields = GetFieldFromObjects(fieldObjects);

  FX_BOOL bHide = action.GetHideStatus();
  FX_BOOL bChanged = FALSE;

  for (CPDF_FormField* pField : fields) {
    for (int i = 0, sz = pField->CountControls(); i < sz; ++i) {
      CPDF_FormControl* pControl = pField->GetControl(i);
      ASSERT(pControl);

      if (CPDFSDK_Widget* pWidget = GetWidget(pControl)) {
        int nFlags = pWidget->GetFlags();
        nFlags &= ~ANNOTFLAG_INVISIBLE;
        nFlags &= ~ANNOTFLAG_NOVIEW;
        if (bHide)
          nFlags |= ANNOTFLAG_HIDDEN;
        else
          nFlags &= ~ANNOTFLAG_HIDDEN;
        pWidget->SetFlags(nFlags);
        pWidget->GetPageView()->UpdateView(pWidget);
        bChanged = TRUE;
      }
    }
  }

  return bChanged;
}

FX_BOOL CPDFSDK_InterForm::DoAction_SubmitForm(const CPDF_Action& action) {
  ASSERT(m_pInterForm != NULL);
  CFX_WideString sDestination = action.GetFilePath();
  if (sDestination.IsEmpty())
    return FALSE;

  CPDF_Dictionary* pActionDict = action.GetDict();
  if (pActionDict->KeyExist("Fields")) {
    CPDF_ActionFields af = action.GetWidgets();
    FX_DWORD dwFlags = action.GetFlags();
    std::vector<CPDF_Object*> fieldObjects = af.GetAllFields();
    std::vector<CPDF_FormField*> fields = GetFieldFromObjects(fieldObjects);
    if (!fields.empty()) {
      bool bIncludeOrExclude = !(dwFlags & 0x01);
      if (m_pInterForm->CheckRequiredFields(&fields, bIncludeOrExclude))
        return FALSE;

      return SubmitFields(sDestination, fields, bIncludeOrExclude, FALSE);
    }
  }
  if (m_pInterForm->CheckRequiredFields(nullptr, true))
    return FALSE;

  return SubmitForm(sDestination, FALSE);
}

FX_BOOL CPDFSDK_InterForm::SubmitFields(
    const CFX_WideString& csDestination,
    const std::vector<CPDF_FormField*>& fields,
    FX_BOOL bIncludeOrExclude,
    FX_BOOL bUrlEncoded) {
  CPDFDoc_Environment* pEnv = m_pDocument->GetEnv();

  CFX_ByteTextBuf textBuf;
  ExportFieldsToFDFTextBuf(fields, bIncludeOrExclude, textBuf);

  uint8_t* pBuffer = textBuf.GetBuffer();
  FX_STRSIZE nBufSize = textBuf.GetLength();

  if (bUrlEncoded && !FDFToURLEncodedData(pBuffer, nBufSize))
    return FALSE;

  pEnv->JS_docSubmitForm(pBuffer, nBufSize, csDestination.c_str());
  return TRUE;
}

FX_BOOL CPDFSDK_InterForm::FDFToURLEncodedData(CFX_WideString csFDFFile,
                                               CFX_WideString csTxtFile) {
  return TRUE;
}

FX_BOOL CPDFSDK_InterForm::FDFToURLEncodedData(uint8_t*& pBuf,
                                               FX_STRSIZE& nBufSize) {
  CFDF_Document* pFDF = CFDF_Document::ParseMemory(pBuf, nBufSize);
  if (pFDF) {
    CPDF_Dictionary* pMainDict = pFDF->GetRoot()->GetDict("FDF");
    if (!pMainDict)
      return FALSE;

    // Get fields
    CPDF_Array* pFields = pMainDict->GetArray("Fields");
    if (!pFields)
      return FALSE;

    CFX_ByteTextBuf fdfEncodedData;

    for (FX_DWORD i = 0; i < pFields->GetCount(); i++) {
      CPDF_Dictionary* pField = pFields->GetDict(i);
      if (!pField)
        continue;
      CFX_WideString name;
      name = pField->GetUnicodeText("T");
      CFX_ByteString name_b = CFX_ByteString::FromUnicode(name);
      CFX_ByteString csBValue = pField->GetString("V");
      CFX_WideString csWValue = PDF_DecodeText(csBValue);
      CFX_ByteString csValue_b = CFX_ByteString::FromUnicode(csWValue);

      fdfEncodedData = fdfEncodedData << name_b.GetBuffer(name_b.GetLength());
      name_b.ReleaseBuffer();
      fdfEncodedData = fdfEncodedData << "=";
      fdfEncodedData = fdfEncodedData
                       << csValue_b.GetBuffer(csValue_b.GetLength());
      csValue_b.ReleaseBuffer();
      if (i != pFields->GetCount() - 1)
        fdfEncodedData = fdfEncodedData << "&";
    }

    nBufSize = fdfEncodedData.GetLength();
    pBuf = FX_Alloc(uint8_t, nBufSize);
    FXSYS_memcpy(pBuf, fdfEncodedData.GetBuffer(), nBufSize);
  }
  return TRUE;
}

FX_BOOL CPDFSDK_InterForm::ExportFieldsToFDFTextBuf(
    const std::vector<CPDF_FormField*>& fields,
    FX_BOOL bIncludeOrExclude,
    CFX_ByteTextBuf& textBuf) {
  nonstd::unique_ptr<CFDF_Document> pFDF(m_pInterForm->ExportToFDF(
      m_pDocument->GetPath(), fields, bIncludeOrExclude));
  return pFDF ? pFDF->WriteBuf(textBuf) : FALSE;
}

CFX_WideString CPDFSDK_InterForm::GetTemporaryFileName(
    const CFX_WideString& sFileExt) {
  CFX_WideString sFileName;
  return L"";
}

FX_BOOL CPDFSDK_InterForm::SubmitForm(const CFX_WideString& sDestination,
                                      FX_BOOL bUrlEncoded) {
  if (sDestination.IsEmpty())
    return FALSE;

  CPDFDoc_Environment* pEnv = m_pDocument->GetEnv();
  ASSERT(pEnv != NULL);

  if (!m_pDocument)
    return FALSE;
  CFX_WideString wsPDFFilePath = m_pDocument->GetPath();

  if (!m_pInterForm)
    return FALSE;
  CFDF_Document* pFDFDoc = m_pInterForm->ExportToFDF(wsPDFFilePath);
  if (!pFDFDoc)
    return FALSE;

  CFX_ByteTextBuf FdfBuffer;
  FX_BOOL bRet = pFDFDoc->WriteBuf(FdfBuffer);
  delete pFDFDoc;
  if (!bRet)
    return FALSE;

  uint8_t* pBuffer = FdfBuffer.GetBuffer();
  FX_STRSIZE nBufSize = FdfBuffer.GetLength();

  if (bUrlEncoded) {
    if (!FDFToURLEncodedData(pBuffer, nBufSize))
      return FALSE;
  }

  pEnv->JS_docSubmitForm(pBuffer, nBufSize, sDestination.c_str());

  if (bUrlEncoded) {
    FX_Free(pBuffer);
    pBuffer = NULL;
  }

  return TRUE;
}

FX_BOOL CPDFSDK_InterForm::ExportFormToFDFTextBuf(CFX_ByteTextBuf& textBuf) {
  ASSERT(m_pInterForm != NULL);
  ASSERT(m_pDocument != NULL);

  CFDF_Document* pFDF = m_pInterForm->ExportToFDF(m_pDocument->GetPath());
  if (!pFDF)
    return FALSE;

  FX_BOOL bRet = pFDF->WriteBuf(textBuf);
  delete pFDF;

  return bRet;
}

FX_BOOL CPDFSDK_InterForm::DoAction_ResetForm(const CPDF_Action& action) {
  ASSERT(action);

  CPDF_Dictionary* pActionDict = action.GetDict();
  if (!pActionDict->KeyExist("Fields"))
    return m_pInterForm->ResetForm(true);

  CPDF_ActionFields af = action.GetWidgets();
  FX_DWORD dwFlags = action.GetFlags();

  std::vector<CPDF_Object*> fieldObjects = af.GetAllFields();
  std::vector<CPDF_FormField*> fields = GetFieldFromObjects(fieldObjects);
  return m_pInterForm->ResetForm(fields, !(dwFlags & 0x01), true);
}

FX_BOOL CPDFSDK_InterForm::DoAction_ImportData(const CPDF_Action& action) {
  return FALSE;
}

std::vector<CPDF_FormField*> CPDFSDK_InterForm::GetFieldFromObjects(
    const std::vector<CPDF_Object*>& objects) const {
  std::vector<CPDF_FormField*> fields;
  for (CPDF_Object* pObject : objects) {
    if (pObject && pObject->IsString()) {
      CFX_WideString csName = pObject->GetUnicodeText();
      CPDF_FormField* pField = m_pInterForm->GetField(0, csName);
      if (pField)
        fields.push_back(pField);
    }
  }
  return fields;
}

/* ----------------------------- CPDF_FormNotify -----------------------------
 */

int CPDFSDK_InterForm::BeforeValueChange(const CPDF_FormField* pField,
                                         CFX_WideString& csValue) {
  CPDF_FormField* pFormField = (CPDF_FormField*)pField;
  int nType = pFormField->GetFieldType();
  if (nType == FIELDTYPE_COMBOBOX || nType == FIELDTYPE_TEXTFIELD) {
    FX_BOOL bRC = TRUE;
    OnKeyStrokeCommit(pFormField, csValue, bRC);
    if (bRC) {
      OnValidate(pFormField, csValue, bRC);
      return bRC ? 1 : -1;
    }
    return -1;
  }
  return 0;
}

int CPDFSDK_InterForm::AfterValueChange(const CPDF_FormField* pField) {
  CPDF_FormField* pFormField = (CPDF_FormField*)pField;
  int nType = pFormField->GetFieldType();
  if (nType == FIELDTYPE_COMBOBOX || nType == FIELDTYPE_TEXTFIELD) {
    OnCalculate(pFormField);
    FX_BOOL bFormated = FALSE;
    CFX_WideString sValue = OnFormat(pFormField, bFormated);
    if (bFormated)
      ResetFieldAppearance(pFormField, sValue.c_str(), TRUE);
    else
      ResetFieldAppearance(pFormField, NULL, TRUE);
    UpdateField(pFormField);
  }
  return 0;
}

int CPDFSDK_InterForm::BeforeSelectionChange(const CPDF_FormField* pField,
                                             CFX_WideString& csValue) {
  CPDF_FormField* pFormField = (CPDF_FormField*)pField;
  if (pFormField->GetFieldType() != FIELDTYPE_LISTBOX)
    return 0;

  FX_BOOL bRC = TRUE;
  OnKeyStrokeCommit(pFormField, csValue, bRC);
  if (!bRC)
    return -1;

  OnValidate(pFormField, csValue, bRC);
  if (!bRC)
    return -1;

  return 1;
}

int CPDFSDK_InterForm::AfterSelectionChange(const CPDF_FormField* pField) {
  CPDF_FormField* pFormField = (CPDF_FormField*)pField;
  if (pFormField->GetFieldType() == FIELDTYPE_LISTBOX) {
    OnCalculate(pFormField);
    ResetFieldAppearance(pFormField, NULL, TRUE);
    UpdateField(pFormField);
  }
  return 0;
}

int CPDFSDK_InterForm::AfterCheckedStatusChange(
    const CPDF_FormField* pField,
    const CFX_ByteArray& statusArray) {
  CPDF_FormField* pFormField = (CPDF_FormField*)pField;
  int nType = pFormField->GetFieldType();
  if (nType == FIELDTYPE_CHECKBOX || nType == FIELDTYPE_RADIOBUTTON) {
    OnCalculate(pFormField);
    UpdateField(pFormField);
  }
  return 0;
}

int CPDFSDK_InterForm::BeforeFormReset(const CPDF_InterForm* pForm) {
  return 0;
}

int CPDFSDK_InterForm::AfterFormReset(const CPDF_InterForm* pForm) {
  OnCalculate(nullptr);
  return 0;
}

int CPDFSDK_InterForm::BeforeFormImportData(const CPDF_InterForm* pForm) {
  return 0;
}

int CPDFSDK_InterForm::AfterFormImportData(const CPDF_InterForm* pForm) {
  OnCalculate(nullptr);
  return 0;
}

FX_BOOL CPDFSDK_InterForm::IsNeedHighLight(int nFieldType) {
  if (nFieldType < 1 || nFieldType > kNumFieldTypes)
    return FALSE;
  return m_bNeedHightlight[nFieldType - 1];
}

void CPDFSDK_InterForm::RemoveAllHighLight() {
  for (int i = 0; i < kNumFieldTypes; ++i)
    m_bNeedHightlight[i] = FALSE;
}

void CPDFSDK_InterForm::SetHighlightColor(FX_COLORREF clr, int nFieldType) {
  if (nFieldType < 0 || nFieldType > kNumFieldTypes)
    return;
  switch (nFieldType) {
    case 0: {
      for (int i = 0; i < kNumFieldTypes; ++i) {
        m_aHighlightColor[i] = clr;
        m_bNeedHightlight[i] = TRUE;
      }
      break;
    }
    default: {
      m_aHighlightColor[nFieldType - 1] = clr;
      m_bNeedHightlight[nFieldType - 1] = TRUE;
      break;
    }
  }
}

FX_COLORREF CPDFSDK_InterForm::GetHighlightColor(int nFieldType) {
  if (nFieldType < 0 || nFieldType > kNumFieldTypes)
    return FXSYS_RGB(255, 255, 255);
  if (nFieldType == 0)
    return m_aHighlightColor[0];
  return m_aHighlightColor[nFieldType - 1];
}

/* ------------------------- CBA_AnnotIterator ------------------------- */

CBA_AnnotIterator::CBA_AnnotIterator(CPDFSDK_PageView* pPageView,
                                     const CFX_ByteString& sType,
                                     const CFX_ByteString& sSubType)
    : m_pPageView(pPageView),
      m_sType(sType),
      m_sSubType(sSubType),
      m_nTabs(BAI_STRUCTURE) {
  ASSERT(m_pPageView != NULL);

  CPDF_Page* pPDFPage = m_pPageView->GetPDFPage();
  ASSERT(pPDFPage != NULL);
  ASSERT(pPDFPage->m_pFormDict != NULL);

  CFX_ByteString sTabs = pPDFPage->m_pFormDict->GetString("Tabs");

  if (sTabs == "R") {
    m_nTabs = BAI_ROW;
  } else if (sTabs == "C") {
    m_nTabs = BAI_COLUMN;
  } else {
    m_nTabs = BAI_STRUCTURE;
  }

  GenerateResults();
}

CBA_AnnotIterator::~CBA_AnnotIterator() {
  m_Annots.RemoveAll();
}

CPDFSDK_Annot* CBA_AnnotIterator::GetFirstAnnot() {
  if (m_Annots.GetSize() > 0)
    return m_Annots[0];

  return NULL;
}

CPDFSDK_Annot* CBA_AnnotIterator::GetLastAnnot() {
  if (m_Annots.GetSize() > 0)
    return m_Annots[m_Annots.GetSize() - 1];

  return NULL;
}

CPDFSDK_Annot* CBA_AnnotIterator::GetNextAnnot(CPDFSDK_Annot* pAnnot) {
  for (int i = 0, sz = m_Annots.GetSize(); i < sz; ++i) {
    if (m_Annots[i] == pAnnot)
      return (i + 1 < sz) ? m_Annots[i + 1] : m_Annots[0];
  }
  return NULL;
}

CPDFSDK_Annot* CBA_AnnotIterator::GetPrevAnnot(CPDFSDK_Annot* pAnnot) {
  for (int i = 0, sz = m_Annots.GetSize(); i < sz; ++i) {
    if (m_Annots[i] == pAnnot)
      return (i - 1 >= 0) ? m_Annots[i - 1] : m_Annots[sz - 1];
  }
  return NULL;
}

int CBA_AnnotIterator::CompareByLeft(CPDFSDK_Annot* p1, CPDFSDK_Annot* p2) {
  ASSERT(p1);
  ASSERT(p2);

  CPDF_Rect rcAnnot1 = GetAnnotRect(p1);
  CPDF_Rect rcAnnot2 = GetAnnotRect(p2);

  if (rcAnnot1.left < rcAnnot2.left)
    return -1;
  if (rcAnnot1.left > rcAnnot2.left)
    return 1;
  return 0;
}

int CBA_AnnotIterator::CompareByTop(CPDFSDK_Annot* p1, CPDFSDK_Annot* p2) {
  ASSERT(p1 != NULL);
  ASSERT(p2 != NULL);

  CPDF_Rect rcAnnot1 = GetAnnotRect(p1);
  CPDF_Rect rcAnnot2 = GetAnnotRect(p2);

  if (rcAnnot1.top < rcAnnot2.top)
    return -1;
  if (rcAnnot1.top > rcAnnot2.top)
    return 1;
  return 0;
}

void CBA_AnnotIterator::GenerateResults() {
  switch (m_nTabs) {
    case BAI_STRUCTURE: {
      for (size_t i = 0; i < m_pPageView->CountAnnots(); ++i) {
        CPDFSDK_Annot* pAnnot = m_pPageView->GetAnnot(i);
        if (pAnnot->GetType() == m_sType && pAnnot->GetSubType() == m_sSubType)
          m_Annots.Add(pAnnot);
      }
      break;
    }
    case BAI_ROW: {
      CPDFSDK_SortAnnots sa;
      for (size_t i = 0; i < m_pPageView->CountAnnots(); ++i) {
        CPDFSDK_Annot* pAnnot = m_pPageView->GetAnnot(i);
        if (pAnnot->GetType() == m_sType && pAnnot->GetSubType() == m_sSubType)
          sa.Add(pAnnot);
      }

      if (sa.GetSize() > 0)
        sa.Sort(CBA_AnnotIterator::CompareByLeft);

      while (sa.GetSize() > 0) {
        int nLeftTopIndex = -1;
        FX_FLOAT fTop = 0.0f;

        for (int i = sa.GetSize() - 1; i >= 0; i--) {
          CPDFSDK_Annot* pAnnot = sa.GetAt(i);
          ASSERT(pAnnot);

          CPDF_Rect rcAnnot = GetAnnotRect(pAnnot);

          if (rcAnnot.top > fTop) {
            nLeftTopIndex = i;
            fTop = rcAnnot.top;
          }
        }

        if (nLeftTopIndex >= 0) {
          CPDFSDK_Annot* pLeftTopAnnot = sa.GetAt(nLeftTopIndex);
          ASSERT(pLeftTopAnnot);

          CPDF_Rect rcLeftTop = GetAnnotRect(pLeftTopAnnot);

          m_Annots.Add(pLeftTopAnnot);
          sa.RemoveAt(nLeftTopIndex);

          CFX_ArrayTemplate<int> aSelect;

          for (int i = 0, sz = sa.GetSize(); i < sz; ++i) {
            CPDFSDK_Annot* pAnnot = sa.GetAt(i);
            ASSERT(pAnnot);

            CPDF_Rect rcAnnot = GetAnnotRect(pAnnot);
            FX_FLOAT fCenterY = (rcAnnot.top + rcAnnot.bottom) / 2.0f;
            if (fCenterY > rcLeftTop.bottom && fCenterY < rcLeftTop.top)
              aSelect.Add(i);
          }

          for (int i = 0, sz = aSelect.GetSize(); i < sz; ++i)
            m_Annots.Add(sa[aSelect[i]]);

          for (int i = aSelect.GetSize() - 1; i >= 0; --i)
              sa.RemoveAt(aSelect[i]);

          aSelect.RemoveAll();
        }
      }
      sa.RemoveAll();
      break;
    }
    case BAI_COLUMN: {
      CPDFSDK_SortAnnots sa;
      for (size_t i = 0; i < m_pPageView->CountAnnots(); ++i) {
        CPDFSDK_Annot* pAnnot = m_pPageView->GetAnnot(i);
        if (pAnnot->GetType() == m_sType && pAnnot->GetSubType() == m_sSubType)
          sa.Add(pAnnot);
      }

      if (sa.GetSize() > 0)
        sa.Sort(CBA_AnnotIterator::CompareByTop, FALSE);

      while (sa.GetSize() > 0) {
        int nLeftTopIndex = -1;
        FX_FLOAT fLeft = -1.0f;

        for (int i = sa.GetSize() - 1; i >= 0; --i) {
          CPDFSDK_Annot* pAnnot = sa.GetAt(i);
          ASSERT(pAnnot);

          CPDF_Rect rcAnnot = GetAnnotRect(pAnnot);

          if (fLeft < 0) {
            nLeftTopIndex = 0;
            fLeft = rcAnnot.left;
          } else if (rcAnnot.left < fLeft) {
            nLeftTopIndex = i;
            fLeft = rcAnnot.left;
          }
        }

        if (nLeftTopIndex >= 0) {
          CPDFSDK_Annot* pLeftTopAnnot = sa.GetAt(nLeftTopIndex);
          ASSERT(pLeftTopAnnot);

          CPDF_Rect rcLeftTop = GetAnnotRect(pLeftTopAnnot);

          m_Annots.Add(pLeftTopAnnot);
          sa.RemoveAt(nLeftTopIndex);

          CFX_ArrayTemplate<int> aSelect;
          for (int i = 0, sz = sa.GetSize(); i < sz; ++i) {
            CPDFSDK_Annot* pAnnot = sa.GetAt(i);
            ASSERT(pAnnot);

            CPDF_Rect rcAnnot = GetAnnotRect(pAnnot);
            FX_FLOAT fCenterX = (rcAnnot.left + rcAnnot.right) / 2.0f;
            if (fCenterX > rcLeftTop.left && fCenterX < rcLeftTop.right)
              aSelect.Add(i);
          }

          for (int i = 0, sz = aSelect.GetSize(); i < sz; ++i)
            m_Annots.Add(sa[aSelect[i]]);

          for (int i = aSelect.GetSize() - 1; i >= 0; --i)
            sa.RemoveAt(aSelect[i]);

          aSelect.RemoveAll();
        }
      }
      sa.RemoveAll();
      break;
    }
  }
}

CPDF_Rect CBA_AnnotIterator::GetAnnotRect(CPDFSDK_Annot* pAnnot) {
  CPDF_Rect rcAnnot;
  pAnnot->GetPDFAnnot()->GetRect(rcAnnot);
  return rcAnnot;
}
