// 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/formfiller/cffl_formfiller.h"

#include "core/fpdfapi/fpdf_page/include/cpdf_page.h"
#include "core/fxge/include/cfx_renderdevice.h"
#include "fpdfsdk/formfiller/cba_fontmap.h"
#include "fpdfsdk/include/cpdfsdk_document.h"
#include "fpdfsdk/include/cpdfsdk_environment.h"
#include "fpdfsdk/include/cpdfsdk_pageview.h"
#include "fpdfsdk/include/cpdfsdk_widget.h"
#include "fpdfsdk/include/fsdk_common.h"
#include "fpdfsdk/pdfwindow/PWL_Utils.h"

#define GetRed(rgb) ((uint8_t)(rgb))
#define GetGreen(rgb) ((uint8_t)(((uint16_t)(rgb)) >> 8))
#define GetBlue(rgb) ((uint8_t)((rgb) >> 16))

#define FFL_HINT_ELAPSE 800

CFFL_FormFiller::CFFL_FormFiller(CPDFSDK_Environment* pApp,
                                 CPDFSDK_Annot* pAnnot)
    : m_pApp(pApp), m_pAnnot(pAnnot), m_bValid(FALSE) {
  m_pWidget = static_cast<CPDFSDK_Widget*>(pAnnot);
}

CFFL_FormFiller::~CFFL_FormFiller() {
  DestroyWindows();
}

void CFFL_FormFiller::DestroyWindows() {
  for (const auto& it : m_Maps) {
    CPWL_Wnd* pWnd = it.second;
    CFFL_PrivateData* pData = (CFFL_PrivateData*)pWnd->GetAttachedData();
    pWnd->InvalidateProvider(this);
    pWnd->Destroy();
    delete pWnd;
    delete pData;
  }
  m_Maps.clear();
}

void CFFL_FormFiller::SetWindowRect(CPDFSDK_PageView* pPageView,
                                    const CFX_FloatRect& rcWindow) {
  if (CPWL_Wnd* pWnd = GetPDFWindow(pPageView, FALSE)) {
    pWnd->Move(CFX_FloatRect(rcWindow), TRUE, FALSE);
  }
}

CFX_FloatRect CFFL_FormFiller::GetWindowRect(CPDFSDK_PageView* pPageView) {
  if (CPWL_Wnd* pWnd = GetPDFWindow(pPageView, FALSE)) {
    return pWnd->GetWindowRect();
  }

  return CFX_FloatRect(0, 0, 0, 0);
}

FX_RECT CFFL_FormFiller::GetViewBBox(CPDFSDK_PageView* pPageView,
                                     CPDFSDK_Annot* pAnnot) {
  ASSERT(pPageView);
  ASSERT(pAnnot);

  CFX_FloatRect rcAnnot = m_pWidget->GetRect();

  if (CPWL_Wnd* pWnd = GetPDFWindow(pPageView, FALSE)) {
    CFX_FloatRect rcWindow = pWnd->GetWindowRect();
    rcAnnot = PWLtoFFL(rcWindow);
  }

  CFX_FloatRect rcWin = rcAnnot;

  CFX_FloatRect rcFocus = GetFocusBox(pPageView);
  if (!rcFocus.IsEmpty())
    rcWin.Union(rcFocus);

  CFX_FloatRect rect = CPWL_Utils::InflateRect(rcWin, 1);

  return rect.GetOuterRect();
}

void CFFL_FormFiller::OnDraw(CPDFSDK_PageView* pPageView,
                             CPDFSDK_Annot* pAnnot,
                             CFX_RenderDevice* pDevice,
                             CFX_Matrix* pUser2Device) {
  ASSERT(pAnnot->GetPDFAnnot()->GetSubtype() == CPDF_Annot::Subtype::WIDGET);

  if (CPWL_Wnd* pWnd = GetPDFWindow(pPageView, FALSE)) {
    CFX_Matrix mt = GetCurMatrix();
    mt.Concat(*pUser2Device);
    pWnd->DrawAppearance(pDevice, &mt);
  } else {
    CPDFSDK_Widget* pWidget = (CPDFSDK_Widget*)pAnnot;
    if (CFFL_IFormFiller::IsVisible(pWidget))
      pWidget->DrawAppearance(pDevice, pUser2Device, CPDF_Annot::Normal,
                              nullptr);
  }
}

