// 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 XFA_FXFA_CXFA_FFDOC_H_
#define XFA_FXFA_CXFA_FFDOC_H_

#include <map>
#include <memory>

#include "core/fxcrt/fx_coordinates.h"
#include "core/fxcrt/fx_stream.h"
#include "core/fxcrt/retain_ptr.h"
#include "core/fxcrt/unowned_ptr.h"
#include "core/fxge/dib/fx_dib.h"
#include "fxjs/gc/heap.h"
#include "v8/include/cppgc/garbage-collected.h"
#include "v8/include/cppgc/member.h"
#include "v8/include/cppgc/prefinalizer.h"
#include "v8/include/cppgc/visitor.h"
#include "xfa/fxfa/fxfa.h"
#include "xfa/fxfa/parser/cxfa_document.h"

class CFGAS_PDFFontMgr;
class CFX_DIBBase;
class CFX_DIBitmap;
class CFX_XMLDocument;
class CPDF_Document;
class CXFA_FFApp;
class CXFA_FFDoc;
class CXFA_FFNotify;
class CXFA_FFDocView;
class CXFA_FFPageView;
class CXFA_FFWidget;
class CXFA_LayoutProcessor;
class IJS_Runtime;

struct FX_IMAGEDIB_AND_DPI {
  FX_IMAGEDIB_AND_DPI();
  FX_IMAGEDIB_AND_DPI(const FX_IMAGEDIB_AND_DPI& that);
  FX_IMAGEDIB_AND_DPI(const RetainPtr<CFX_DIBBase>& pDib,
                      int32_t xDpi,
                      int32_t yDpi);
  ~FX_IMAGEDIB_AND_DPI();

  RetainPtr<CFX_DIBBase> pDibSource;
  int32_t iImageXDpi;
  int32_t iImageYDpi;
};

class CXFA_FFDoc : public cppgc::GarbageCollected<CXFA_FFDoc> {
  CPPGC_USING_PRE_FINALIZER(CXFA_FFDoc, PreFinalize);

 public:
  enum class PageViewEvent {
    kPostAdded = 1,
    kPostRemoved = 3,
    kStopLayout = 4,
  };

  class CallbackIface {
   public:
    virtual ~CallbackIface() = default;

    virtual void SetChangeMark(CXFA_FFDoc* hDoc) = 0;
    virtual void InvalidateRect(CXFA_FFPageView* pPageView,
                                const CFX_RectF& rt) = 0;
    // Show or hide caret.
    virtual void DisplayCaret(CXFA_FFWidget* hWidget,
                              bool bVisible,
                              const CFX_RectF* pRtAnchor) = 0;

    virtual bool GetPopupPos(CXFA_FFWidget* hWidget,
                             float fMinPopup,
                             float fMaxPopup,
                             const CFX_RectF& rtAnchor,
                             CFX_RectF* pPopupRect) = 0;
    virtual bool PopupMenu(CXFA_FFWidget* hWidget,
                           const CFX_PointF& ptPopup) = 0;

    virtual void OnPageViewEvent(CXFA_FFPageView* pPageView,
                                 PageViewEvent eEvent) = 0;

    virtual void WidgetPostAdd(CXFA_FFWidget* hWidget) = 0;
    virtual void WidgetPreRemove(CXFA_FFWidget* hWidget) = 0;
    virtual int32_t CountPages(const CXFA_FFDoc* hDoc) const = 0;
    virtual int32_t GetCurrentPage(const CXFA_FFDoc* hDoc) const = 0;
    virtual void SetCurrentPage(CXFA_FFDoc* hDoc, int32_t iCurPage) = 0;
    virtual bool IsCalculationsEnabled(const CXFA_FFDoc* hDoc) const = 0;
    virtual void SetCalculationsEnabled(CXFA_FFDoc* hDoc, bool bEnabled) = 0;
    virtual WideString GetTitle(const CXFA_FFDoc* hDoc) const = 0;
    virtual void SetTitle(CXFA_FFDoc* hDoc, const WideString& wsTitle) = 0;
    virtual void ExportData(CXFA_FFDoc* hDoc,
                            const WideString& wsFilePath,
                            bool bXDP) = 0;
    virtual void GotoURL(CXFA_FFDoc* hDoc, const WideString& bsURL) = 0;
    virtual bool IsValidationsEnabled(const CXFA_FFDoc* hDoc) const = 0;
    virtual void SetValidationsEnabled(CXFA_FFDoc* hDoc, bool bEnabled) = 0;
    virtual void SetFocusWidget(CXFA_FFDoc* hDoc, CXFA_FFWidget* hWidget) = 0;
    virtual void Print(CXFA_FFDoc* hDoc,
                       int32_t nStartPage,
                       int32_t nEndPage,
                       XFA_PrintOptMask dwOptions) = 0;
    virtual FX_ARGB GetHighlightColor(const CXFA_FFDoc* hDoc) const = 0;
    virtual IJS_Runtime* GetIJSRuntime(const CXFA_FFDoc* hDoc) const = 0;
    virtual CFX_XMLDocument* GetXMLDoc() const = 0;
    virtual RetainPtr<IFX_SeekableReadStream> OpenLinkedFile(
        CXFA_FFDoc* hDoc,
        const WideString& wsLink) = 0;

#ifdef PDF_XFA_ELEMENT_SUBMIT_ENABLED
    virtual bool Submit(CXFA_FFDoc* hDoc, CXFA_Submit* submit) = 0;
#endif  // PDF_XFA_ELEMENT_SUBMIT_ENABLED
  };

  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
  ~CXFA_FFDoc();

