// 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 CPDF_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_AffineMatrix 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);
}

CPDF_Matrix CPDFSDK_Widget::GetMatrix() const {
  CPDF_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 = CPDF_Matrix(1, 0, 0, 1, 0, 0);
      break;
    case 90:
      mt = CPDF_Matrix(0, 1, -1, 0, fWidth, 0);
      break;
    case 180:
      mt = CPDF_Matrix(-1, 0, 0, -1, fWidth, fHeight);
      break;
    case 270:
      mt = CPDF_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;
}