void CFFL_FormFiller::OnDrawDeactive(CPDFSDK_PageView* pPageView,
                                     CPDFSDK_Annot* pAnnot,
                                     CFX_RenderDevice* pDevice,
                                     CFX_Matrix* pUser2Device) {
  CPDFSDK_Widget* pWidget = (CPDFSDK_Widget*)pAnnot;
  pWidget->DrawAppearance(pDevice, pUser2Device, CPDF_Annot::Normal, nullptr);
}

void CFFL_FormFiller::OnCreate(CPDFSDK_Annot* pAnnot) {}

void CFFL_FormFiller::OnLoad(CPDFSDK_Annot* pAnnot) {}

void CFFL_FormFiller::OnDelete(CPDFSDK_Annot* pAnnot) {}

void CFFL_FormFiller::OnMouseEnter(CPDFSDK_PageView* pPageView,
                                   CPDFSDK_Annot* pAnnot) {}

void CFFL_FormFiller::OnMouseExit(CPDFSDK_PageView* pPageView,
                                  CPDFSDK_Annot* pAnnot) {
  EndTimer();
  ASSERT(m_pWidget);
}

FX_BOOL CFFL_FormFiller::OnLButtonDown(CPDFSDK_PageView* pPageView,
                                       CPDFSDK_Annot* pAnnot,
                                       uint32_t nFlags,
                                       const CFX_FloatPoint& point) {
  if (CPWL_Wnd* pWnd = GetPDFWindow(pPageView, TRUE)) {
    m_bValid = TRUE;
    FX_RECT rect = GetViewBBox(pPageView, pAnnot);
    InvalidateRect(rect.left, rect.top, rect.right, rect.bottom);

    if (!rect.Contains((int)point.x, (int)point.y))
      return FALSE;

    return pWnd->OnLButtonDown(WndtoPWL(pPageView, point), nFlags);
  }

  return FALSE;
}

FX_BOOL CFFL_FormFiller::OnLButtonUp(CPDFSDK_PageView* pPageView,
                                     CPDFSDK_Annot* pAnnot,
                                     uint32_t nFlags,
                                     const CFX_FloatPoint& point) {
  CPWL_Wnd* pWnd = GetPDFWindow(pPageView, FALSE);
  if (!pWnd)
    return FALSE;

  FX_RECT rcFFL = GetViewBBox(pPageView, pAnnot);
  InvalidateRect(rcFFL.left, rcFFL.top, rcFFL.right, rcFFL.bottom);
  pWnd->OnLButtonUp(WndtoPWL(pPageView, point), nFlags);
  return TRUE;
}

FX_BOOL CFFL_FormFiller::OnLButtonDblClk(CPDFSDK_PageView* pPageView,
                                         CPDFSDK_Annot* pAnnot,
                                         uint32_t nFlags,
                                         const CFX_FloatPoint& point) {
  CPWL_Wnd* pWnd = GetPDFWindow(pPageView, FALSE);
  if (!pWnd)
    return FALSE;

  pWnd->OnLButtonDblClk(WndtoPWL(pPageView, point), nFlags);
  return TRUE;
}

FX_BOOL CFFL_FormFiller::OnMouseMove(CPDFSDK_PageView* pPageView,
                                     CPDFSDK_Annot* pAnnot,
                                     uint32_t nFlags,
                                     const CFX_FloatPoint& point) {
  if (m_ptOldPos != point)
    m_ptOldPos = point;

  CPWL_Wnd* pWnd = GetPDFWindow(pPageView, FALSE);
  if (!pWnd)
    return FALSE;

  pWnd->OnMouseMove(WndtoPWL(pPageView, point), nFlags);
  return TRUE;
}

FX_BOOL CFFL_FormFiller::OnMouseWheel(CPDFSDK_PageView* pPageView,
                                      CPDFSDK_Annot* pAnnot,
                                      uint32_t nFlags,
                                      short zDelta,
                                      const CFX_FloatPoint& point) {
  if (!IsValid())
    return FALSE;

  CPWL_Wnd* pWnd = GetPDFWindow(pPageView, TRUE);
  return pWnd && pWnd->OnMouseWheel(zDelta, WndtoPWL(pPageView, point), nFlags);
}

