// 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

#ifndef FPDFSDK_INCLUDE_FSDK_MGR_H_
#define FPDFSDK_INCLUDE_FSDK_MGR_H_

#include <map>

#include "../../core/include/fpdftext/fpdf_text.h"
#include "../../public/fpdf_formfill.h"
#include "../../public/fpdf_fwlevent.h"  // cross platform keycode and events define.
#include "fsdk_common.h"
#include "fsdk_define.h"
#include "fx_systemhandler.h"
#include "fsdk_baseannot.h"
#include "fsdk_baseform.h"
#include "fsdk_annothandler.h"
#include "fsdk_actionhandler.h"
#include "javascript/IJavaScript.h"

class CFFL_IFormFiller;
class CJS_RuntimeFactory;
class CPDFSDK_ActionHandler;
class CPDFSDK_Annot;
class CPDFSDK_Document;
class CPDFSDK_InterForm;
class CPDFSDK_PageView;
class CPDFSDK_Widget;
class IFX_SystemHandler;

class CPDFDoc_Environment final {
 public:
  CPDFDoc_Environment(CPDF_Document* pDoc, FPDF_FORMFILLINFO* pFFinfo);
  ~CPDFDoc_Environment();

  void FFI_Invalidate(FPDF_PAGE page,
                      double left,
                      double top,
                      double right,
                      double bottom) {
    if (m_pInfo && m_pInfo->FFI_Invalidate)
      m_pInfo->FFI_Invalidate(m_pInfo, page, left, top, right, bottom);
  }

  void FFI_OutputSelectedRect(FPDF_PAGE page,
                              double left,
                              double top,
                              double right,
                              double bottom) {
    if (m_pInfo && m_pInfo->FFI_OutputSelectedRect)
      m_pInfo->FFI_OutputSelectedRect(m_pInfo, page, left, top, right, bottom);
  }

  void FFI_SetCursor(int nCursorType) {
    if (m_pInfo && m_pInfo->FFI_SetCursor)
      m_pInfo->FFI_SetCursor(m_pInfo, nCursorType);
  }

  int FFI_SetTimer(int uElapse, TimerCallback lpTimerFunc) {
    if (m_pInfo && m_pInfo->FFI_SetTimer)
      return m_pInfo->FFI_SetTimer(m_pInfo, uElapse, lpTimerFunc);
    return -1;
  }

  void FFI_KillTimer(int nTimerID) {
    if (m_pInfo && m_pInfo->FFI_KillTimer)
      m_pInfo->FFI_KillTimer(m_pInfo, nTimerID);
  }

  FX_SYSTEMTIME FFI_GetLocalTime() const {
    FX_SYSTEMTIME fxtime;
    if (m_pInfo && m_pInfo->FFI_GetLocalTime) {
      FPDF_SYSTEMTIME systime = m_pInfo->FFI_GetLocalTime(m_pInfo);
      fxtime.wDay = systime.wDay;
      fxtime.wDayOfWeek = systime.wDayOfWeek;
      fxtime.wHour = systime.wHour;
      fxtime.wMilliseconds = systime.wMilliseconds;
      fxtime.wMinute = systime.wMinute;
      fxtime.wMonth = systime.wMonth;
      fxtime.wSecond = systime.wSecond;
      fxtime.wYear = systime.wYear;
    }
    return fxtime;
  }

  void FFI_OnChange() {
    if (m_pInfo && m_pInfo->FFI_OnChange)
      m_pInfo->FFI_OnChange(m_pInfo);
  }

  FX_BOOL FFI_IsSHIFTKeyDown(FX_DWORD nFlag) const {
    return (nFlag & FWL_EVENTFLAG_ShiftKey) != 0;
  }

  FX_BOOL FFI_IsCTRLKeyDown(FX_DWORD nFlag) const {
    return (nFlag & FWL_EVENTFLAG_ControlKey) != 0;
  }

