// 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_LAYOUT_CXFA_VIEWLAYOUTPROCESSOR_H_
#define XFA_FXFA_LAYOUT_CXFA_VIEWLAYOUTPROCESSOR_H_

#include <iterator>
#include <list>
#include <map>
#include <memory>
#include <vector>

#include "core/fxcrt/unowned_ptr.h"
#include "fxjs/gc/heap.h"
#include "third_party/base/optional.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/layout/cxfa_contentlayoutprocessor.h"

class CXFA_LayoutItem;
class CXFA_Node;

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

 public:
  struct BreakData {
    CXFA_Node* pLeader;
    CXFA_Node* pTrailer;
    bool bCreatePage;
  };

  struct OverflowData {
    CXFA_Node* pLeader;
    CXFA_Node* pTrailer;
  };

  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
  ~CXFA_ViewLayoutProcessor();

  void PreFinalize();
  void Trace(cppgc::Visitor* visitor) const;
  cppgc::Heap* GetHeap() const { return m_pHeap.Get(); }

  bool InitLayoutPage(CXFA_Node* pFormNode);
  bool PrepareFirstPage(CXFA_Node* pRootSubform);
  float GetAvailHeight();
  bool GetNextAvailContentHeight(float fChildHeight);
  void SubmitContentItem(CXFA_ContentLayoutItem* pContentLayoutItem,
                         CXFA_ContentLayoutProcessor::Result eStatus);
  void FinishPaginatedPageSets();
  void SyncLayoutData();
  int32_t GetPageCount() const;
  CXFA_ViewLayoutItem* GetPage(int32_t index) const;
  int32_t GetPageIndex(const CXFA_ViewLayoutItem* pPage) const;
  CXFA_ViewLayoutItem* GetRootLayoutItem() const {
    return m_pPageSetRootLayoutItem.Get();
  }
  Optional<BreakData> ProcessBreakBefore(const CXFA_Node* pBreakNode);
  Optional<BreakData> ProcessBreakAfter(const CXFA_Node* pBreakNode);
  Optional<OverflowData> ProcessOverflow(CXFA_Node* pFormNode,
                                         bool bCreatePage);
  CXFA_Node* QueryOverflow(CXFA_Node* pFormNode);
  CXFA_Node* ProcessBookendLeader(const CXFA_Node* pBookendNode);
  CXFA_Node* ProcessBookendTrailer(const CXFA_Node* pBookendNode);

 private:
  class CXFA_ViewRecord : public cppgc::GarbageCollected<CXFA_ViewRecord> {
   public:
    CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
    ~CXFA_ViewRecord();

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

    cppgc::Member<CXFA_ViewLayoutItem> pCurPageSet;
    cppgc::Member<CXFA_ViewLayoutItem> pCurPageArea;
    cppgc::Member<CXFA_ViewLayoutItem> pCurContentArea;

   private:
    CXFA_ViewRecord();
  };

  CXFA_ViewLayoutProcessor(cppgc::Heap* pHeap,
                           CXFA_LayoutProcessor* pLayoutProcessor);

  bool AppendNewPage(bool bFirstTemPage);
  void ReorderPendingLayoutRecordToTail(CXFA_ViewRecord* pNewRecord,
                                        CXFA_ViewRecord* pPrevRecord);
  void RemoveLayoutRecord(CXFA_ViewRecord* pNewRecord,
                          CXFA_ViewRecord* pPrevRecord);
  bool HasCurrentViewRecord() const {
    return m_CurrentViewRecordIter != m_ProposedViewRecords.end();
  }
  CXFA_ViewRecord* GetCurrentViewRecord() {
    return m_CurrentViewRecordIter->Get();
  }
  const CXFA_ViewRecord* GetCurrentViewRecord() const {
    return m_CurrentViewRecordIter->Get();
  }
  void ResetToFirstViewRecord() {
    m_CurrentViewRecordIter = m_ProposedViewRecords.begin();
  }
  std::list<cppgc::Member<CXFA_ViewRecord>>::iterator GetTailPosition() {
    auto iter = m_ProposedViewRecords.end();
    return !m_ProposedViewRecords.empty() ? std::prev(iter) : iter;
  }
  void AppendNewRecord(CXFA_ViewRecord* pNewRecord);
  CXFA_ViewRecord* CreateViewRecord(CXFA_Node* pPageNode, bool bCreateNew);
  CXFA_ViewRecord* CreateViewRecordSimple();
  void AddPageAreaLayoutItem(CXFA_ViewRecord* pNewRecord,
                             CXFA_Node* pNewPageArea);
  void AddContentAreaLayoutItem(CXFA_ViewRecord* pNewRecord,
                                CXFA_Node* pContentArea);
  bool RunBreak(XFA_Element eBreakType,
                XFA_AttributeValue eTargetType,
                CXFA_Node* pTarget,
                bool bStartNew);
  bool ShouldGetNextPageArea(CXFA_Node* pTarget, bool bStartNew) const;
  bool BreakOverflow(const CXFA_Node* pOverflowNode,
                     bool bCreatePage,
                     CXFA_Node** pLeaderTemplate,
                     CXFA_Node** pTrailerTemplate);
  CXFA_Node* ProcessBookendLeaderOrTrailer(const CXFA_Node* pBookendNode,
                                           bool bLeader);
  CXFA_Node* ResolveBookendLeaderOrTrailer(const CXFA_Node* pBookendNode,
                                           bool bLeader);
  Optional<BreakData> ProcessBreakBeforeOrAfter(const CXFA_Node* pBreakNode,
                                                bool bBefore);
  BreakData ExecuteBreakBeforeOrAfter(const CXFA_Node* pCurNode, bool bBefore);

  int32_t CreateMinPageRecord(CXFA_Node* pPageArea,
                              bool bTargetPageArea,
                              bool bCreateLast);
  void CreateMinPageSetRecord(CXFA_Node* pPageSet, bool bCreateAll);
  void CreateNextMinRecord(CXFA_Node* pRecordNode);
  bool FindPageAreaFromPageSet(CXFA_Node* pPageSet,
                               CXFA_Node* pStartChild,
                               CXFA_Node* pTargetPageArea,
                               CXFA_Node* pTargetContentArea,
                               bool bNewPage,
                               bool bQuery);
  bool FindPageAreaFromPageSet_Ordered(CXFA_Node* pPageSet,
                                       CXFA_Node* pStartChild,
                                       CXFA_Node* pTargetPageArea,
                                       CXFA_Node* pTargetContentArea,
                                       bool bNewPage,
                                       bool bQuery);
  bool FindPageAreaFromPageSet_SimplexDuplex(
      CXFA_Node* pPageSet,
      CXFA_Node* pStartChild,
      CXFA_Node* pTargetPageArea,
      CXFA_Node* pTargetContentArea,
      bool bNewPage,
      bool bQuery,
      XFA_AttributeValue ePreferredPosition);
  bool MatchPageAreaOddOrEven(CXFA_Node* pPageArea);
  CXFA_Node* GetNextAvailPageArea(CXFA_Node* pTargetPageArea,
                                  CXFA_Node* pTargetContentArea,
                                  bool bNewPage,
                                  bool bQuery);
  bool GetNextContentArea(CXFA_Node* pTargetContentArea);
  void InitPageSetMap();
  void ProcessLastPageSet();
  bool IsPageSetRootOrderedOccurrence() const {
    return m_ePageSetMode == XFA_AttributeValue::OrderedOccurrence;
  }
  void ClearData();
  void MergePageSetContents();
  void LayoutPageSetContents();
  void PrepareLayout();
  void SaveLayoutItemChildren(CXFA_LayoutItem* pParentLayoutItem);
  void ProcessSimplexOrDuplexPageSets(CXFA_ViewLayoutItem* pPageSetLayoutItem,
                                      bool bIsSimplex);

  UnownedPtr<cppgc::Heap> m_pHeap;
  cppgc::Member<CXFA_LayoutProcessor> m_pLayoutProcessor;
  cppgc::Member<CXFA_Node> m_pPageSetNode;
  cppgc::Member<CXFA_Node> m_pCurPageArea;
  cppgc::Member<CXFA_ViewLayoutItem> m_pPageSetRootLayoutItem;
  cppgc::Member<CXFA_ViewLayoutItem> m_pPageSetCurLayoutItem;
  std::list<cppgc::Member<CXFA_ViewRecord>> m_ProposedViewRecords;
  std::list<cppgc::Member<CXFA_ViewRecord>>::iterator m_CurrentViewRecordIter;
  int32_t m_nAvailPages = 0;
  int32_t m_nCurPageCount = 0;
  XFA_AttributeValue m_ePageSetMode = XFA_AttributeValue::OrderedOccurrence;
  bool m_bCreateOverFlowPage = false;
  std::map<CXFA_Node*, int32_t> m_pPageSetMap;
  std::vector<cppgc::Member<CXFA_ViewLayoutItem>> m_PageArray;
};

#endif  // XFA_FXFA_LAYOUT_CXFA_VIEWLAYOUTPROCESSOR_H_