FX_BOOL CFFL_FormFiller::OnRButtonDown(CPDFSDK_PageView* pPageView,
                                       CPDFSDK_Annot* pAnnot,
                                       uint32_t nFlags,
                                       const CFX_FloatPoint& point) {
  CPWL_Wnd* pWnd = GetPDFWindow(pPageView, TRUE);
  if (!pWnd)
    return FALSE;

  pWnd->OnRButtonDown(WndtoPWL(pPageView, point), nFlags);
  return TRUE;
}

FX_BOOL CFFL_FormFiller::OnRButtonUp(CPDFSDK_PageView* pPageView,
                                     CPDFSDK_Annot* pAnnot,
                                     uint32_t nFlags,
                                     const CFX_FloatPoint& point) {
  CPWL_Wnd* pWnd = GetPDFWindow(pPageView, FALSE);
  if (!pWnd)
    return FALSE;

  pWnd->OnRButtonUp(WndtoPWL(pPageView, point), nFlags);
  return TRUE;
}

FX_BOOL CFFL_FormFiller::OnKeyDown(CPDFSDK_Annot* pAnnot,
                                   uint32_t nKeyCode,
                                   uint32_t nFlags) {
  if (IsValid()) {
    CPDFSDK_PageView* pPageView = GetCurPageView(true);
    ASSERT(pPageView);

    if (CPWL_Wnd* pWnd = GetPDFWindow(pPageView, FALSE)) {
      return pWnd->OnKeyDown(nKeyCode, nFlags);
    }
  }

  return FALSE;
}

FX_BOOL CFFL_FormFiller::OnChar(CPDFSDK_Annot* pAnnot,
                                uint32_t nChar,
                                uint32_t nFlags) {
  if (IsValid()) {
    CPDFSDK_PageView* pPageView = GetCurPageView(true);
    ASSERT(pPageView);

    if (CPWL_Wnd* pWnd = GetPDFWindow(pPageView, FALSE)) {
      return pWnd->OnChar(nChar, nFlags);
    }
  }

  return FALSE;
}

void CFFL_FormFiller::SetFocusForAnnot(CPDFSDK_Annot* pAnnot, uint32_t nFlag) {
  CPDFSDK_Widget* pWidget = (CPDFSDK_Widget*)pAnnot;
  UnderlyingPageType* pPage = pWidget->GetUnderlyingPage();
  CPDFSDK_Document* pDoc = m_pApp->GetSDKDocument();
  CPDFSDK_PageView* pPageView = pDoc->GetPageView(pPage, true);
  if (CPWL_Wnd* pWnd = GetPDFWindow(pPageView, TRUE))
    pWnd->SetFocus();

  m_bValid = TRUE;
  FX_RECT rcRect = GetViewBBox(pPageView, pAnnot);
  InvalidateRect(rcRect.left, rcRect.top, rcRect.right, rcRect.bottom);
}

void CFFL_FormFiller::KillFocusForAnnot(CPDFSDK_Annot* pAnnot, uint32_t nFlag) {
  if (!IsValid())
    return;

  CPDFSDK_PageView* pPageView = GetCurPageView(false);
  if (!pPageView)
    return;

  CommitData(pPageView, nFlag);

  if (CPWL_Wnd* pWnd = GetPDFWindow(pPageView, FALSE))
    pWnd->KillFocus();

  FX_BOOL bDestroyPDFWindow;
  switch (m_pWidget->GetFieldType()) {
    case FIELDTYPE_PUSHBUTTON:
    case FIELDTYPE_CHECKBOX:
    case FIELDTYPE_RADIOBUTTON:
      bDestroyPDFWindow = TRUE;
      break;
    default:
      bDestroyPDFWindow = FALSE;
      break;
  }
  EscapeFiller(pPageView, bDestroyPDFWindow);
}

FX_BOOL CFFL_FormFiller::IsValid() const {
  return m_bValid;
}