  FX_BOOL FFI_IsALTKeyDown(FX_DWORD nFlag) const {
    return (nFlag & FWL_EVENTFLAG_AltKey) != 0;
  }

  FX_BOOL FFI_IsINSERTKeyDown(FX_DWORD nFlag) const { return FALSE; }

  int JS_appAlert(const FX_WCHAR* Msg,
                  const FX_WCHAR* Title,
                  FX_UINT Type,
                  FX_UINT Icon);
  int JS_appResponse(const FX_WCHAR* Question,
                     const FX_WCHAR* Title,
                     const FX_WCHAR* Default,
                     const FX_WCHAR* cLabel,
                     FPDF_BOOL bPassword,
                     void* response,
                     int length);

  void JS_appBeep(int nType) {
    if (m_pInfo && m_pInfo->m_pJsPlatform && m_pInfo->m_pJsPlatform->app_beep)
      m_pInfo->m_pJsPlatform->app_beep(m_pInfo->m_pJsPlatform, nType);
  }

  CFX_WideString JS_fieldBrowse();
  CFX_WideString JS_docGetFilePath();

  void JS_docSubmitForm(void* formData, int length, const FX_WCHAR* URL);
  void JS_docmailForm(void* mailData,
                      int length,
                      FPDF_BOOL bUI,
                      const FX_WCHAR* To,
                      const FX_WCHAR* Subject,
                      const FX_WCHAR* CC,
                      const FX_WCHAR* BCC,
                      const FX_WCHAR* Msg);

  void JS_docprint(FPDF_BOOL bUI,
                   int nStart,
                   int nEnd,
                   FPDF_BOOL bSilent,
                   FPDF_BOOL bShrinkToFit,
                   FPDF_BOOL bPrintAsImage,
                   FPDF_BOOL bReverse,
                   FPDF_BOOL bAnnotations) {
    if (m_pInfo && m_pInfo->m_pJsPlatform && m_pInfo->m_pJsPlatform->Doc_print)
      m_pInfo->m_pJsPlatform->Doc_print(m_pInfo->m_pJsPlatform, bUI, nStart,
                                        nEnd, bSilent, bShrinkToFit,
                                        bPrintAsImage, bReverse, bAnnotations);
  }

  void JS_docgotoPage(int nPageNum) {
    if (m_pInfo && m_pInfo->m_pJsPlatform &&
        m_pInfo->m_pJsPlatform->Doc_gotoPage)
      m_pInfo->m_pJsPlatform->Doc_gotoPage(m_pInfo->m_pJsPlatform, nPageNum);
  }

  FPDF_PAGE FFI_GetPage(FPDF_DOCUMENT document, int nPageIndex) {
    if (m_pInfo && m_pInfo->FFI_GetPage)
      return m_pInfo->FFI_GetPage(m_pInfo, document, nPageIndex);
    return NULL;
  }

  FPDF_PAGE FFI_GetCurrentPage(FPDF_DOCUMENT document) {
    if (m_pInfo && m_pInfo->FFI_GetCurrentPage)
      return m_pInfo->FFI_GetCurrentPage(m_pInfo, document);
    return NULL;
  }

  int FFI_GetRotation(FPDF_PAGE page) {
    if (m_pInfo && m_pInfo->FFI_GetRotation)
      return m_pInfo->FFI_GetRotation(m_pInfo, page);
    return 0;
  }

  void FFI_ExecuteNamedAction(const FX_CHAR* namedAction) {
    if (m_pInfo && m_pInfo->FFI_ExecuteNamedAction)
      m_pInfo->FFI_ExecuteNamedAction(m_pInfo, namedAction);
  }

  void FFI_OnSetFieldInputFocus(void* field,
                                FPDF_WIDESTRING focusText,
                                FPDF_DWORD nTextLen,
                                FX_BOOL bFocus) {
    if (m_pInfo && m_pInfo->FFI_SetTextFieldFocus)
      m_pInfo->FFI_SetTextFieldFocus(m_pInfo, focusText, nTextLen, bFocus);
  }

