// 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_stream.h"
#include "core/fxcrt/retain_ptr.h"
#include "core/fxcrt/unowned_ptr.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_FFNotify;
class CXFA_FFDocView;
class CXFA_LayoutProcessor;

namespace cppgc {
class Heap;
}  // namespace cppgc

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:
  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,
                       IXFA_DocEnvironment::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,
             IXFA_DocEnvironment* pDocEnvironment,
             CPDF_Document* pPDFDoc,
             cppgc::Heap* pHeap);
  bool BuildDoc(CFX_XMLDocument* pXML);

  UnownedPtr<IXFA_DocEnvironment> 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_