PWL_CREATEPARAM CFFL_FormFiller::GetCreateParam() {
  ASSERT(m_pApp);

  PWL_CREATEPARAM cp;
  cp.pParentWnd = nullptr;
  cp.pProvider = this;
  cp.rcRectWnd = GetPDFWindowRect();

  uint32_t dwCreateFlags = PWS_BORDER | PWS_BACKGROUND | PWS_VISIBLE;
  uint32_t dwFieldFlag = m_pWidget->GetFieldFlags();
  if (dwFieldFlag & FIELDFLAG_READONLY) {
    dwCreateFlags |= PWS_READONLY;
  }

  FX_COLORREF color;
  if (m_pWidget->GetFillColor(color)) {
    cp.sBackgroundColor =
        CPWL_Color(GetRed(color), GetGreen(color), GetBlue(color));
  }

  if (m_pWidget->GetBorderColor(color)) {
    cp.sBorderColor =
        CPWL_Color(GetRed(color), GetGreen(color), GetBlue(color));
  }

  cp.sTextColor = CPWL_Color(COLORTYPE_GRAY, 0);

  if (m_pWidget->GetTextColor(color)) {
    cp.sTextColor = CPWL_Color(GetRed(color), GetGreen(color), GetBlue(color));
  }

  cp.fFontSize = m_pWidget->GetFontSize();
  cp.dwBorderWidth = m_pWidget->GetBorderWidth();

  cp.nBorderStyle = m_pWidget->GetBorderStyle();
  switch (cp.nBorderStyle) {
    case BorderStyle::DASH:
      cp.sDash = CPWL_Dash(3, 3, 0);
      break;
    case BorderStyle::BEVELED:
      cp.dwBorderWidth *= 2;
      break;
    case BorderStyle::INSET:
      cp.dwBorderWidth *= 2;
      break;
    default:
      break;
  }

  if (cp.fFontSize <= 0)
    dwCreateFlags |= PWS_AUTOFONTSIZE;

  cp.dwFlags = dwCreateFlags;
  cp.pSystemHandler = m_pApp->GetSysHandler();
  return cp;
}

CPWL_Wnd* CFFL_FormFiller::GetPDFWindow(CPDFSDK_PageView* pPageView,
                                        FX_BOOL bNew) {
  ASSERT(pPageView);

  auto it = m_Maps.find(pPageView);
  const bool found = it != m_Maps.end();
  CPWL_Wnd* pWnd = found ? it->second : nullptr;
  if (!bNew)
    return pWnd;

  if (found) {
    CFFL_PrivateData* pPrivateData = (CFFL_PrivateData*)pWnd->GetAttachedData();
    if (pPrivateData->nWidgetAge != m_pWidget->GetAppearanceAge()) {
      return ResetPDFWindow(
          pPageView, m_pWidget->GetValueAge() == pPrivateData->nValueAge);
    }
  } else {
    PWL_CREATEPARAM cp = GetCreateParam();
    cp.pAttachedWidget = m_pWidget;

    CFFL_PrivateData* pPrivateData = new CFFL_PrivateData;
    pPrivateData->pWidget = m_pWidget;
    pPrivateData->pPageView = pPageView;
    pPrivateData->nWidgetAge = m_pWidget->GetAppearanceAge();
    pPrivateData->nValueAge = 0;

    cp.pAttachedData = pPrivateData;

    pWnd = NewPDFWindow(cp, pPageView);
    m_Maps[pPageView] = pWnd;
  }

  return pWnd;
}

void CFFL_FormFiller::DestroyPDFWindow(CPDFSDK_PageView* pPageView) {
  auto it = m_Maps.find(pPageView);
  if (it == m_Maps.end())
    return;

  CPWL_Wnd* pWnd = it->second;
  CFFL_PrivateData* pData = (CFFL_PrivateData*)pWnd->GetAttachedData();
  pWnd->Destroy();
  delete pWnd;
  delete pData;

  m_Maps.erase(it);
}

CFX_Matrix CFFL_FormFiller::GetWindowMatrix(void* pAttachedData) {
  if (CFFL_PrivateData* pPrivateData = (CFFL_PrivateData*)pAttachedData) {
    if (pPrivateData->pPageView) {
      CFX_Matrix mtPageView;
      pPrivateData->pPageView->GetCurrentMatrix(mtPageView);
      CFX_Matrix mt = GetCurMatrix();
      mt.Concat(mtPageView);

      return mt;
    }
  }
  return CFX_Matrix(1, 0, 0, 1, 0, 0);
}