  void FFI_DoURIAction(const FX_CHAR* bsURI) {
    if (m_pInfo && m_pInfo->FFI_DoURIAction)
      m_pInfo->FFI_DoURIAction(m_pInfo, bsURI);
  }

  void FFI_DoGoToAction(int nPageIndex,
                        int zoomMode,
                        float* fPosArray,
                        int sizeOfArray) {
    if (m_pInfo && m_pInfo->FFI_DoGoToAction)
      m_pInfo->FFI_DoGoToAction(m_pInfo, nPageIndex, zoomMode, fPosArray,
                                sizeOfArray);
  }

  FX_BOOL IsJSInitiated() const { return m_pInfo && m_pInfo->m_pJsPlatform; }
  void SetSDKDocument(CPDFSDK_Document* pFXDoc) { m_pSDKDoc = pFXDoc; }
  CPDFSDK_Document* GetSDKDocument() const { return m_pSDKDoc; }
  CPDF_Document* GetPDFDocument() const { return m_pPDFDoc; }
  CFX_ByteString GetAppName() const { return ""; }
  IFX_SystemHandler* GetSysHandler() const { return m_pSysHandler; }
  FPDF_FORMFILLINFO* GetFormFillInfo() const { return m_pInfo; }
  CJS_RuntimeFactory* GetRuntimeFactory() const { return m_pJSRuntimeFactory; }

  CFFL_IFormFiller* GetIFormFiller();             // Creates if not present.
  CPDFSDK_AnnotHandlerMgr* GetAnnotHandlerMgr();  // Creates if not present.
  IFXJS_Runtime* GetJSRuntime();                  // Creates if not present.
  CPDFSDK_ActionHandler* GetActionHander();       // Creates if not present.

 private:
  CPDFSDK_AnnotHandlerMgr* m_pAnnotHandlerMgr;
  CPDFSDK_ActionHandler* m_pActionHandler;
  IFXJS_Runtime* m_pJSRuntime;
  FPDF_FORMFILLINFO* const m_pInfo;
  CPDFSDK_Document* m_pSDKDoc;
  CPDF_Document* const m_pPDFDoc;
  CFFL_IFormFiller* m_pIFormFiller;
  IFX_SystemHandler* m_pSysHandler;
  CJS_RuntimeFactory* m_pJSRuntimeFactory;
};

class CPDFSDK_Document {
 public:
  CPDFSDK_Document(CPDF_Document* pDoc, CPDFDoc_Environment* pEnv);
  ~CPDFSDK_Document();

  CPDFSDK_InterForm* GetInterForm();
  CPDF_Document* GetDocument() { return m_pDoc; }

  CPDFSDK_PageView* GetPageView(CPDF_Page* pPDFPage, FX_BOOL ReNew = TRUE);
  CPDFSDK_PageView* GetPageView(int nIndex);
  CPDFSDK_PageView* GetCurrentView();
  void ReMovePageView(CPDF_Page* pPDFPage);
  void UpdateAllViews(CPDFSDK_PageView* pSender, CPDFSDK_Annot* pAnnot);

  CPDFSDK_Annot* GetFocusAnnot();

  IFXJS_Runtime* GetJsRuntime();

  FX_BOOL SetFocusAnnot(CPDFSDK_Annot* pAnnot, FX_UINT nFlag = 0);
  FX_BOOL KillFocusAnnot(FX_UINT nFlag = 0);

  FX_BOOL ExtractPages(const CFX_WordArray& arrExtraPages,
                       CPDF_Document* pDstDoc);
  FX_BOOL InsertPages(int nInsertAt,
                      const CPDF_Document* pSrcDoc,
                      const CFX_WordArray& arrSrcPages);
  FX_BOOL ReplacePages(int nPage,
                       const CPDF_Document* pSrcDoc,
                       const CFX_WordArray& arrSrcPages);

  void OnCloseDocument();