  void PreFinalize();
  void Trace(cppgc::Visitor* visitor) const;

  bool OpenDoc(CFX_XMLDocument* pXML);

  void SetChangeMark();
  void InvalidateRect(CXFA_FFPageView* pPageView, const CFX_RectF& rt);
  void DisplayCaret(CXFA_FFWidget* hWidget,
                    bool bVisible,
                    const CFX_RectF* pRtAnchor);
  bool GetPopupPos(CXFA_FFWidget* hWidget,
                   float fMinPopup,
                   float fMaxPopup,
                   const CFX_RectF& rtAnchor,
                   CFX_RectF* pPopupRect) const;
  bool PopupMenu(CXFA_FFWidget* hWidget, const CFX_PointF& ptPopup);
  void OnPageViewEvent(CXFA_FFPageView* pPageView, PageViewEvent eEvent);
  void WidgetPostAdd(CXFA_FFWidget* hWidget);
  void WidgetPreRemove(CXFA_FFWidget* hWidget);
  int32_t CountPages() const;
  int32_t GetCurrentPage() const;
  void SetCurrentPage(int32_t iCurPage);
  bool IsCalculationsEnabled() const;
  void SetCalculationsEnabled(bool bEnabled);
  WideString GetTitle() const;
  void SetTitle(const WideString& wsTitle);
  void ExportData(const WideString& wsFilePath, bool bXDP);
  void GotoURL(const WideString& bsURL);
  bool IsValidationsEnabled() const;
  void SetValidationsEnabled(bool bEnabled);
  void SetFocusWidget(CXFA_FFWidget* hWidget);
  void Print(int32_t nStartPage, int32_t nEndPage, XFA_PrintOptMask dwOptions);
  FX_ARGB GetHighlightColor() const;
  IJS_Runtime* GetIJSRuntime() const;
  CFX_XMLDocument* GetXMLDocument() const;
  RetainPtr<IFX_SeekableReadStream> OpenLinkedFile(const WideString& wsLink);

  CXFA_FFDocView* CreateDocView();
  FormType GetFormType() const { return m_FormType; }
  cppgc::Heap* GetHeap() const { return m_pHeap.Get(); }
  CXFA_Document* GetXFADoc() const { return m_pDocument; }
  CXFA_FFApp* GetApp() const { return m_pApp.Get(); }
  CPDF_Document* GetPDFDoc() const { return m_pPDFDoc.Get(); }
  CFGAS_PDFFontMgr* GetPDFFontMgr() const { return m_pPDFFontMgr.get(); }
  CXFA_FFDocView* GetDocView(CXFA_LayoutProcessor* pLayout);
  CXFA_FFDocView* GetDocView();
  RetainPtr<CFX_DIBitmap> GetPDFNamedImage(WideStringView wsName,
                                           int32_t& iImageXDpi,
                                           int32_t& iImageYDpi);

  bool SavePackage(CXFA_Node* pNode,
                   const RetainPtr<IFX_SeekableStream>& pFile);

 private:
  CXFA_FFDoc(CXFA_FFApp* pApp,
             CallbackIface* pDocEnvironment,
             CPDF_Document* pPDFDoc,
             cppgc::Heap* pHeap);
  bool BuildDoc(CFX_XMLDocument* pXML);

  UnownedPtr<CallbackIface> const m_pDocEnvironment;
  UnownedPtr<CPDF_Document> const m_pPDFDoc;
  UnownedPtr<cppgc::Heap> const m_pHeap;
  UnownedPtr<CFX_XMLDocument> m_pXMLDoc;
  cppgc::Member<CXFA_FFApp> const m_pApp;
  cppgc::Member<CXFA_FFNotify> m_pNotify;
  cppgc::Member<CXFA_Document> m_pDocument;
  cppgc::Member<CXFA_FFDocView> m_DocView;
  std::unique_ptr<CFGAS_PDFFontMgr> m_pPDFFontMgr;
  std::map<uint32_t, FX_IMAGEDIB_AND_DPI> m_HashToDibDpiMap;
  FormType m_FormType = FormType::kXFAForeground;
};

#endif  // XFA_FXFA_CXFA_FFDOC_H_