CFX_Matrix CFFL_FormFiller::GetCurMatrix() {
  CFX_Matrix mt;

  CFX_FloatRect rcDA = m_pWidget->GetPDFAnnot()->GetRect();

  switch (m_pWidget->GetRotate()) {
    default:
    case 0:
      mt = CFX_Matrix(1, 0, 0, 1, 0, 0);
      break;
    case 90:
      mt = CFX_Matrix(0, 1, -1, 0, rcDA.right - rcDA.left, 0);
      break;
    case 180:
      mt = CFX_Matrix(-1, 0, 0, -1, rcDA.right - rcDA.left,
                      rcDA.top - rcDA.bottom);
      break;
    case 270:
      mt = CFX_Matrix(0, -1, 1, 0, 0, rcDA.top - rcDA.bottom);
      break;
  }
  mt.e += rcDA.left;
  mt.f += rcDA.bottom;

  return mt;
}

CFX_WideString CFFL_FormFiller::LoadPopupMenuString(int nIndex) {
  ASSERT(m_pApp);

  return L"";
}

CFX_FloatRect CFFL_FormFiller::GetPDFWindowRect() const {
  CFX_FloatRect rectAnnot = m_pWidget->GetPDFAnnot()->GetRect();

  FX_FLOAT fWidth = rectAnnot.right - rectAnnot.left;
  FX_FLOAT fHeight = rectAnnot.top - rectAnnot.bottom;
  if ((m_pWidget->GetRotate() / 90) & 0x01)
    return CFX_FloatRect(0, 0, fHeight, fWidth);

  return CFX_FloatRect(0, 0, fWidth, fHeight);
}

CPDFSDK_PageView* CFFL_FormFiller::GetCurPageView(bool renew) {
  UnderlyingPageType* pPage = m_pAnnot->GetUnderlyingPage();
  CPDFSDK_Document* pSDKDoc = m_pApp->GetSDKDocument();
  return pSDKDoc ? pSDKDoc->GetPageView(pPage, renew) : nullptr;
}

CFX_FloatRect CFFL_FormFiller::GetFocusBox(CPDFSDK_PageView* pPageView) {
  if (CPWL_Wnd* pWnd = GetPDFWindow(pPageView, FALSE)) {
    CFX_FloatRect rcFocus = FFLtoWnd(pPageView, PWLtoFFL(pWnd->GetFocusRect()));
    CFX_FloatRect rcPage = pPageView->GetPDFPage()->GetPageBBox();
    if (rcPage.Contains(rcFocus))
      return rcFocus;
  }
  return CFX_FloatRect(0, 0, 0, 0);
}

CFX_FloatRect CFFL_FormFiller::FFLtoPWL(const CFX_FloatRect& rect) {
  CFX_Matrix mt;
  mt.SetReverse(GetCurMatrix());

  CFX_FloatRect temp = rect;
  mt.TransformRect(temp);

  return temp;
}

CFX_FloatRect CFFL_FormFiller::PWLtoFFL(const CFX_FloatRect& rect) {
  CFX_Matrix mt = GetCurMatrix();

  CFX_FloatRect temp = rect;
  mt.TransformRect(temp);

  return temp;
}

CFX_FloatPoint CFFL_FormFiller::FFLtoPWL(const CFX_FloatPoint& point) {
  CFX_Matrix mt;
  mt.SetReverse(GetCurMatrix());

  CFX_FloatPoint pt = point;
  mt.Transform(pt.x, pt.y);

  return pt;
}

CFX_FloatPoint CFFL_FormFiller::PWLtoFFL(const CFX_FloatPoint& point) {
  CFX_Matrix mt = GetCurMatrix();

  CFX_FloatPoint pt = point;
  mt.Transform(pt.x, pt.y);

  return pt;
}

CFX_FloatPoint CFFL_FormFiller::WndtoPWL(CPDFSDK_PageView* pPageView,
                                         const CFX_FloatPoint& pt) {
  return FFLtoPWL(pt);
}

CFX_FloatRect CFFL_FormFiller::FFLtoWnd(CPDFSDK_PageView* pPageView,
                                        const CFX_FloatRect& rect) {
  return rect;
}