  int GetPageCount() { return m_pDoc->GetPageCount(); }
  FX_BOOL GetPermissions(int nFlag);
  FX_BOOL GetChangeMark() { return m_bChangeMask; }
  void SetChangeMark() { m_bChangeMask = TRUE; }
  void ClearChangeMark() { m_bChangeMask = FALSE; }
  CFX_WideString GetPath();
  CPDF_Page* GetPage(int nIndex);
  CPDFDoc_Environment* GetEnv() { return m_pEnv; }
  void ProcJavascriptFun();
  FX_BOOL ProcOpenAction();
  CPDF_OCContext* GetOCContext();

 private:
  std::map<CPDF_Page*, CPDFSDK_PageView*> m_pageMap;
  CPDF_Document* m_pDoc;
  CPDFSDK_InterForm* m_pInterForm;
  CPDFSDK_Annot* m_pFocusAnnot;
  CPDFDoc_Environment* m_pEnv;
  CPDF_OCContext* m_pOccontent;
  FX_BOOL m_bChangeMask;
};
class CPDFSDK_PageView final {
 public:
  CPDFSDK_PageView(CPDFSDK_Document* pSDKDoc, CPDF_Page* page);
  ~CPDFSDK_PageView();
  void PageView_OnDraw(CFX_RenderDevice* pDevice,
                       CPDF_Matrix* pUser2Device,
                       CPDF_RenderOptions* pOptions);
  CPDF_Annot* GetPDFAnnotAtPoint(FX_FLOAT pageX, FX_FLOAT pageY);
  CPDFSDK_Annot* GetFXAnnotAtPoint(FX_FLOAT pageX, FX_FLOAT pageY);
  CPDF_Annot* GetPDFWidgetAtPoint(FX_FLOAT pageX, FX_FLOAT pageY);
  CPDFSDK_Annot* GetFXWidgetAtPoint(FX_FLOAT pageX, FX_FLOAT pageY);
  CPDFSDK_Annot* GetFocusAnnot();
  void SetFocusAnnot(CPDFSDK_Annot* pSDKAnnot, FX_UINT nFlag = 0) {
    m_pSDKDoc->SetFocusAnnot(pSDKAnnot, nFlag);
  }
  FX_BOOL KillFocusAnnot(FX_UINT nFlag = 0) {
    return m_pSDKDoc->KillFocusAnnot(nFlag);
  }
  FX_BOOL Annot_HasAppearance(CPDF_Annot* pAnnot);

  CPDFSDK_Annot* AddAnnot(CPDF_Dictionary* pDict);
  CPDFSDK_Annot* AddAnnot(const FX_CHAR* lpSubType, CPDF_Dictionary* pDict);
  CPDFSDK_Annot* AddAnnot(CPDF_Annot* pPDFAnnot);
  FX_BOOL DeleteAnnot(CPDFSDK_Annot* pAnnot);
  int CountAnnots();
  CPDFSDK_Annot* GetAnnot(int nIndex);
  CPDFSDK_Annot* GetAnnotByDict(CPDF_Dictionary* pDict);
  CPDF_Page* GetPDFPage() { return m_page; }
  CPDF_Document* GetPDFDocument();
  CPDFSDK_Document* GetSDKDocument() { return m_pSDKDoc; }
  FX_BOOL OnLButtonDown(const CPDF_Point& point, FX_UINT nFlag);
  FX_BOOL OnLButtonUp(const CPDF_Point& point, FX_UINT nFlag);
  FX_BOOL OnChar(int nChar, FX_UINT nFlag);
  FX_BOOL OnKeyDown(int nKeyCode, int nFlag);
  FX_BOOL OnKeyUp(int nKeyCode, int nFlag);

