// Copyright 2016 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_FPDFXFA_CPDFXFA_DOCENVIRONMENT_H_
#define FPDFSDK_FPDFXFA_CPDFXFA_DOCENVIRONMENT_H_

#include "public/fpdfview.h"
#include "xfa/fxfa/fxfa.h"

class CPDFXFA_Document;
class IJS_Context;

class CPDFXFA_DocEnvironment : public IXFA_DocEnvironment {
 public:
  CPDFXFA_DocEnvironment(CPDFXFA_Document*);
  ~CPDFXFA_DocEnvironment() override;

  // IXFA_DocEnvironment
  void SetChangeMark(CXFA_FFDoc* hDoc) override;
  // used in dynamic xfa, dwFlags refer to XFA_INVALIDATE_XXX macros.
  void InvalidateRect(CXFA_FFPageView* pPageView,
                      const CFX_RectF& rt,
                      uint32_t dwFlags) override;
  // show or hide caret
  void DisplayCaret(CXFA_FFWidget* hWidget,
                    FX_BOOL bVisible,
                    const CFX_RectF* pRtAnchor) override;
  // dwPos: (0:bottom 1:top)
  FX_BOOL GetPopupPos(CXFA_FFWidget* hWidget,
                      FX_FLOAT fMinPopup,
                      FX_FLOAT fMaxPopup,
                      const CFX_RectF& rtAnchor,
                      CFX_RectF& rtPopup) override;
  FX_BOOL PopupMenu(CXFA_FFWidget* hWidget, CFX_PointF ptPopup) override;

  // dwFlags XFA_PAGEVIEWEVENT_Added, XFA_PAGEVIEWEVENT_Removing
  void PageViewEvent(CXFA_FFPageView* pPageView, uint32_t dwFlags) override;
  void WidgetPostAdd(CXFA_FFWidget* hWidget,
                     CXFA_WidgetAcc* pWidgetData) override;
  void WidgetPreRemove(CXFA_FFWidget* hWidget,
                       CXFA_WidgetAcc* pWidgetData) override;

  // Host method
  int32_t CountPages(CXFA_FFDoc* hDoc) override;
  int32_t GetCurrentPage(CXFA_FFDoc* hDoc) override;
  void SetCurrentPage(CXFA_FFDoc* hDoc, int32_t iCurPage) override;
  FX_BOOL IsCalculationsEnabled(CXFA_FFDoc* hDoc) override;
  void SetCalculationsEnabled(CXFA_FFDoc* hDoc, FX_BOOL bEnabled) override;
  void GetTitle(CXFA_FFDoc* hDoc, CFX_WideString& wsTitle) override;
  void SetTitle(CXFA_FFDoc* hDoc, const CFX_WideString& wsTitle) override;
  void ExportData(CXFA_FFDoc* hDoc,
                  const CFX_WideString& wsFilePath,
                  FX_BOOL bXDP) override;
  void GotoURL(CXFA_FFDoc* hDoc, const CFX_WideString& bsURL) override;
  FX_BOOL IsValidationsEnabled(CXFA_FFDoc* hDoc) override;
  void SetValidationsEnabled(CXFA_FFDoc* hDoc, FX_BOOL bEnabled) override;
  void SetFocusWidget(CXFA_FFDoc* hDoc, CXFA_FFWidget* hWidget) override;
  void Print(CXFA_FFDoc* hDoc,
             int32_t nStartPage,
             int32_t nEndPage,
             uint32_t dwOptions) override;
  FX_ARGB GetHighlightColor(CXFA_FFDoc* hDoc) override;

  /**
   *Submit data to email, http, ftp.
   * @param[in] hDoc The document handler.
   * @param[in] eFormat Determines the format in which the data will be
   *submitted. XFA_ATTRIBUTEENUM_Xdp, XFA_ATTRIBUTEENUM_Xml...
   * @param[in] wsTarget The URL to which the data will be submitted.
   * @param[in] eEncoding The encoding of text content.
   * @param[in] pXDPContent Controls what subset of the data is submitted, used
   *only when the format property is xdp.
   * @param[in] bEmbedPDF, specifies whether PDF is embedded in the submitted
   *content or not.
   */
  FX_BOOL SubmitData(CXFA_FFDoc* hDoc, CXFA_Submit submit) override;

  FX_BOOL GetGlobalProperty(CXFA_FFDoc* hDoc,
                            const CFX_ByteStringC& szPropName,
                            CFXJSE_Value* pValue) override;
  FX_BOOL SetGlobalProperty(CXFA_FFDoc* hDoc,
                            const CFX_ByteStringC& szPropName,
                            CFXJSE_Value* pValue) override;

  IFX_SeekableReadStream* OpenLinkedFile(CXFA_FFDoc* hDoc,
                                         const CFX_WideString& wsLink) override;

 private:
  FX_BOOL OnBeforeNotifySubmit();
  void OnAfterNotifySubmit();
  FX_BOOL NotifySubmit(FX_BOOL bPrevOrPost);
  FX_BOOL SubmitDataInternal(CXFA_FFDoc* hDoc, CXFA_Submit submit);
  FX_BOOL MailToInfo(CFX_WideString& csURL,
                     CFX_WideString& csToAddress,
                     CFX_WideString& csCCAddress,
                     CFX_WideString& csBCCAddress,
                     CFX_WideString& csSubject,
                     CFX_WideString& csMsg);
  FX_BOOL ExportSubmitFile(FPDF_FILEHANDLER* ppFileHandler,
                           int fileType,
                           FPDF_DWORD encodeType,
                           FPDF_DWORD flag);
  void ToXFAContentFlags(CFX_WideString csSrcContent, FPDF_DWORD& flag);

  CPDFXFA_Document* const m_pDocument;  // Not owned;
  IJS_Context* m_pJSContext;
};

#endif  // FPDFSDK_FPDFXFA_CPDFXFA_DOCENVIRONMENT_H_