FX_BOOL CFFL_FormFiller::CommitData(CPDFSDK_PageView* pPageView,
                                    uint32_t nFlag) {
  if (IsDataChanged(pPageView)) {
    FX_BOOL bRC = TRUE;
    FX_BOOL bExit = FALSE;
    CFFL_IFormFiller* pIFormFiller = m_pApp->GetIFormFiller();
    pIFormFiller->OnKeyStrokeCommit(m_pWidget, pPageView, bRC, bExit, nFlag);
    if (bExit)
      return TRUE;
    if (!bRC) {
      ResetPDFWindow(pPageView, FALSE);
      return TRUE;
    }

    pIFormFiller->OnValidate(m_pWidget, pPageView, bRC, bExit, nFlag);
    if (bExit)
      return TRUE;
    if (!bRC) {
      ResetPDFWindow(pPageView, FALSE);
      return TRUE;
    }

    SaveData(pPageView);
    pIFormFiller->OnCalculate(m_pWidget, pPageView, bExit, nFlag);
    if (bExit)
      return TRUE;

    pIFormFiller->OnFormat(m_pWidget, pPageView, bExit, nFlag);
  }
  return TRUE;
}

FX_BOOL CFFL_FormFiller::IsDataChanged(CPDFSDK_PageView* pPageView) {
  return FALSE;
}

void CFFL_FormFiller::SaveData(CPDFSDK_PageView* pPageView) {}

#ifdef PDF_ENABLE_XFA
FX_BOOL CFFL_FormFiller::IsFieldFull(CPDFSDK_PageView* pPageView) {
  return FALSE;
}
#endif  // PDF_ENABLE_XFA

void CFFL_FormFiller::SetChangeMark() {
  m_pApp->OnChange();
}

void CFFL_FormFiller::GetActionData(CPDFSDK_PageView* pPageView,
                                    CPDF_AAction::AActionType type,
                                    PDFSDK_FieldAction& fa) {
  fa.sValue = m_pWidget->GetValue();
}

void CFFL_FormFiller::SetActionData(CPDFSDK_PageView* pPageView,
                                    CPDF_AAction::AActionType type,
                                    const PDFSDK_FieldAction& fa) {}

FX_BOOL CFFL_FormFiller::IsActionDataChanged(CPDF_AAction::AActionType type,
                                             const PDFSDK_FieldAction& faOld,
                                             const PDFSDK_FieldAction& faNew) {
  return FALSE;
}

void CFFL_FormFiller::SaveState(CPDFSDK_PageView* pPageView) {}

void CFFL_FormFiller::RestoreState(CPDFSDK_PageView* pPageView) {}

CPWL_Wnd* CFFL_FormFiller::ResetPDFWindow(CPDFSDK_PageView* pPageView,
                                          FX_BOOL bRestoreValue) {
  return GetPDFWindow(pPageView, FALSE);
}

void CFFL_FormFiller::TimerProc() {}

CFX_SystemHandler* CFFL_FormFiller::GetSystemHandler() const {
  return m_pApp->GetSysHandler();
}

void CFFL_FormFiller::EscapeFiller(CPDFSDK_PageView* pPageView,
                                   FX_BOOL bDestroyPDFWindow) {
  m_bValid = FALSE;

  FX_RECT rcRect = GetViewBBox(pPageView, m_pWidget);
  InvalidateRect(rcRect.left, rcRect.top, rcRect.right, rcRect.bottom);

  if (bDestroyPDFWindow)
    DestroyPDFWindow(pPageView);
}

void CFFL_FormFiller::InvalidateRect(double left,
                                     double top,
                                     double right,
                                     double bottom) {
  UnderlyingPageType* pPage = m_pWidget->GetUnderlyingPage();
  m_pApp->Invalidate(pPage, left, top, right, bottom);
}

CFFL_Button::CFFL_Button(CPDFSDK_Environment* pApp, CPDFSDK_Annot* pWidget)
    : CFFL_FormFiller(pApp, pWidget), m_bMouseIn(FALSE), m_bMouseDown(FALSE) {}

CFFL_Button::~CFFL_Button() {}