  FX_BOOL OnMouseMove(const CPDF_Point& point, int nFlag);
  FX_BOOL OnMouseWheel(double deltaX,
                       double deltaY,
                       const CPDF_Point& point,
                       int nFlag);
  FX_BOOL IsValidAnnot(void* p);
  void GetCurrentMatrix(CPDF_Matrix& matrix) { matrix = m_curMatrix; }
  void UpdateRects(CFX_RectArray& rects);
  void UpdateView(CPDFSDK_Annot* pAnnot);
  CFX_PtrArray* GetAnnotList() { return &m_fxAnnotArray; }

  int GetPageIndex();
  void LoadFXAnnots();

  void SetValid(FX_BOOL bValid) { m_bValid = bValid; }
  FX_BOOL IsValid() { return m_bValid; }
  void SetLock(FX_BOOL bLocked) { m_bLocked = bLocked; }
  FX_BOOL IsLocked() { return m_bLocked; }
  void TakeOverPage() { m_bTakeOverPage = TRUE; }

 private:
  void PageView_OnHighlightFormFields(CFX_RenderDevice* pDevice,
                                      CPDFSDK_Widget* pWidget);
  CPDF_Matrix m_curMatrix;
  CPDF_Page* m_page;
  CPDF_AnnotList* m_pAnnotList;
  // CPDFSDK_Annot* m_pFocusAnnot;
  CFX_PtrArray m_fxAnnotArray;
  CPDFSDK_Document* m_pSDKDoc;
  CPDFSDK_Widget* m_CaptureWidget;
  FX_BOOL m_bEnterWidget;
  FX_BOOL m_bExitWidget;
  FX_BOOL m_bOnWidget;
  FX_BOOL m_bValid;
  FX_BOOL m_bLocked;
  FX_BOOL m_bTakeOverPage;
};

template <class TYPE>
class CGW_ArrayTemplate : public CFX_ArrayTemplate<TYPE> {
 public:
  CGW_ArrayTemplate() {}
  ~CGW_ArrayTemplate() {}

  typedef int (*LP_COMPARE)(TYPE p1, TYPE p2);

  void Sort(LP_COMPARE pCompare, FX_BOOL bAscent = TRUE) {
    int nSize = this->GetSize();
    QuickSort(0, nSize - 1, bAscent, pCompare);
  }

 private:
  void QuickSort(FX_UINT nStartPos,
                 FX_UINT nStopPos,
                 FX_BOOL bAscend,
                 LP_COMPARE pCompare) {
    if (nStartPos >= nStopPos)
      return;

    if ((nStopPos - nStartPos) == 1) {
      TYPE Value1 = this->GetAt(nStartPos);
      TYPE Value2 = this->GetAt(nStopPos);

      int iGreate = (*pCompare)(Value1, Value2);
      if ((bAscend && iGreate > 0) || (!bAscend && iGreate < 0)) {
        this->SetAt(nStartPos, Value2);
        this->SetAt(nStopPos, Value1);
      }
      return;
    }

    FX_UINT m = nStartPos + (nStopPos - nStartPos) / 2;
    FX_UINT i = nStartPos;

    TYPE Value = this->GetAt(m);

    while (i < m) {
      TYPE temp = this->GetAt(i);

      int iGreate = (*pCompare)(temp, Value);
      if ((bAscend && iGreate > 0) || (!bAscend && iGreate < 0)) {
        this->InsertAt(m + 1, temp);
        this->RemoveAt(i);
        m--;
      } else {
        i++;
      }
    }

    FX_UINT j = nStopPos;

    while (j > m) {
      TYPE temp = this->GetAt(j);

      int iGreate = (*pCompare)(temp, Value);
      if ((bAscend && iGreate < 0) || (!bAscend && iGreate > 0)) {
        this->RemoveAt(j);
        this->InsertAt(m, temp);
        m++;
      } else {
        j--;
      }
    }

    if (nStartPos < m)
      QuickSort(nStartPos, m, bAscend, pCompare);
    if (nStopPos > m)
      QuickSort(m, nStopPos, bAscend, pCompare);
  }
};

#endif  // FPDFSDK_INCLUDE_FSDK_MGR_H_
