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

#include <stddef.h>
#include <stdint.h>

#include <map>
#include <memory>
#include <vector>

#include "core/fpdfapi/parser/fpdf_parser_decode.h"
#include "core/fpdfdoc/cpdf_defaultappearance.h"
#include "core/fpdfdoc/cpdf_formfield.h"
#include "core/fxcrt/fx_coordinates.h"
#include "core/fxcrt/fx_string.h"
#include "core/fxcrt/retain_ptr.h"
#include "core/fxcrt/unowned_ptr.h"
#include "third_party/base/span.h"

class CFieldTree;
class CFDF_Document;
class CPDF_Document;
class CPDF_Dictionary;
class CPDF_Font;
class CPDF_FormControl;
class CPDF_Page;

class CPDF_InteractiveForm {
 public:
  class NotifierIface {
   public:
    virtual ~NotifierIface() = default;

    virtual bool BeforeValueChange(CPDF_FormField* pField,
                                   const WideString& csValue) = 0;
    virtual void AfterValueChange(CPDF_FormField* pField) = 0;
    virtual bool BeforeSelectionChange(CPDF_FormField* pField,
                                       const WideString& csValue) = 0;
    virtual void AfterSelectionChange(CPDF_FormField* pField) = 0;
    virtual void AfterCheckedStatusChange(CPDF_FormField* pField) = 0;
    virtual void AfterFormReset(CPDF_InteractiveForm* pForm) = 0;
  };

  explicit CPDF_InteractiveForm(CPDF_Document* pDocument);
  ~CPDF_InteractiveForm();

  static bool IsUpdateAPEnabled();
  static void SetUpdateAP(bool bUpdateAP);
  static RetainPtr<CPDF_Font> AddNativeInteractiveFormFont(
      CPDF_Dictionary*& pFormDict,
      CPDF_Document* pDocument,
      ByteString* csNameTag);

  size_t CountFields(const WideString& csFieldName) const;
  CPDF_FormField* GetField(uint32_t index, const WideString& csFieldName) const;
  CPDF_FormField* GetFieldByDict(CPDF_Dictionary* pFieldDict) const;

  const CPDF_FormControl* GetControlAtPoint(const CPDF_Page* pPage,
                                            const CFX_PointF& point,
                                            int* z_order) const;
  CPDF_FormControl* GetControlByDict(const CPDF_Dictionary* pWidgetDict) const;

  bool NeedConstructAP() const;
  int CountFieldsInCalculationOrder();
  CPDF_FormField* GetFieldInCalculationOrder(int index);
  int FindFieldInCalculationOrder(const CPDF_FormField* pField);

  RetainPtr<CPDF_Font> GetFormFont(ByteString csNameTag) const;
  CPDF_DefaultAppearance GetDefaultAppearance() const;
  int GetFormAlignment() const;

  bool CheckRequiredFields(const std::vector<CPDF_FormField*>* fields,
                           bool bIncludeOrExclude) const;

  std::unique_ptr<CFDF_Document> ExportToFDF(const WideString& pdf_path) const;
  std::unique_ptr<CFDF_Document> ExportToFDF(
      const WideString& pdf_path,
      const std::vector<CPDF_FormField*>& fields,
      bool bIncludeOrExclude) const;

  void ResetForm();
  void ResetForm(pdfium::span<CPDF_FormField*> fields, bool bIncludeOrExclude);

  void SetNotifierIface(NotifierIface* pNotify);
  void FixPageFields(CPDF_Page* pPage);

  NotifierIface* GetFormNotify() const { return m_pFormNotify.Get(); }
  CPDF_Document* GetDocument() const { return m_pDocument.Get(); }
  CPDF_Dictionary* GetFormDict() const { return m_pFormDict.Get(); }

  const std::vector<UnownedPtr<CPDF_FormControl>>& GetControlsForField(
      const CPDF_FormField* pField);

 private:
  void LoadField(CPDF_Dictionary* pFieldDict, int nLevel);
  void AddTerminalField(CPDF_Dictionary* pFieldDict);
  CPDF_FormControl* AddControl(CPDF_FormField* pField,
                               CPDF_Dictionary* pWidgetDict);

  static bool s_bUpdateAP;

  ByteString m_bsEncoding;
  UnownedPtr<CPDF_Document> const m_pDocument;
  RetainPtr<CPDF_Dictionary> m_pFormDict;
  std::unique_ptr<CFieldTree> m_pFieldTree;
  std::map<const CPDF_Dictionary*, std::unique_ptr<CPDF_FormControl>>
      m_ControlMap;
  // Points into |m_ControlMap|.
  std::map<const CPDF_FormField*, std::vector<UnownedPtr<CPDF_FormControl>>>
      m_ControlLists;
  UnownedPtr<NotifierIface> m_pFormNotify;
};

#endif  // CORE_FPDFDOC_CPDF_INTERACTIVEFORM_H_
