// 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/mask.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,
                       Mask<XFA_PrintOpt> 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,
             Mask<XFA_PrintOpt> 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;
  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_
