// 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 "core/fpdfapi/fpdf_page/include/cpdf_page.h"
#include "fpdfsdk/include/formfiller/FFL_CBA_Fontmap.h"
#include "fpdfsdk/include/fsdk_common.h"
#include "fpdfsdk/include/fsdk_mgr.h"
#include "fpdfsdk/include/pdfwindow/PWL_Utils.h"

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

#define FFL_HINT_ELAPSE 800

CFFL_FormFiller::CFFL_FormFiller(CPDFDoc_Environment* pApp,
                                 CPDFSDK_Annot* pAnnot)
    : m_pApp(pApp), m_pAnnot(pAnnot), m_bValid(FALSE), m_ptOldPos(0, 0) {
  m_pWidget = (CPDFSDK_Widget*)pAnnot;
}

CFFL_FormFiller::~CFFL_FormFiller() {
  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.GetOutterRect();
}

void CFFL_FormFiller::OnDraw(CPDFSDK_PageView* pPageView,
                             CPDFSDK_Annot* pAnnot,
                             CFX_RenderDevice* pDevice,
                             CFX_Matrix* pUser2Device,
                             FX_DWORD dwFlags) {
  ASSERT(pAnnot->GetPDFAnnot()->GetSubType() == "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, NULL);
  }
}

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

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,
                                       FX_UINT 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,
                                     FX_UINT nFlags,
                                     const CFX_FloatPoint& point) {
  if (CPWL_Wnd* pWnd = GetPDFWindow(pPageView, FALSE)) {
    FX_RECT rcFFL = GetViewBBox(pPageView, pAnnot);
    InvalidateRect(rcFFL.left, rcFFL.top, rcFFL.right, rcFFL.bottom);
    pWnd->OnLButtonUp(WndtoPWL(pPageView, point), nFlags);
    return TRUE;
  }

  return FALSE;
}

FX_BOOL CFFL_FormFiller::OnLButtonDblClk(CPDFSDK_PageView* pPageView,
                                         CPDFSDK_Annot* pAnnot,
                                         FX_UINT nFlags,
                                         const CFX_FloatPoint& point) {
  if (CPWL_Wnd* pWnd = GetPDFWindow(pPageView, FALSE)) {
    pWnd->OnLButtonDblClk(WndtoPWL(pPageView, point), nFlags);
    return TRUE;
  }

  return FALSE;
}

FX_BOOL CFFL_FormFiller::OnMouseMove(CPDFSDK_PageView* pPageView,
                                     CPDFSDK_Annot* pAnnot,
                                     FX_UINT nFlags,
                                     const CFX_FloatPoint& point) {
  if ((m_ptOldPos.x != point.x) || (m_ptOldPos.y != point.y)) {
    m_ptOldPos = point;
  }

  if (CPWL_Wnd* pWnd = GetPDFWindow(pPageView, FALSE)) {
    pWnd->OnMouseMove(WndtoPWL(pPageView, point), nFlags);
    return TRUE;
  }

  return FALSE;
}

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

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

  return FALSE;
}

FX_BOOL CFFL_FormFiller::OnRButtonDown(CPDFSDK_PageView* pPageView,
                                       CPDFSDK_Annot* pAnnot,
                                       FX_UINT nFlags,
                                       const CFX_FloatPoint& point) {
  if (CPWL_Wnd* pWnd = GetPDFWindow(pPageView, TRUE)) {
    pWnd->OnRButtonDown(WndtoPWL(pPageView, point), nFlags);
    return TRUE;
  }

  return FALSE;
}

FX_BOOL CFFL_FormFiller::OnRButtonUp(CPDFSDK_PageView* pPageView,
                                     CPDFSDK_Annot* pAnnot,
                                     FX_UINT nFlags,
                                     const CFX_FloatPoint& point) {
  if (CPWL_Wnd* pWnd = GetPDFWindow(pPageView, FALSE)) {
    pWnd->OnRButtonUp(WndtoPWL(pPageView, point), nFlags);
    return TRUE;
  }

  return FALSE;
}

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

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

  return FALSE;
}

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

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

  return FALSE;
}

void CFFL_FormFiller::SetFocusForAnnot(CPDFSDK_Annot* pAnnot, FX_UINT nFlag) {
  CPDFSDK_Widget* pWidget = (CPDFSDK_Widget*)pAnnot;
  UnderlyingPageType* pPage = pWidget->GetUnderlyingPage();
  CPDFSDK_Document* pDoc = m_pApp->GetSDKDocument();
  CPDFSDK_PageView* pPageView = pDoc->GetPageView(pPage);
  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, FX_UINT nFlag) {
  if (!IsValid())
    return;

  CPDFSDK_PageView* pPageView = GetCurPageView();
  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 = NULL;
  cp.pProvider = this;
  cp.rcRectWnd = GetPDFWindowRect();

  FX_DWORD dwCreateFlags = PWS_BORDER | PWS_BACKGROUND | PWS_VISIBLE;
  FX_DWORD 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();

  int nBorderStyle = m_pWidget->GetBorderStyle();

  switch (nBorderStyle) {
    case BBS_SOLID:
      cp.nBorderStyle = PBS_SOLID;
      break;
    case BBS_DASH:
      cp.nBorderStyle = PBS_DASH;
      cp.sDash = CPWL_Dash(3, 3, 0);
      break;
    case BBS_BEVELED:
      cp.nBorderStyle = PBS_BEVELED;
      cp.dwBorderWidth *= 2;
      break;
    case BBS_INSET:
      cp.nBorderStyle = PBS_INSET;
      cp.dwBorderWidth *= 2;
      break;
    case BBS_UNDERLINE:
      cp.nBorderStyle = PBS_UNDERLINED;
      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.hAttachedWnd = (FX_HWND)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(rcDA);

  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(rectAnnot);

  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() {
  UnderlyingPageType* pPage = m_pAnnot->GetUnderlyingPage();
  CPDFSDK_Document* pSDKDoc = m_pApp->GetSDKDocument();
  return pSDKDoc ? pSDKDoc->GetPageView(pPage) : 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,
                                    FX_UINT 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->FFI_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() {}

IFX_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->FFI_Invalidate(pPage, left, top, right, bottom);
}

CFFL_Button::CFFL_Button(CPDFDoc_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,
                                   FX_UINT 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,
                                 FX_UINT 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,
                                 FX_UINT 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,
                         FX_DWORD dwFlags) {
  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, NULL);
    return;
  }

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

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