void CFFL_Button::OnMouseEnter(CPDFSDK_PageView* pPageView,
                               CPDFSDK_Annot* pAnnot) {
  m_bMouseIn = TRUE;
  FX_RECT rect = GetViewBBox(pPageView, pAnnot);
  InvalidateRect(rect.left, rect.top, rect.right, rect.bottom);
}

void CFFL_Button::OnMouseExit(CPDFSDK_PageView* pPageView,
                              CPDFSDK_Annot* pAnnot) {
  m_bMouseIn = FALSE;

  FX_RECT rect = GetViewBBox(pPageView, pAnnot);
  InvalidateRect(rect.left, rect.top, rect.right, rect.bottom);
  EndTimer();
  ASSERT(m_pWidget);
}

FX_BOOL CFFL_Button::OnLButtonDown(CPDFSDK_PageView* pPageView,
                                   CPDFSDK_Annot* pAnnot,
                                   uint32_t nFlags,
                                   const CFX_FloatPoint& point) {
  CFX_FloatRect rcAnnot = pAnnot->GetRect();
  if (!rcAnnot.Contains(point.x, point.y))
    return FALSE;

  m_bMouseDown = TRUE;
  m_bValid = TRUE;
  FX_RECT rect = GetViewBBox(pPageView, pAnnot);
  InvalidateRect(rect.left, rect.top, rect.right, rect.bottom);
  return TRUE;
}

FX_BOOL CFFL_Button::OnLButtonUp(CPDFSDK_PageView* pPageView,
                                 CPDFSDK_Annot* pAnnot,
                                 uint32_t nFlags,
                                 const CFX_FloatPoint& point) {
  CFX_FloatRect rcAnnot = pAnnot->GetRect();
  if (!rcAnnot.Contains(point.x, point.y))
    return FALSE;

  m_bMouseDown = FALSE;
  m_pWidget->GetPDFPage();

  FX_RECT rect = GetViewBBox(pPageView, pAnnot);
  InvalidateRect(rect.left, rect.top, rect.right, rect.bottom);
  return TRUE;
}

FX_BOOL CFFL_Button::OnMouseMove(CPDFSDK_PageView* pPageView,
                                 CPDFSDK_Annot* pAnnot,
                                 uint32_t nFlags,
                                 const CFX_FloatPoint& point) {
  ASSERT(m_pApp);

  return TRUE;
}

void CFFL_Button::OnDraw(CPDFSDK_PageView* pPageView,
                         CPDFSDK_Annot* pAnnot,
                         CFX_RenderDevice* pDevice,
                         CFX_Matrix* pUser2Device) {
  ASSERT(pPageView);
  CPDFSDK_Widget* pWidget = (CPDFSDK_Widget*)pAnnot;
  CPDF_FormControl* pCtrl = pWidget->GetFormControl();
  CPDF_FormControl::HighlightingMode eHM = pCtrl->GetHighlightingMode();

  if (eHM != CPDF_FormControl::Push) {
    pWidget->DrawAppearance(pDevice, pUser2Device, CPDF_Annot::Normal, nullptr);
    return;
  }

  if (m_bMouseDown) {
    if (pWidget->IsWidgetAppearanceValid(CPDF_Annot::Down))
      pWidget->DrawAppearance(pDevice, pUser2Device, CPDF_Annot::Down, nullptr);
    else
      pWidget->DrawAppearance(pDevice, pUser2Device, CPDF_Annot::Normal,
                              nullptr);
  } else if (m_bMouseIn) {
    if (pWidget->IsWidgetAppearanceValid(CPDF_Annot::Rollover))
      pWidget->DrawAppearance(pDevice, pUser2Device, CPDF_Annot::Rollover,
                              nullptr);
    else
      pWidget->DrawAppearance(pDevice, pUser2Device, CPDF_Annot::Normal,
                              nullptr);
  } else {
    pWidget->DrawAppearance(pDevice, pUser2Device, CPDF_Annot::Normal, nullptr);
  }
}

void CFFL_Button::OnDrawDeactive(CPDFSDK_PageView* pPageView,
                                 CPDFSDK_Annot* pAnnot,
                                 CFX_RenderDevice* pDevice,
                                 CFX_Matrix* pUser2Device) {
  OnDraw(pPageView, pAnnot, pDevice, pUser2Device);
}
