// 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

#include "xfa/fxfa/parser/cxfa_layoutpagemgr.h"

#include "fxjs/cfxjse_engine.h"
#include "third_party/base/stl_util.h"
#include "xfa/fxfa/cxfa_ffnotify.h"
#include "xfa/fxfa/parser/cxfa_containerlayoutitem.h"
#include "xfa/fxfa/parser/cxfa_contentlayoutitem.h"
#include "xfa/fxfa/parser/cxfa_document.h"
#include "xfa/fxfa/parser/cxfa_itemlayoutprocessor.h"
#include "xfa/fxfa/parser/cxfa_layoutprocessor.h"
#include "xfa/fxfa/parser/cxfa_localemgr.h"
#include "xfa/fxfa/parser/cxfa_measurement.h"
#include "xfa/fxfa/parser/cxfa_node.h"
#include "xfa/fxfa/parser/cxfa_nodeiteratortemplate.h"
#include "xfa/fxfa/parser/cxfa_object.h"
#include "xfa/fxfa/parser/cxfa_traversestrategy_contentareacontainerlayoutitem.h"
#include "xfa/fxfa/parser/cxfa_traversestrategy_layoutitem.h"
#include "xfa/fxfa/parser/cxfa_traversestrategy_xfacontainernode.h"
#include "xfa/fxfa/parser/cxfa_traversestrategy_xfanode.h"
#include "xfa/fxfa/parser/xfa_document_datamerger_imp.h"
#include "xfa/fxfa/parser/xfa_resolvenode_rs.h"

namespace {

class PageSetContainerLayoutItem {
 public:
  static CXFA_ContainerLayoutItem* GetFirstChild(
      CXFA_ContainerLayoutItem* pLayoutItem) {
    if (pLayoutItem->m_pFormNode->GetElementType() != XFA_Element::PageSet)
      return nullptr;

    CXFA_ContainerLayoutItem* pChildItem =
        static_cast<CXFA_ContainerLayoutItem*>(pLayoutItem->m_pFirstChild);
    while (pChildItem &&
           pChildItem->m_pFormNode->GetElementType() != XFA_Element::PageSet) {
      pChildItem =
          static_cast<CXFA_ContainerLayoutItem*>(pChildItem->m_pNextSibling);
    }
    return pChildItem;
  }

  static CXFA_ContainerLayoutItem* GetNextSibling(
      CXFA_ContainerLayoutItem* pLayoutItem) {
    CXFA_ContainerLayoutItem* pChildItem =
        static_cast<CXFA_ContainerLayoutItem*>(pLayoutItem->m_pNextSibling);
    while (pChildItem &&
           pChildItem->m_pFormNode->GetElementType() != XFA_Element::PageSet) {
      pChildItem =
          static_cast<CXFA_ContainerLayoutItem*>(pChildItem->m_pNextSibling);
    }
    return pChildItem;
  }

  static CXFA_ContainerLayoutItem* GetParent(
      CXFA_ContainerLayoutItem* pLayoutItem) {
    return static_cast<CXFA_ContainerLayoutItem*>(pLayoutItem->m_pParent);
  }
};

uint32_t GetRelevant(CXFA_Node* pFormItem, uint32_t dwParentRelvant) {
  uint32_t dwRelevant = XFA_WidgetStatus_Viewable | XFA_WidgetStatus_Printable;
  WideString wsRelevant =
      pFormItem->JSNode()->GetCData(XFA_Attribute::Relevant);
  if (!wsRelevant.IsEmpty()) {
    if (wsRelevant == L"+print" || wsRelevant == L"print")
      dwRelevant &= ~XFA_WidgetStatus_Viewable;
    else if (wsRelevant == L"-print")
      dwRelevant &= ~XFA_WidgetStatus_Printable;
  }

  if (!(dwParentRelvant & XFA_WidgetStatus_Viewable) &&
      (dwRelevant != XFA_WidgetStatus_Viewable)) {
    dwRelevant &= ~XFA_WidgetStatus_Viewable;
  }

  if (!(dwParentRelvant & XFA_WidgetStatus_Printable) &&
      (dwRelevant != XFA_WidgetStatus_Printable)) {
    dwRelevant &= ~XFA_WidgetStatus_Printable;
  }
  return dwRelevant;
}

void SyncContainer(CXFA_FFNotify* pNotify,
                   CXFA_LayoutProcessor* pDocLayout,
                   CXFA_LayoutItem* pContainerItem,
                   uint32_t dwRelevant,
                   bool bVisible,
                   int32_t nPageIndex) {
  bool bVisibleItem = false;
  uint32_t dwStatus = 0;
  uint32_t dwRelevantContainer = 0;
  if (bVisible) {
    XFA_ATTRIBUTEENUM eAttributeValue =
        pContainerItem->m_pFormNode->JSNode()->GetEnum(XFA_Attribute::Presence);
    if (eAttributeValue == XFA_ATTRIBUTEENUM_Visible ||
        eAttributeValue == XFA_ATTRIBUTEENUM_Unknown) {
      bVisibleItem = true;
    }
    dwRelevantContainer = GetRelevant(pContainerItem->m_pFormNode, dwRelevant);
    dwStatus =
        (bVisibleItem ? XFA_WidgetStatus_Visible : 0) | dwRelevantContainer;
  }
  pNotify->OnLayoutItemAdded(pDocLayout, pContainerItem, nPageIndex, dwStatus);
  for (CXFA_LayoutItem* pChild = pContainerItem->m_pFirstChild; pChild;
       pChild = pChild->m_pNextSibling) {
    if (pChild->IsContentLayoutItem()) {
      SyncContainer(pNotify, pDocLayout, pChild, dwRelevantContainer,
                    bVisibleItem, nPageIndex);
    }
  }
}

void ReorderLayoutItemToTail(CXFA_ContainerLayoutItem* pLayoutItem) {
  CXFA_ContainerLayoutItem* pParentLayoutItem =
      static_cast<CXFA_ContainerLayoutItem*>(pLayoutItem->m_pParent);
  if (!pParentLayoutItem)
    return;

  pParentLayoutItem->RemoveChild(pLayoutItem);
  pParentLayoutItem->AddChild(pLayoutItem);
}

void RemoveLayoutItem(CXFA_ContainerLayoutItem* pLayoutItem) {
  CXFA_ContainerLayoutItem* pParentLayoutItem =
      static_cast<CXFA_ContainerLayoutItem*>(pLayoutItem->m_pParent);
  if (!pParentLayoutItem)
    return;

  pParentLayoutItem->RemoveChild(pLayoutItem);
}

CXFA_Node* ResolveBreakTarget(CXFA_Node* pPageSetRoot,
                              bool bNewExprStyle,
                              WideString& wsTargetAll) {
  CXFA_Document* pDocument = pPageSetRoot->GetDocument();
  if (wsTargetAll.IsEmpty())
    return nullptr;

  wsTargetAll.Trim();
  int32_t iSplitIndex = 0;
  bool bTargetAllFind = true;
  while (iSplitIndex != -1) {
    WideString wsExpr;
    pdfium::Optional<size_t> iSplitNextIndex = 0;
    if (!bTargetAllFind) {
      iSplitNextIndex = wsTargetAll.Find(' ', iSplitIndex);
      if (!iSplitNextIndex.has_value())
        return nullptr;
      wsExpr =
          wsTargetAll.Mid(iSplitIndex, iSplitNextIndex.value() - iSplitIndex);
    } else {
      wsExpr = wsTargetAll;
    }
    if (wsExpr.IsEmpty())
      return nullptr;

    bTargetAllFind = false;
    if (wsExpr[0] == '#') {
      CXFA_Node* pNode = pDocument->GetNodeByID(
          ToNode(pDocument->GetXFAObject(XFA_HASHCODE_Template)),
          wsExpr.Right(wsExpr.GetLength() - 1).AsStringView());
      if (pNode)
        return pNode;
    } else if (bNewExprStyle) {
      WideString wsProcessedTarget = wsExpr;
      if (wsExpr.Left(4) == L"som(" && wsExpr.Last() == L')') {
        wsProcessedTarget = wsExpr.Mid(4, wsExpr.GetLength() - 5);
      }
      XFA_RESOLVENODE_RS rs;
      int32_t iCount = pDocument->GetScriptContext()->ResolveObjects(
          pPageSetRoot, wsProcessedTarget.AsStringView(), rs,
          XFA_RESOLVENODE_Children | XFA_RESOLVENODE_Properties |
              XFA_RESOLVENODE_Attributes | XFA_RESOLVENODE_Siblings |
              XFA_RESOLVENODE_Parent);
      if (iCount > 0 && rs.objects.front()->IsNode())
        return rs.objects.front()->AsNode();
    }
    iSplitIndex = iSplitNextIndex.value();
  }
  return nullptr;
}

void SetLayoutGeneratedNodeFlag(CXFA_Node* pNode) {
  pNode->SetFlag(XFA_NodeFlag_LayoutGeneratedNode, false);
  pNode->ClearFlag(XFA_NodeFlag_UnusedNode);
}

bool CheckContentAreaNotUsed(
    CXFA_ContainerLayoutItem* pPageAreaLayoutItem,
    CXFA_Node* pContentArea,
    CXFA_ContainerLayoutItem*& pContentAreaLayoutItem) {
  for (CXFA_ContainerLayoutItem* pLayoutItem =
           static_cast<CXFA_ContainerLayoutItem*>(
               pPageAreaLayoutItem->m_pFirstChild);
       pLayoutItem; pLayoutItem = static_cast<CXFA_ContainerLayoutItem*>(
                        pLayoutItem->m_pNextSibling)) {
    if (pLayoutItem->m_pFormNode == pContentArea) {
      if (!pLayoutItem->m_pFirstChild) {
        pContentAreaLayoutItem = pLayoutItem;
        return true;
      }
      return false;
    }
  }
  return true;
}

void SyncRemoveLayoutItem(CXFA_LayoutItem* pParentLayoutItem,
                          CXFA_FFNotify* pNotify,
                          CXFA_LayoutProcessor* pDocLayout) {
  CXFA_LayoutItem* pNextLayoutItem;
  CXFA_LayoutItem* pCurLayoutItem = pParentLayoutItem->m_pFirstChild;
  while (pCurLayoutItem) {
    pNextLayoutItem = pCurLayoutItem->m_pNextSibling;
    if (pCurLayoutItem->m_pFirstChild)
      SyncRemoveLayoutItem(pCurLayoutItem, pNotify, pDocLayout);

    pNotify->OnLayoutItemRemoving(pDocLayout, pCurLayoutItem);
    delete pCurLayoutItem;
    pCurLayoutItem = pNextLayoutItem;
  }
}

}  // namespace

class CXFA_ContainerRecord {
 public:
  CXFA_ContainerRecord(CXFA_ContainerLayoutItem* pPageSet = nullptr,
                       CXFA_ContainerLayoutItem* pPageArea = nullptr,
                       CXFA_ContainerLayoutItem* pContentArea = nullptr)
      : pCurPageSet(pPageSet),
        pCurPageArea(pPageArea),
        pCurContentArea(pContentArea) {}

  CXFA_ContainerLayoutItem* pCurPageSet;
  CXFA_ContainerLayoutItem* pCurPageArea;
  CXFA_ContainerLayoutItem* pCurContentArea;
};

CXFA_LayoutPageMgr::CXFA_LayoutPageMgr(CXFA_LayoutProcessor* pLayoutProcessor)
    : m_pLayoutProcessor(pLayoutProcessor),
      m_pTemplatePageSetRoot(nullptr),
      m_pPageSetLayoutItemRoot(nullptr),
      m_pPageSetCurRoot(nullptr),
      m_CurrentContainerRecordIter(m_ProposedContainerRecords.end()),
      m_pCurPageArea(nullptr),
      m_nAvailPages(0),
      m_nCurPageCount(0),
      m_ePageSetMode(XFA_ATTRIBUTEENUM_OrderedOccurrence),
      m_bCreateOverFlowPage(false) {}

CXFA_LayoutPageMgr::~CXFA_LayoutPageMgr() {
  ClearData();
  CXFA_LayoutItem* pLayoutItem = GetRootLayoutItem();
  CXFA_LayoutItem* pNextLayout = nullptr;
  for (; pLayoutItem; pLayoutItem = pNextLayout) {
    pNextLayout = pLayoutItem->m_pNextSibling;
    XFA_ReleaseLayoutItem(pLayoutItem);
  }
}

bool CXFA_LayoutPageMgr::InitLayoutPage(CXFA_Node* pFormNode) {
  PrepareLayout();
  CXFA_Node* pTemplateNode = pFormNode->GetTemplateNode();
  if (!pTemplateNode)
    return false;

  m_pTemplatePageSetRoot =
      pTemplateNode->JSNode()->GetProperty(0, XFA_Element::PageSet, true);
  ASSERT(m_pTemplatePageSetRoot);
  if (m_pPageSetLayoutItemRoot) {
    m_pPageSetLayoutItemRoot->m_pParent = nullptr;
    m_pPageSetLayoutItemRoot->m_pFirstChild = nullptr;
    m_pPageSetLayoutItemRoot->m_pNextSibling = nullptr;
    m_pPageSetLayoutItemRoot->m_pFormNode = m_pTemplatePageSetRoot;
  } else {
    m_pPageSetLayoutItemRoot =
        new CXFA_ContainerLayoutItem(m_pTemplatePageSetRoot);
  }
  m_pPageSetCurRoot = m_pPageSetLayoutItemRoot;
  m_pTemplatePageSetRoot->JSNode()->SetLayoutItem(m_pPageSetLayoutItemRoot);

  XFA_ATTRIBUTEENUM eRelation =
      m_pTemplatePageSetRoot->JSNode()->GetEnum(XFA_Attribute::Relation);
  if (eRelation != XFA_ATTRIBUTEENUM_Unknown)
    m_ePageSetMode = eRelation;

  InitPageSetMap();
  CXFA_Node* pPageArea = nullptr;
  int32_t iCount = 0;
  for (pPageArea = m_pTemplatePageSetRoot->GetNodeItem(XFA_NODEITEM_FirstChild);
       pPageArea;
       pPageArea = pPageArea->GetNodeItem(XFA_NODEITEM_NextSibling)) {
    if (pPageArea->GetElementType() == XFA_Element::PageArea) {
      iCount++;
      if (pPageArea->GetFirstChildByClass(XFA_Element::ContentArea))
        return true;
    }
  }
  if (iCount > 0)
    return false;

  CXFA_Document* pDocument = pTemplateNode->GetDocument();
  pPageArea = m_pTemplatePageSetRoot->GetChild(0, XFA_Element::PageArea, false);
  if (!pPageArea) {
    pPageArea = pDocument->CreateNode(m_pTemplatePageSetRoot->GetPacketID(),
                                      XFA_Element::PageArea);
    if (!pPageArea)
      return false;

    m_pTemplatePageSetRoot->InsertChild(pPageArea, nullptr);
    pPageArea->SetFlag(XFA_NodeFlag_Initialized, true);
  }
  CXFA_Node* pContentArea =
      pPageArea->GetChild(0, XFA_Element::ContentArea, false);
  if (!pContentArea) {
    pContentArea = pDocument->CreateNode(pPageArea->GetPacketID(),
                                         XFA_Element::ContentArea);
    if (!pContentArea)
      return false;

    pPageArea->InsertChild(pContentArea, nullptr);
    pContentArea->SetFlag(XFA_NodeFlag_Initialized, true);
    pContentArea->JSNode()->SetMeasure(
        XFA_Attribute::X, CXFA_Measurement(0.25f, XFA_Unit::In), false);
    pContentArea->JSNode()->SetMeasure(
        XFA_Attribute::Y, CXFA_Measurement(0.25f, XFA_Unit::In), false);
    pContentArea->JSNode()->SetMeasure(
        XFA_Attribute::W, CXFA_Measurement(8.0f, XFA_Unit::In), false);
    pContentArea->JSNode()->SetMeasure(
        XFA_Attribute::H, CXFA_Measurement(10.5f, XFA_Unit::In), false);
  }
  CXFA_Node* pMedium = pPageArea->GetChild(0, XFA_Element::Medium, false);
  if (!pMedium) {
    pMedium =
        pDocument->CreateNode(pPageArea->GetPacketID(), XFA_Element::Medium);
    if (!pContentArea)
      return false;

    pPageArea->InsertChild(pMedium, nullptr);
    pMedium->SetFlag(XFA_NodeFlag_Initialized, true);
    pMedium->JSNode()->SetMeasure(XFA_Attribute::Short,
                                  CXFA_Measurement(8.5f, XFA_Unit::In), false);
    pMedium->JSNode()->SetMeasure(XFA_Attribute::Long,
                                  CXFA_Measurement(11.0f, XFA_Unit::In), false);
  }
  return true;
}

bool CXFA_LayoutPageMgr::PrepareFirstPage(CXFA_Node* pRootSubform) {
  bool bProBreakBefore = false;
  CXFA_Node* pBreakBeforeNode = nullptr;
  while (pRootSubform) {
    for (CXFA_Node* pBreakNode =
             pRootSubform->GetNodeItem(XFA_NODEITEM_FirstChild);
         pBreakNode;
         pBreakNode = pBreakNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
      XFA_Element eType = pBreakNode->GetElementType();
      if (eType == XFA_Element::BreakBefore ||
          (eType == XFA_Element::Break &&
           pBreakNode->JSNode()->GetEnum(XFA_Attribute::Before) !=
               XFA_ATTRIBUTEENUM_Auto)) {
        bProBreakBefore = true;
        pBreakBeforeNode = pBreakNode;
        break;
      }
    }
    if (bProBreakBefore)
      break;

    bProBreakBefore = true;
    pRootSubform = pRootSubform->GetFirstChildByClass(XFA_Element::Subform);
    while (pRootSubform &&
           !XFA_ItemLayoutProcessor_IsTakingSpace(pRootSubform)) {
      pRootSubform =
          pRootSubform->GetNextSameClassSibling(XFA_Element::Subform);
    }
  }
  CXFA_Node* pLeader;
  CXFA_Node* pTrailer;
  if (pBreakBeforeNode &&
      ExecuteBreakBeforeOrAfter(pBreakBeforeNode, true, pLeader, pTrailer)) {
    m_CurrentContainerRecordIter = m_ProposedContainerRecords.begin();
    return true;
  }
  return AppendNewPage(true);
}

bool CXFA_LayoutPageMgr::AppendNewPage(bool bFirstTemPage) {
  if (m_CurrentContainerRecordIter != GetTailPosition())
    return true;

  CXFA_Node* pPageNode = GetNextAvailPageArea(nullptr);
  if (!pPageNode)
    return false;

  if (bFirstTemPage &&
      m_CurrentContainerRecordIter == m_ProposedContainerRecords.end()) {
    m_CurrentContainerRecordIter = m_ProposedContainerRecords.begin();
  }
  return !bFirstTemPage ||
         m_CurrentContainerRecordIter != m_ProposedContainerRecords.end();
}

void CXFA_LayoutPageMgr::RemoveLayoutRecord(CXFA_ContainerRecord* pNewRecord,
                                            CXFA_ContainerRecord* pPrevRecord) {
  if (!pNewRecord || !pPrevRecord)
    return;
  if (pNewRecord->pCurPageSet != pPrevRecord->pCurPageSet) {
    RemoveLayoutItem(pNewRecord->pCurPageSet);
    return;
  }
  if (pNewRecord->pCurPageArea != pPrevRecord->pCurPageArea) {
    RemoveLayoutItem(pNewRecord->pCurPageArea);
    return;
  }
  if (pNewRecord->pCurContentArea != pPrevRecord->pCurContentArea) {
    RemoveLayoutItem(pNewRecord->pCurContentArea);
    return;
  }
}

void CXFA_LayoutPageMgr::ReorderPendingLayoutRecordToTail(
    CXFA_ContainerRecord* pNewRecord,
    CXFA_ContainerRecord* pPrevRecord) {
  if (!pNewRecord || !pPrevRecord)
    return;
  if (pNewRecord->pCurPageSet != pPrevRecord->pCurPageSet) {
    ReorderLayoutItemToTail(pNewRecord->pCurPageSet);
    return;
  }
  if (pNewRecord->pCurPageArea != pPrevRecord->pCurPageArea) {
    ReorderLayoutItemToTail(pNewRecord->pCurPageArea);
    return;
  }
  if (pNewRecord->pCurContentArea != pPrevRecord->pCurContentArea) {
    ReorderLayoutItemToTail(pNewRecord->pCurContentArea);
    return;
  }
}

void CXFA_LayoutPageMgr::SubmitContentItem(
    CXFA_ContentLayoutItem* pContentLayoutItem,
    XFA_ItemLayoutProcessorResult eStatus) {
  if (pContentLayoutItem) {
    GetCurrentContainerRecord()->pCurContentArea->AddChild(pContentLayoutItem);
    m_bCreateOverFlowPage = false;
  }

  if (eStatus != XFA_ItemLayoutProcessorResult::Done) {
    if (eStatus == XFA_ItemLayoutProcessorResult::PageFullBreak &&
        m_CurrentContainerRecordIter == GetTailPosition()) {
      AppendNewPage();
    }
    m_CurrentContainerRecordIter = GetTailPosition();
    m_pCurPageArea = GetCurrentContainerRecord()->pCurPageArea->m_pFormNode;
  }
}

float CXFA_LayoutPageMgr::GetAvailHeight() {
  CXFA_ContainerLayoutItem* pLayoutItem =
      GetCurrentContainerRecord()->pCurContentArea;
  if (!pLayoutItem || !pLayoutItem->m_pFormNode)
    return 0.0f;

  float fAvailHeight = pLayoutItem->m_pFormNode->JSNode()
                           ->GetMeasure(XFA_Attribute::H)
                           .ToUnit(XFA_Unit::Pt);
  if (fAvailHeight >= XFA_LAYOUT_FLOAT_PERCISION)
    return fAvailHeight;
  if (m_CurrentContainerRecordIter == m_ProposedContainerRecords.begin())
    return 0.0f;
  return FLT_MAX;
}

bool XFA_LayoutPageMgr_RunBreakTestScript(CXFA_Node* pTestScript) {
  WideString wsExpression = pTestScript->JSNode()->GetContent(false);
  if (wsExpression.IsEmpty())
    return true;
  return pTestScript->GetDocument()->GetNotify()->RunScript(
      pTestScript, pTestScript->GetNodeItem(XFA_NODEITEM_Parent,
                                            XFA_ObjectType::ContainerNode));
}

CXFA_ContainerRecord* CXFA_LayoutPageMgr::CreateContainerRecord(
    CXFA_Node* pPageNode,
    bool bCreateNew) {
  CXFA_ContainerRecord* pNewRecord = new CXFA_ContainerRecord();
  if (m_CurrentContainerRecordIter != m_ProposedContainerRecords.end()) {
    if (!IsPageSetRootOrderedOccurrence() || !pPageNode) {
      *pNewRecord = *GetCurrentContainerRecord();
      m_ProposedContainerRecords.push_back(pNewRecord);
      return pNewRecord;
    }
    CXFA_Node* pPageSet = pPageNode->GetNodeItem(XFA_NODEITEM_Parent);
    if (!bCreateNew) {
      if (pPageSet == m_pTemplatePageSetRoot) {
        pNewRecord->pCurPageSet = m_pPageSetCurRoot;
      } else {
        CXFA_ContainerLayoutItem* pParentLayoutItem =
            static_cast<CXFA_ContainerLayoutItem*>(
                pPageSet->JSNode()->GetLayoutItem());
        if (!pParentLayoutItem)
          pParentLayoutItem = m_pPageSetCurRoot;

        pNewRecord->pCurPageSet = pParentLayoutItem;
      }
    } else {
      CXFA_ContainerLayoutItem* pParentPageSetLayout = nullptr;
      if (pPageSet == GetCurrentContainerRecord()->pCurPageSet->m_pFormNode) {
        pParentPageSetLayout = static_cast<CXFA_ContainerLayoutItem*>(
            GetCurrentContainerRecord()->pCurPageSet->m_pParent);
      } else {
        pParentPageSetLayout = static_cast<CXFA_ContainerLayoutItem*>(
            pPageSet->GetNodeItem(XFA_NODEITEM_Parent)
                ->JSNode()
                ->GetLayoutItem());
      }
      CXFA_ContainerLayoutItem* pPageSetLayoutItem =
          new CXFA_ContainerLayoutItem(pPageSet);
      pPageSet->JSNode()->SetLayoutItem(pPageSetLayoutItem);
      if (!pParentPageSetLayout) {
        CXFA_ContainerLayoutItem* pPrePageSet = m_pPageSetLayoutItemRoot;
        while (pPrePageSet->m_pNextSibling) {
          pPrePageSet = static_cast<CXFA_ContainerLayoutItem*>(
              pPrePageSet->m_pNextSibling);
        }

        pPrePageSet->m_pNextSibling = pPageSetLayoutItem;
        m_pPageSetCurRoot = pPageSetLayoutItem;
      } else {
        pParentPageSetLayout->AddChild(pPageSetLayoutItem);
      }
      pNewRecord->pCurPageSet = pPageSetLayoutItem;
    }
  } else {
    if (pPageNode) {
      CXFA_Node* pPageSet = pPageNode->GetNodeItem(XFA_NODEITEM_Parent);
      if (pPageSet == m_pTemplatePageSetRoot) {
        pNewRecord->pCurPageSet = m_pPageSetLayoutItemRoot;
      } else {
        CXFA_ContainerLayoutItem* pPageSetLayoutItem =
            new CXFA_ContainerLayoutItem(pPageSet);
        pPageSet->JSNode()->SetLayoutItem(pPageSetLayoutItem);
        m_pPageSetLayoutItemRoot->AddChild(pPageSetLayoutItem);
        pNewRecord->pCurPageSet = pPageSetLayoutItem;
      }
    } else {
      pNewRecord->pCurPageSet = m_pPageSetLayoutItemRoot;
    }
  }
  m_ProposedContainerRecords.push_back(pNewRecord);
  return pNewRecord;
}

void CXFA_LayoutPageMgr::AddPageAreaLayoutItem(CXFA_ContainerRecord* pNewRecord,
                                               CXFA_Node* pNewPageArea) {
  CXFA_ContainerLayoutItem* pNewPageAreaLayoutItem = nullptr;
  if (pdfium::IndexInBounds(m_PageArray, m_nAvailPages)) {
    CXFA_ContainerLayoutItem* pContainerItem = m_PageArray[m_nAvailPages];
    pContainerItem->m_pFormNode = pNewPageArea;
    m_nAvailPages++;
    pNewPageAreaLayoutItem = pContainerItem;
  } else {
    CXFA_FFNotify* pNotify = pNewPageArea->GetDocument()->GetNotify();
    auto* pContainerItem = static_cast<CXFA_ContainerLayoutItem*>(
        pNotify->OnCreateLayoutItem(pNewPageArea));
    m_PageArray.push_back(pContainerItem);
    m_nAvailPages++;
    pNotify->OnPageEvent(pContainerItem, XFA_PAGEVIEWEVENT_PostRemoved);
    pNewPageAreaLayoutItem = pContainerItem;
  }
  pNewRecord->pCurPageSet->AddChild(pNewPageAreaLayoutItem);
  pNewRecord->pCurPageArea = pNewPageAreaLayoutItem;
  pNewRecord->pCurContentArea = nullptr;
}

void CXFA_LayoutPageMgr::AddContentAreaLayoutItem(
    CXFA_ContainerRecord* pNewRecord,
    CXFA_Node* pContentArea) {
  if (!pContentArea) {
    pNewRecord->pCurContentArea = nullptr;
    return;
  }
  CXFA_ContainerLayoutItem* pNewContentAreaLayoutItem =
      new CXFA_ContainerLayoutItem(pContentArea);
  ASSERT(pNewRecord->pCurPageArea);
  pNewRecord->pCurPageArea->AddChild(pNewContentAreaLayoutItem);
  pNewRecord->pCurContentArea = pNewContentAreaLayoutItem;
}

void CXFA_LayoutPageMgr::FinishPaginatedPageSets() {
  CXFA_ContainerLayoutItem* pRootPageSetLayoutItem = m_pPageSetLayoutItemRoot;
  for (; pRootPageSetLayoutItem;
       pRootPageSetLayoutItem = static_cast<CXFA_ContainerLayoutItem*>(
           pRootPageSetLayoutItem->m_pNextSibling)) {
    CXFA_NodeIteratorTemplate<CXFA_ContainerLayoutItem,
                              PageSetContainerLayoutItem>
        sIterator(pRootPageSetLayoutItem);
    for (CXFA_ContainerLayoutItem* pPageSetLayoutItem = sIterator.GetCurrent();
         pPageSetLayoutItem; pPageSetLayoutItem = sIterator.MoveToNext()) {
      XFA_ATTRIBUTEENUM ePageRelation =
          pPageSetLayoutItem->m_pFormNode->JSNode()->GetEnum(
              XFA_Attribute::Relation);
      switch (ePageRelation) {
        case XFA_ATTRIBUTEENUM_OrderedOccurrence:
        default: { ProcessLastPageSet(); } break;
        case XFA_ATTRIBUTEENUM_SimplexPaginated:
        case XFA_ATTRIBUTEENUM_DuplexPaginated: {
          CXFA_LayoutItem* pLastPageAreaLayoutItem = nullptr;
          int32_t nPageAreaCount = 0;
          for (CXFA_LayoutItem* pPageAreaLayoutItem =
                   pPageSetLayoutItem->m_pFirstChild;
               pPageAreaLayoutItem;
               pPageAreaLayoutItem = pPageAreaLayoutItem->m_pNextSibling) {
            if (pPageAreaLayoutItem->m_pFormNode->GetElementType() !=
                XFA_Element::PageArea) {
              continue;
            }
            nPageAreaCount++;
            pLastPageAreaLayoutItem = pPageAreaLayoutItem;
          }
          if (!pLastPageAreaLayoutItem)
            break;

          if (!FindPageAreaFromPageSet_SimplexDuplex(
                  pPageSetLayoutItem->m_pFormNode, nullptr, nullptr, nullptr,
                  true, true, nPageAreaCount == 1 ? XFA_ATTRIBUTEENUM_Only
                                                  : XFA_ATTRIBUTEENUM_Last) &&
              (nPageAreaCount == 1 &&
               !FindPageAreaFromPageSet_SimplexDuplex(
                   pPageSetLayoutItem->m_pFormNode, nullptr, nullptr, nullptr,
                   true, true, XFA_ATTRIBUTEENUM_Last))) {
            break;
          }
          CXFA_Node* pNode = m_pCurPageArea;
          XFA_ATTRIBUTEENUM eCurChoice =
              pNode->JSNode()->GetEnum(XFA_Attribute::PagePosition);
          if (eCurChoice == XFA_ATTRIBUTEENUM_Last) {
            XFA_ATTRIBUTEENUM eOddOrEven =
                pNode->JSNode()->GetEnum(XFA_Attribute::OddOrEven);
            XFA_ATTRIBUTEENUM eLastChoice =
                pLastPageAreaLayoutItem->m_pFormNode->JSNode()->GetEnum(
                    XFA_Attribute::PagePosition);
            if (eLastChoice == XFA_ATTRIBUTEENUM_First &&
                (ePageRelation == XFA_ATTRIBUTEENUM_SimplexPaginated ||
                 eOddOrEven != XFA_ATTRIBUTEENUM_Odd)) {
              CXFA_ContainerRecord* pRecord = CreateContainerRecord();
              AddPageAreaLayoutItem(pRecord, pNode);
              break;
            }
          }
          bool bUsable = true;
          std::vector<float> rgUsedHeights;
          for (CXFA_LayoutItem* pChildLayoutItem =
                   pLastPageAreaLayoutItem->m_pFirstChild;
               pChildLayoutItem;
               pChildLayoutItem = pChildLayoutItem->m_pNextSibling) {
            if (pChildLayoutItem->m_pFormNode->GetElementType() !=
                XFA_Element::ContentArea) {
              continue;
            }
            float fUsedHeight = 0;
            for (CXFA_LayoutItem* pContentChildLayoutItem =
                     pChildLayoutItem->m_pFirstChild;
                 pContentChildLayoutItem;
                 pContentChildLayoutItem =
                     pContentChildLayoutItem->m_pNextSibling) {
              if (CXFA_ContentLayoutItem* pContent =
                      pContentChildLayoutItem->AsContentLayoutItem()) {
                fUsedHeight += pContent->m_sSize.height;
              }
            }
            rgUsedHeights.push_back(fUsedHeight);
          }
          int32_t iCurContentAreaIndex = -1;
          for (CXFA_Node* pContentAreaNode =
                   pNode->GetNodeItem(XFA_NODEITEM_FirstChild);
               pContentAreaNode;
               pContentAreaNode =
                   pContentAreaNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
            if (pContentAreaNode->GetElementType() !=
                XFA_Element::ContentArea) {
              continue;
            }
            iCurContentAreaIndex++;
            if (rgUsedHeights[iCurContentAreaIndex] >
                pContentAreaNode->JSNode()
                        ->GetMeasure(XFA_Attribute::H)
                        .ToUnit(XFA_Unit::Pt) +
                    XFA_LAYOUT_FLOAT_PERCISION) {
              bUsable = false;
              break;
            }
          }
          if (bUsable) {
            CXFA_LayoutItem* pChildLayoutItem =
                pLastPageAreaLayoutItem->m_pFirstChild;
            CXFA_Node* pContentAreaNode =
                pNode->GetNodeItem(XFA_NODEITEM_FirstChild);
            pLastPageAreaLayoutItem->m_pFormNode = pNode;
            while (pChildLayoutItem && pContentAreaNode) {
              if (pChildLayoutItem->m_pFormNode->GetElementType() !=
                  XFA_Element::ContentArea) {
                pChildLayoutItem = pChildLayoutItem->m_pNextSibling;
                continue;
              }
              if (pContentAreaNode->GetElementType() !=
                  XFA_Element::ContentArea) {
                pContentAreaNode =
                    pContentAreaNode->GetNodeItem(XFA_NODEITEM_NextSibling);
                continue;
              }
              pChildLayoutItem->m_pFormNode = pContentAreaNode;
              pChildLayoutItem = pChildLayoutItem->m_pNextSibling;
              pContentAreaNode =
                  pContentAreaNode->GetNodeItem(XFA_NODEITEM_NextSibling);
            }
          } else if (pNode->JSNode()->GetEnum(XFA_Attribute::PagePosition) ==
                     XFA_ATTRIBUTEENUM_Last) {
            CXFA_ContainerRecord* pRecord = CreateContainerRecord();
            AddPageAreaLayoutItem(pRecord, pNode);
          }
        } break;
      }
    }
  }
}

int32_t CXFA_LayoutPageMgr::GetPageCount() const {
  return pdfium::CollectionSize<int32_t>(m_PageArray);
}

CXFA_ContainerLayoutItem* CXFA_LayoutPageMgr::GetPage(int32_t index) const {
  if (!pdfium::IndexInBounds(m_PageArray, index))
    return nullptr;
  return m_PageArray[index];
}

int32_t CXFA_LayoutPageMgr::GetPageIndex(
    const CXFA_ContainerLayoutItem* pPage) const {
  auto it = std::find(m_PageArray.begin(), m_PageArray.end(), pPage);
  return it != m_PageArray.end() ? it - m_PageArray.begin() : -1;
}

bool CXFA_LayoutPageMgr::RunBreak(XFA_Element eBreakType,
                                  XFA_ATTRIBUTEENUM eTargetType,
                                  CXFA_Node* pTarget,
                                  bool bStartNew) {
  bool bRet = false;
  switch (eTargetType) {
    case XFA_ATTRIBUTEENUM_ContentArea:
      if (pTarget && pTarget->GetElementType() != XFA_Element::ContentArea)
        pTarget = nullptr;
      if (!pTarget ||
          m_CurrentContainerRecordIter == m_ProposedContainerRecords.end() ||
          pTarget !=
              GetCurrentContainerRecord()->pCurContentArea->m_pFormNode ||
          bStartNew) {
        CXFA_Node* pPageArea = nullptr;
        if (pTarget)
          pPageArea = pTarget->GetNodeItem(XFA_NODEITEM_Parent);

        pPageArea = GetNextAvailPageArea(pPageArea, pTarget);
        bRet = !!pPageArea;
      }
      break;
    case XFA_ATTRIBUTEENUM_PageArea:
      if (pTarget && pTarget->GetElementType() != XFA_Element::PageArea)
        pTarget = nullptr;
      if (!pTarget ||
          m_CurrentContainerRecordIter == m_ProposedContainerRecords.end() ||
          pTarget != GetCurrentContainerRecord()->pCurPageArea->m_pFormNode ||
          bStartNew) {
        CXFA_Node* pPageArea = GetNextAvailPageArea(pTarget, nullptr, true);
        bRet = !!pPageArea;
      }
      break;
    case XFA_ATTRIBUTEENUM_PageOdd:
      if (pTarget && pTarget->GetElementType() != XFA_Element::PageArea)
        pTarget = nullptr;
      break;
    case XFA_ATTRIBUTEENUM_PageEven:
      if (pTarget && pTarget->GetElementType() != XFA_Element::PageArea)
        pTarget = nullptr;
      break;
    case XFA_ATTRIBUTEENUM_Auto:
    default:
      break;
  }
  return bRet;
}

bool CXFA_LayoutPageMgr::ExecuteBreakBeforeOrAfter(
    CXFA_Node* pCurNode,
    bool bBefore,
    CXFA_Node*& pBreakLeaderTemplate,
    CXFA_Node*& pBreakTrailerTemplate) {
  XFA_Element eType = pCurNode->GetElementType();
  switch (eType) {
    case XFA_Element::BreakBefore:
    case XFA_Element::BreakAfter: {
      WideString wsBreakLeader;
      WideString wsBreakTrailer;
      CXFA_Node* pFormNode = pCurNode->GetNodeItem(
          XFA_NODEITEM_Parent, XFA_ObjectType::ContainerNode);
      CXFA_Node* pContainer = pFormNode->GetTemplateNode();
      bool bStartNew =
          pCurNode->JSNode()->GetInteger(XFA_Attribute::StartNew) != 0;
      CXFA_Node* pScript = pCurNode->GetFirstChildByClass(XFA_Element::Script);
      if (pScript && !XFA_LayoutPageMgr_RunBreakTestScript(pScript))
        return false;

      WideString wsTarget = pCurNode->JSNode()->GetCData(XFA_Attribute::Target);
      CXFA_Node* pTarget =
          ResolveBreakTarget(m_pTemplatePageSetRoot, true, wsTarget);
      wsBreakTrailer = pCurNode->JSNode()->GetCData(XFA_Attribute::Trailer);
      wsBreakLeader = pCurNode->JSNode()->GetCData(XFA_Attribute::Leader);
      pBreakLeaderTemplate =
          ResolveBreakTarget(pContainer, true, wsBreakLeader);
      pBreakTrailerTemplate =
          ResolveBreakTarget(pContainer, true, wsBreakTrailer);
      if (RunBreak(eType,
                   pCurNode->JSNode()->GetEnum(XFA_Attribute::TargetType),
                   pTarget, bStartNew)) {
        return true;
      }
      if (!m_ProposedContainerRecords.empty() &&
          m_CurrentContainerRecordIter == m_ProposedContainerRecords.begin() &&
          eType == XFA_Element::BreakBefore) {
        CXFA_Node* pParentNode = pFormNode->GetNodeItem(
            XFA_NODEITEM_Parent, XFA_ObjectType::ContainerNode);
        if (!pParentNode ||
            pFormNode !=
                pParentNode->GetNodeItem(XFA_NODEITEM_FirstChild,
                                         XFA_ObjectType::ContainerNode)) {
          break;
        }
        pParentNode = pParentNode->GetNodeItem(XFA_NODEITEM_Parent);
        if (!pParentNode ||
            pParentNode->GetElementType() != XFA_Element::Form) {
          break;
        }
        return true;
      }
      break;
    }
    case XFA_Element::Break: {
      bool bStartNew =
          pCurNode->JSNode()->GetInteger(XFA_Attribute::StartNew) != 0;
      WideString wsTarget = pCurNode->JSNode()->GetCData(
          bBefore ? XFA_Attribute::BeforeTarget : XFA_Attribute::AfterTarget);
      CXFA_Node* pTarget =
          ResolveBreakTarget(m_pTemplatePageSetRoot, true, wsTarget);
      if (RunBreak(bBefore ? XFA_Element::BreakBefore : XFA_Element::BreakAfter,
                   pCurNode->JSNode()->GetEnum(bBefore ? XFA_Attribute::Before
                                                       : XFA_Attribute::After),
                   pTarget, bStartNew)) {
        return true;
      }
      break;
    }
    default:
      break;
  }
  return false;
}

bool CXFA_LayoutPageMgr::ProcessBreakBeforeOrAfter(
    CXFA_Node* pBreakNode,
    bool bBefore,
    CXFA_Node*& pBreakLeaderNode,
    CXFA_Node*& pBreakTrailerNode,
    bool& bCreatePage) {
  CXFA_Node* pLeaderTemplate = nullptr;
  CXFA_Node* pTrailerTemplate = nullptr;
  CXFA_Node* pFormNode = pBreakNode->GetNodeItem(XFA_NODEITEM_Parent,
                                                 XFA_ObjectType::ContainerNode);
  if (XFA_ItemLayoutProcessor_IsTakingSpace(pFormNode)) {
    bCreatePage = ExecuteBreakBeforeOrAfter(pBreakNode, bBefore,
                                            pLeaderTemplate, pTrailerTemplate);
    CXFA_Document* pDocument = pBreakNode->GetDocument();
    CXFA_Node* pDataScope = nullptr;
    pFormNode = pFormNode->GetNodeItem(XFA_NODEITEM_Parent,
                                       XFA_ObjectType::ContainerNode);
    if (pLeaderTemplate) {
      if (!pDataScope)
        pDataScope = XFA_DataMerge_FindDataScope(pFormNode);

      pBreakLeaderNode = pDocument->DataMerge_CopyContainer(
          pLeaderTemplate, pFormNode, pDataScope, true, true, true);
      pDocument->DataMerge_UpdateBindingRelations(pBreakLeaderNode);
      SetLayoutGeneratedNodeFlag(pBreakLeaderNode);
    }
    if (pTrailerTemplate) {
      if (!pDataScope)
        pDataScope = XFA_DataMerge_FindDataScope(pFormNode);

      pBreakTrailerNode = pDocument->DataMerge_CopyContainer(
          pTrailerTemplate, pFormNode, pDataScope, true, true, true);
      pDocument->DataMerge_UpdateBindingRelations(pBreakTrailerNode);
      SetLayoutGeneratedNodeFlag(pBreakTrailerNode);
    }
    return true;
  }
  return false;
}

bool CXFA_LayoutPageMgr::ProcessBookendLeaderOrTrailer(
    CXFA_Node* pBookendNode,
    bool bLeader,
    CXFA_Node*& pBookendAppendNode) {
  CXFA_Node* pLeaderTemplate = nullptr;
  CXFA_Node* pFormNode = pBookendNode->GetNodeItem(
      XFA_NODEITEM_Parent, XFA_ObjectType::ContainerNode);
  if (ResolveBookendLeaderOrTrailer(pBookendNode, bLeader, pLeaderTemplate)) {
    CXFA_Document* pDocument = pBookendNode->GetDocument();
    CXFA_Node* pDataScope = nullptr;
    if (pLeaderTemplate) {
      if (!pDataScope)
        pDataScope = XFA_DataMerge_FindDataScope(pFormNode);

      pBookendAppendNode = pDocument->DataMerge_CopyContainer(
          pLeaderTemplate, pFormNode, pDataScope, true, true, true);
      pDocument->DataMerge_UpdateBindingRelations(pBookendAppendNode);
      SetLayoutGeneratedNodeFlag(pBookendAppendNode);
      return true;
    }
  }
  return false;
}

CXFA_Node* CXFA_LayoutPageMgr::BreakOverflow(CXFA_Node* pOverflowNode,
                                             CXFA_Node*& pLeaderTemplate,
                                             CXFA_Node*& pTrailerTemplate,
                                             bool bCreatePage) {
  CXFA_Node* pContainer =
      pOverflowNode
          ->GetNodeItem(XFA_NODEITEM_Parent, XFA_ObjectType::ContainerNode)
          ->GetTemplateNode();
  if (pOverflowNode->GetElementType() == XFA_Element::Break) {
    WideString wsOverflowLeader =
        pOverflowNode->JSNode()->GetCData(XFA_Attribute::OverflowLeader);
    WideString wsOverflowTarget =
        pOverflowNode->JSNode()->GetCData(XFA_Attribute::OverflowTarget);
    WideString wsOverflowTrailer =
        pOverflowNode->JSNode()->GetCData(XFA_Attribute::OverflowTrailer);
    if (wsOverflowTarget.IsEmpty() && wsOverflowLeader.IsEmpty() &&
        wsOverflowTrailer.IsEmpty()) {
      return nullptr;
    }

    if (!wsOverflowTarget.IsEmpty() && bCreatePage && !m_bCreateOverFlowPage) {
      CXFA_Node* pTarget =
          ResolveBreakTarget(m_pTemplatePageSetRoot, true, wsOverflowTarget);
      if (pTarget) {
        m_bCreateOverFlowPage = true;
        switch (pTarget->GetElementType()) {
          case XFA_Element::PageArea:
            RunBreak(XFA_Element::Overflow, XFA_ATTRIBUTEENUM_PageArea, pTarget,
                     true);
            break;
          case XFA_Element::ContentArea:
            RunBreak(XFA_Element::Overflow, XFA_ATTRIBUTEENUM_ContentArea,
                     pTarget, true);
            break;
          default:
            break;
        }
      }
    }
    if (!bCreatePage) {
      pLeaderTemplate = ResolveBreakTarget(pContainer, true, wsOverflowLeader);
      pTrailerTemplate =
          ResolveBreakTarget(pContainer, true, wsOverflowTrailer);
    }
    return pOverflowNode;
  }

  if (pOverflowNode->GetElementType() != XFA_Element::Overflow)
    return nullptr;

  WideString wsOverflowTarget =
      pOverflowNode->JSNode()->GetCData(XFA_Attribute::Target);
  if (!wsOverflowTarget.IsEmpty() && bCreatePage && !m_bCreateOverFlowPage) {
    CXFA_Node* pTarget =
        ResolveBreakTarget(m_pTemplatePageSetRoot, true, wsOverflowTarget);
    if (pTarget) {
      m_bCreateOverFlowPage = true;
      switch (pTarget->GetElementType()) {
        case XFA_Element::PageArea:
          RunBreak(XFA_Element::Overflow, XFA_ATTRIBUTEENUM_PageArea, pTarget,
                   true);
          break;
        case XFA_Element::ContentArea:
          RunBreak(XFA_Element::Overflow, XFA_ATTRIBUTEENUM_ContentArea,
                   pTarget, true);
          break;
        default:
          break;
      }
    }
  }
  if (!bCreatePage) {
    WideString wsLeader =
        pOverflowNode->JSNode()->GetCData(XFA_Attribute::Leader);
    WideString wsTrailer =
        pOverflowNode->JSNode()->GetCData(XFA_Attribute::Trailer);
    pLeaderTemplate = ResolveBreakTarget(pContainer, true, wsLeader);
    pTrailerTemplate = ResolveBreakTarget(pContainer, true, wsTrailer);
  }
  return pOverflowNode;
}

bool CXFA_LayoutPageMgr::ProcessOverflow(CXFA_Node* pFormNode,
                                         CXFA_Node*& pLeaderNode,
                                         CXFA_Node*& pTrailerNode,
                                         bool bDataMerge,
                                         bool bCreatePage) {
  if (!pFormNode)
    return false;

  CXFA_Node* pLeaderTemplate = nullptr;
  CXFA_Node* pTrailerTemplate = nullptr;
  bool bIsOverflowNode = false;
  if (pFormNode->GetElementType() == XFA_Element::Overflow ||
      pFormNode->GetElementType() == XFA_Element::Break) {
    bIsOverflowNode = true;
  }
  for (CXFA_Node* pCurNode =
           bIsOverflowNode ? pFormNode
                           : pFormNode->GetNodeItem(XFA_NODEITEM_FirstChild);
       pCurNode; pCurNode = pCurNode->GetNodeItem((XFA_NODEITEM_NextSibling))) {
    if (BreakOverflow(pCurNode, pLeaderTemplate, pTrailerTemplate,
                      bCreatePage)) {
      if (bIsOverflowNode)
        pFormNode = pCurNode->GetNodeItem(XFA_NODEITEM_Parent);

      CXFA_Document* pDocument = pCurNode->GetDocument();
      CXFA_Node* pDataScope = nullptr;
      if (pLeaderTemplate) {
        if (!pDataScope)
          pDataScope = XFA_DataMerge_FindDataScope(pFormNode);

        pLeaderNode = pDocument->DataMerge_CopyContainer(
            pLeaderTemplate, pFormNode, pDataScope, true, true, true);
        pDocument->DataMerge_UpdateBindingRelations(pLeaderNode);
        SetLayoutGeneratedNodeFlag(pLeaderNode);
      }
      if (pTrailerTemplate) {
        if (!pDataScope)
          pDataScope = XFA_DataMerge_FindDataScope(pFormNode);

        pTrailerNode = pDocument->DataMerge_CopyContainer(
            pTrailerTemplate, pFormNode, pDataScope, true, true, true);
        pDocument->DataMerge_UpdateBindingRelations(pTrailerNode);
        SetLayoutGeneratedNodeFlag(pTrailerNode);
      }
      return true;
    }
    if (bIsOverflowNode) {
      break;
    }
  }
  return false;
}

bool CXFA_LayoutPageMgr::ResolveBookendLeaderOrTrailer(
    CXFA_Node* pBookendNode,
    bool bLeader,
    CXFA_Node*& pBookendAppendTemplate) {
  CXFA_Node* pContainer =
      pBookendNode
          ->GetNodeItem(XFA_NODEITEM_Parent, XFA_ObjectType::ContainerNode)
          ->GetTemplateNode();
  if (pBookendNode->GetElementType() == XFA_Element::Break) {
    WideString leader = pBookendNode->JSNode()->GetCData(
        bLeader ? XFA_Attribute::BookendLeader : XFA_Attribute::BookendTrailer);
    if (!leader.IsEmpty()) {
      pBookendAppendTemplate = ResolveBreakTarget(pContainer, false, leader);
      return true;
    }
    return false;
  }

  if (pBookendNode->GetElementType() == XFA_Element::Bookend) {
    WideString leader = pBookendNode->JSNode()->GetCData(
        bLeader ? XFA_Attribute::Leader : XFA_Attribute::Trailer);
    pBookendAppendTemplate = ResolveBreakTarget(pContainer, true, leader);
    return true;
  }
  return false;
}

bool CXFA_LayoutPageMgr::FindPageAreaFromPageSet(CXFA_Node* pPageSet,
                                                 CXFA_Node* pStartChild,
                                                 CXFA_Node* pTargetPageArea,
                                                 CXFA_Node* pTargetContentArea,
                                                 bool bNewPage,
                                                 bool bQuery) {
  if (!pPageSet && !pStartChild)
    return false;

  if (IsPageSetRootOrderedOccurrence()) {
    return FindPageAreaFromPageSet_Ordered(pPageSet, pStartChild,
                                           pTargetPageArea, pTargetContentArea,
                                           bNewPage, bQuery);
  }
  XFA_ATTRIBUTEENUM ePreferredPosition =
      m_CurrentContainerRecordIter != m_ProposedContainerRecords.end()
          ? XFA_ATTRIBUTEENUM_Rest
          : XFA_ATTRIBUTEENUM_First;
  return FindPageAreaFromPageSet_SimplexDuplex(
      pPageSet, pStartChild, pTargetPageArea, pTargetContentArea, bNewPage,
      bQuery, ePreferredPosition);
}

bool CXFA_LayoutPageMgr::FindPageAreaFromPageSet_Ordered(
    CXFA_Node* pPageSet,
    CXFA_Node* pStartChild,
    CXFA_Node* pTargetPageArea,
    CXFA_Node* pTargetContentArea,
    bool bNewPage,
    bool bQuery) {
  int32_t iPageSetCount = 0;
  if (!pStartChild && !bQuery) {
    auto it = m_pPageSetMap.find(pPageSet);
    if (it != m_pPageSetMap.end())
      iPageSetCount = it->second;
    int32_t iMax = -1;
    CXFA_Node* pOccurNode = pPageSet->GetFirstChildByClass(XFA_Element::Occur);
    if (pOccurNode) {
      pdfium::Optional<int32_t> ret =
          pOccurNode->JSNode()->TryInteger(XFA_Attribute::Max, false);
      if (ret)
        iMax = *ret;
    }
    if (iMax >= 0 && iMax <= iPageSetCount)
      return false;
  }

  bool bRes = false;
  CXFA_Node* pCurrentNode =
      pStartChild ? pStartChild->GetNodeItem(XFA_NODEITEM_NextSibling)
                  : pPageSet->GetNodeItem(XFA_NODEITEM_FirstChild);
  for (; pCurrentNode;
       pCurrentNode = pCurrentNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
    if (pCurrentNode->GetElementType() == XFA_Element::PageArea) {
      if ((pTargetPageArea == pCurrentNode || !pTargetPageArea)) {
        if (!pCurrentNode->GetFirstChildByClass(XFA_Element::ContentArea)) {
          if (pTargetPageArea == pCurrentNode) {
            CreateMinPageRecord(pCurrentNode, true);
            pTargetPageArea = nullptr;
          }
          continue;
        }
        if (!bQuery) {
          CXFA_ContainerRecord* pNewRecord =
              CreateContainerRecord(pCurrentNode, !pStartChild);
          AddPageAreaLayoutItem(pNewRecord, pCurrentNode);
          if (!pTargetContentArea) {
            pTargetContentArea =
                pCurrentNode->GetFirstChildByClass(XFA_Element::ContentArea);
          }
          AddContentAreaLayoutItem(pNewRecord, pTargetContentArea);
        }
        m_pCurPageArea = pCurrentNode;
        m_nCurPageCount = 1;
        bRes = true;
        break;
      }
      if (!bQuery)
        CreateMinPageRecord(pCurrentNode, false);
    } else if (pCurrentNode->GetElementType() == XFA_Element::PageSet) {
      if (FindPageAreaFromPageSet_Ordered(pCurrentNode, nullptr,
                                          pTargetPageArea, pTargetContentArea,
                                          bNewPage, bQuery)) {
        bRes = true;
        break;
      }
      if (!bQuery)
        CreateMinPageSetRecord(pCurrentNode, true);
    }
  }
  if (!pStartChild && bRes && !bQuery)
    m_pPageSetMap[pPageSet] = ++iPageSetCount;
  return bRes;
}

bool CXFA_LayoutPageMgr::FindPageAreaFromPageSet_SimplexDuplex(
    CXFA_Node* pPageSet,
    CXFA_Node* pStartChild,
    CXFA_Node* pTargetPageArea,
    CXFA_Node* pTargetContentArea,
    bool bNewPage,
    bool bQuery,
    XFA_ATTRIBUTEENUM ePreferredPosition) {
  const XFA_ATTRIBUTEENUM eFallbackPosition = XFA_ATTRIBUTEENUM_Any;
  CXFA_Node* pPreferredPageArea = nullptr;
  CXFA_Node* pFallbackPageArea = nullptr;
  CXFA_Node* pCurrentNode = nullptr;
  if (!pStartChild || pStartChild->GetElementType() == XFA_Element::PageArea)
    pCurrentNode = pPageSet->GetNodeItem(XFA_NODEITEM_FirstChild);
  else
    pCurrentNode = pStartChild->GetNodeItem(XFA_NODEITEM_NextSibling);

  for (; pCurrentNode;
       pCurrentNode = pCurrentNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
    if (pCurrentNode->GetElementType() == XFA_Element::PageArea) {
      if (!MatchPageAreaOddOrEven(pCurrentNode))
        continue;

      XFA_ATTRIBUTEENUM eCurPagePosition =
          pCurrentNode->JSNode()->GetEnum(XFA_Attribute::PagePosition);
      if (ePreferredPosition == XFA_ATTRIBUTEENUM_Last) {
        if (eCurPagePosition != ePreferredPosition)
          continue;
        if (m_ePageSetMode == XFA_ATTRIBUTEENUM_SimplexPaginated ||
            pCurrentNode->JSNode()->GetEnum(XFA_Attribute::OddOrEven) ==
                XFA_ATTRIBUTEENUM_Any) {
          pPreferredPageArea = pCurrentNode;
          break;
        }
        CXFA_ContainerRecord* pNewRecord = CreateContainerRecord();
        AddPageAreaLayoutItem(pNewRecord, pCurrentNode);
        AddContentAreaLayoutItem(pNewRecord, pCurrentNode->GetFirstChildByClass(
                                                 XFA_Element::ContentArea));
        pPreferredPageArea = pCurrentNode;
        return false;
      }
      if (ePreferredPosition == XFA_ATTRIBUTEENUM_Only) {
        if (eCurPagePosition != ePreferredPosition)
          continue;
        if (m_ePageSetMode != XFA_ATTRIBUTEENUM_DuplexPaginated ||
            pCurrentNode->JSNode()->GetEnum(XFA_Attribute::OddOrEven) ==
                XFA_ATTRIBUTEENUM_Any) {
          pPreferredPageArea = pCurrentNode;
          break;
        }
        return false;
      }
      if ((pTargetPageArea == pCurrentNode || !pTargetPageArea)) {
        if (!pCurrentNode->GetFirstChildByClass(XFA_Element::ContentArea)) {
          if (pTargetPageArea == pCurrentNode) {
            CXFA_ContainerRecord* pNewRecord = CreateContainerRecord();
            AddPageAreaLayoutItem(pNewRecord, pCurrentNode);
            pTargetPageArea = nullptr;
          }
          continue;
        }
        if ((ePreferredPosition == XFA_ATTRIBUTEENUM_Rest &&
             eCurPagePosition == XFA_ATTRIBUTEENUM_Any) ||
            eCurPagePosition == ePreferredPosition) {
          pPreferredPageArea = pCurrentNode;
          break;
        } else if (eCurPagePosition == eFallbackPosition &&
                   !pFallbackPageArea) {
          pFallbackPageArea = pCurrentNode;
        }
      } else if (pTargetPageArea && !MatchPageAreaOddOrEven(pTargetPageArea)) {
        CXFA_ContainerRecord* pNewRecord = CreateContainerRecord();
        AddPageAreaLayoutItem(pNewRecord, pCurrentNode);
        AddContentAreaLayoutItem(pNewRecord, pCurrentNode->GetFirstChildByClass(
                                                 XFA_Element::ContentArea));
      }
    } else if (pCurrentNode->GetElementType() == XFA_Element::PageSet) {
      if (FindPageAreaFromPageSet_SimplexDuplex(
              pCurrentNode, nullptr, pTargetPageArea, pTargetContentArea,
              bNewPage, bQuery, ePreferredPosition)) {
        break;
      }
    }
  }

  CXFA_Node* pCurPageArea = nullptr;
  if (pPreferredPageArea)
    pCurPageArea = pPreferredPageArea;
  else if (pFallbackPageArea)
    pCurPageArea = pFallbackPageArea;

  if (!pCurPageArea)
    return false;

  if (!bQuery) {
    CXFA_ContainerRecord* pNewRecord = CreateContainerRecord();
    AddPageAreaLayoutItem(pNewRecord, pCurPageArea);
    if (!pTargetContentArea) {
      pTargetContentArea =
          pCurPageArea->GetFirstChildByClass(XFA_Element::ContentArea);
    }
    AddContentAreaLayoutItem(pNewRecord, pTargetContentArea);
  }
  m_pCurPageArea = pCurPageArea;
  return true;
}

bool CXFA_LayoutPageMgr::MatchPageAreaOddOrEven(CXFA_Node* pPageArea) {
  if (m_ePageSetMode != XFA_ATTRIBUTEENUM_DuplexPaginated)
    return true;

  pdfium::Optional<XFA_ATTRIBUTEENUM> ret =
      pPageArea->JSNode()->TryEnum(XFA_Attribute::OddOrEven, true);
  if (!ret || *ret == XFA_ATTRIBUTEENUM_Any)
    return true;

  int32_t iPageLast = GetPageCount() % 2;
  return *ret == XFA_ATTRIBUTEENUM_Odd ? iPageLast == 0 : iPageLast == 1;
}

CXFA_Node* CXFA_LayoutPageMgr::GetNextAvailPageArea(
    CXFA_Node* pTargetPageArea,
    CXFA_Node* pTargetContentArea,
    bool bNewPage,
    bool bQuery) {
  if (!m_pCurPageArea) {
    FindPageAreaFromPageSet(m_pTemplatePageSetRoot, nullptr, pTargetPageArea,
                            pTargetContentArea, bNewPage, bQuery);
    ASSERT(m_pCurPageArea);
    return m_pCurPageArea;
  }

  if (!pTargetPageArea || pTargetPageArea == m_pCurPageArea) {
    if (!bNewPage && GetNextContentArea(pTargetContentArea))
      return m_pCurPageArea;

    if (IsPageSetRootOrderedOccurrence()) {
      int32_t iMax = -1;
      CXFA_Node* pOccurNode =
          m_pCurPageArea->GetFirstChildByClass(XFA_Element::Occur);
      if (pOccurNode) {
        pdfium::Optional<int32_t> ret =
            pOccurNode->JSNode()->TryInteger(XFA_Attribute::Max, false);
        if (ret)
          iMax = *ret;
      }
      if ((iMax < 0 || m_nCurPageCount < iMax)) {
        if (!bQuery) {
          CXFA_ContainerRecord* pNewRecord =
              CreateContainerRecord(m_pCurPageArea);
          AddPageAreaLayoutItem(pNewRecord, m_pCurPageArea);
          if (!pTargetContentArea) {
            pTargetContentArea =
                m_pCurPageArea->GetFirstChildByClass(XFA_Element::ContentArea);
          }
          AddContentAreaLayoutItem(pNewRecord, pTargetContentArea);
        }
        m_nCurPageCount++;
        return m_pCurPageArea;
      }
    }
  }

  if (!bQuery && IsPageSetRootOrderedOccurrence())
    CreateMinPageRecord(m_pCurPageArea, false, true);
  if (FindPageAreaFromPageSet(m_pCurPageArea->GetNodeItem(XFA_NODEITEM_Parent),
                              m_pCurPageArea, pTargetPageArea,
                              pTargetContentArea, bNewPage, bQuery)) {
    return m_pCurPageArea;
  }

  CXFA_Node* pPageSet = m_pCurPageArea->GetNodeItem(XFA_NODEITEM_Parent);
  while (true) {
    if (FindPageAreaFromPageSet(pPageSet, nullptr, pTargetPageArea,
                                pTargetContentArea, bNewPage, bQuery)) {
      return m_pCurPageArea;
    }
    if (!bQuery && IsPageSetRootOrderedOccurrence())
      CreateMinPageSetRecord(pPageSet);
    if (FindPageAreaFromPageSet(nullptr, pPageSet, pTargetPageArea,
                                pTargetContentArea, bNewPage, bQuery)) {
      return m_pCurPageArea;
    }
    if (pPageSet == m_pTemplatePageSetRoot)
      break;

    pPageSet = pPageSet->GetNodeItem(XFA_NODEITEM_Parent);
  }
  return nullptr;
}

bool CXFA_LayoutPageMgr::GetNextContentArea(CXFA_Node* pContentArea) {
  CXFA_Node* pCurContentNode =
      GetCurrentContainerRecord()->pCurContentArea->m_pFormNode;
  if (!pContentArea) {
    pContentArea =
        pCurContentNode->GetNextSameClassSibling(XFA_Element::ContentArea);
    if (!pContentArea)
      return false;
  } else {
    if (pContentArea->GetNodeItem(XFA_NODEITEM_Parent) != m_pCurPageArea)
      return false;

    CXFA_ContainerLayoutItem* pContentAreaLayout = nullptr;
    if (!CheckContentAreaNotUsed(GetCurrentContainerRecord()->pCurPageArea,
                                 pContentArea, pContentAreaLayout)) {
      return false;
    }
    if (pContentAreaLayout) {
      if (pContentAreaLayout->m_pFormNode != pCurContentNode) {
        CXFA_ContainerRecord* pNewRecord = CreateContainerRecord();
        pNewRecord->pCurContentArea = pContentAreaLayout;
        return true;
      }
      return false;
    }
  }

  CXFA_ContainerRecord* pNewRecord = CreateContainerRecord();
  AddContentAreaLayoutItem(pNewRecord, pContentArea);
  return true;
}

void CXFA_LayoutPageMgr::InitPageSetMap() {
  if (!IsPageSetRootOrderedOccurrence())
    return;

  CXFA_NodeIterator sIterator(m_pTemplatePageSetRoot);
  for (CXFA_Node* pPageSetNode = sIterator.GetCurrent(); pPageSetNode;
       pPageSetNode = sIterator.MoveToNext()) {
    if (pPageSetNode->GetElementType() == XFA_Element::PageSet) {
      XFA_ATTRIBUTEENUM eRelation =
          pPageSetNode->JSNode()->GetEnum(XFA_Attribute::Relation);
      if (eRelation == XFA_ATTRIBUTEENUM_OrderedOccurrence)
        m_pPageSetMap[pPageSetNode] = 0;
    }
  }
}

int32_t CXFA_LayoutPageMgr::CreateMinPageRecord(CXFA_Node* pPageArea,
                                                bool bTargetPageArea,
                                                bool bCreateLast) {
  if (!pPageArea)
    return 0;

  int32_t iMin = 0;
  pdfium::Optional<int32_t> ret;
  CXFA_Node* pOccurNode = pPageArea->GetFirstChildByClass(XFA_Element::Occur);
  if (pOccurNode) {
    ret = pOccurNode->JSNode()->TryInteger(XFA_Attribute::Min, false);
    if (ret)
      iMin = *ret;
  }

  if (!ret && !bTargetPageArea)
    return iMin;

  CXFA_Node* pContentArea =
      pPageArea->GetFirstChildByClass(XFA_Element::ContentArea);
  if (iMin < 1 && bTargetPageArea && !pContentArea)
    iMin = 1;

  int32_t i = 0;
  if (bCreateLast)
    i = m_nCurPageCount;

  for (; i < iMin; i++) {
    CXFA_ContainerRecord* pNewRecord = CreateContainerRecord();
    AddPageAreaLayoutItem(pNewRecord, pPageArea);
    AddContentAreaLayoutItem(pNewRecord, pContentArea);
  }
  return iMin;
}

void CXFA_LayoutPageMgr::CreateMinPageSetRecord(CXFA_Node* pPageSet,
                                                bool bCreateAll) {
  if (!pPageSet)
    return;

  auto it = m_pPageSetMap.find(pPageSet);
  if (it == m_pPageSetMap.end())
    return;

  int32_t iCurSetCount = it->second;
  if (bCreateAll)
    iCurSetCount = 0;

  CXFA_Node* pOccurNode = pPageSet->GetFirstChildByClass(XFA_Element::Occur);
  if (!pOccurNode)
    return;

  pdfium::Optional<int32_t> iMin =
      pOccurNode->JSNode()->TryInteger(XFA_Attribute::Min, false);
  if (!iMin || iCurSetCount >= *iMin)
    return;

  for (int32_t i = 0; i < *iMin - iCurSetCount; i++) {
    for (CXFA_Node* node = pPageSet->GetNodeItem(XFA_NODEITEM_FirstChild); node;
         node = node->GetNodeItem(XFA_NODEITEM_NextSibling)) {
      if (node->GetElementType() == XFA_Element::PageArea)
        CreateMinPageRecord(node, false);
      else if (node->GetElementType() == XFA_Element::PageSet)
        CreateMinPageSetRecord(node, true);
    }
  }
  m_pPageSetMap[pPageSet] = *iMin;
}

void CXFA_LayoutPageMgr::CreateNextMinRecord(CXFA_Node* pRecordNode) {
  if (!pRecordNode)
    return;

  for (CXFA_Node* pCurrentNode =
           pRecordNode->GetNodeItem(XFA_NODEITEM_NextSibling);
       pCurrentNode;
       pCurrentNode = pCurrentNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
    if (pCurrentNode->GetElementType() == XFA_Element::PageArea)
      CreateMinPageRecord(pCurrentNode, false);
    else if (pCurrentNode->GetElementType() == XFA_Element::PageSet)
      CreateMinPageSetRecord(pCurrentNode, true);
  }
}

void CXFA_LayoutPageMgr::ProcessLastPageSet() {
  CreateMinPageRecord(m_pCurPageArea, false, true);
  CreateNextMinRecord(m_pCurPageArea);
  CXFA_Node* pPageSet = m_pCurPageArea->GetNodeItem(XFA_NODEITEM_Parent);
  while (true) {
    CreateMinPageSetRecord(pPageSet);
    if (pPageSet == m_pTemplatePageSetRoot)
      break;

    CreateNextMinRecord(pPageSet);
    pPageSet = pPageSet->GetNodeItem(XFA_NODEITEM_Parent);
  }
}

bool CXFA_LayoutPageMgr::GetNextAvailContentHeight(float fChildHeight) {
  CXFA_Node* pCurContentNode =
      GetCurrentContainerRecord()->pCurContentArea->m_pFormNode;
  if (!pCurContentNode)
    return false;

  pCurContentNode =
      pCurContentNode->GetNextSameClassSibling(XFA_Element::ContentArea);
  if (pCurContentNode) {
    float fNextContentHeight = pCurContentNode->JSNode()
                                   ->GetMeasure(XFA_Attribute::H)
                                   .ToUnit(XFA_Unit::Pt);
    return fNextContentHeight > fChildHeight;
  }

  CXFA_Node* pPageNode = GetCurrentContainerRecord()->pCurPageArea->m_pFormNode;
  CXFA_Node* pOccurNode = pPageNode->GetFirstChildByClass(XFA_Element::Occur);
  int32_t iMax = 0;
  pdfium::Optional<int32_t> ret;
  if (pOccurNode) {
    ret = pOccurNode->JSNode()->TryInteger(XFA_Attribute::Max, false);
    if (ret)
      iMax = *ret;
  }
  if (ret) {
    if (m_nCurPageCount == iMax) {
      CXFA_Node* pSrcPage = m_pCurPageArea;
      int32_t nSrcPageCount = m_nCurPageCount;
      auto psSrcIter = GetTailPosition();
      CXFA_Node* pNextPage =
          GetNextAvailPageArea(nullptr, nullptr, false, true);
      m_pCurPageArea = pSrcPage;
      m_nCurPageCount = nSrcPageCount;
      CXFA_ContainerRecord* pPrevRecord = *psSrcIter++;
      while (psSrcIter != m_ProposedContainerRecords.end()) {
        auto psSaveIter = psSrcIter;
        CXFA_ContainerRecord* pInsertRecord = *psSrcIter++;
        RemoveLayoutRecord(pInsertRecord, pPrevRecord);
        delete pInsertRecord;
        m_ProposedContainerRecords.erase(psSaveIter);
      }
      if (pNextPage) {
        CXFA_Node* pContentArea =
            pNextPage->GetFirstChildByClass(XFA_Element::ContentArea);
        if (pContentArea) {
          float fNextContentHeight = pContentArea->JSNode()
                                         ->GetMeasure(XFA_Attribute::H)
                                         .ToUnit(XFA_Unit::Pt);
          if (fNextContentHeight > fChildHeight)
            return true;
        }
      }
      return false;
    }
  }

  CXFA_Node* pContentArea =
      pPageNode->GetFirstChildByClass(XFA_Element::ContentArea);
  float fNextContentHeight =
      pContentArea->JSNode()->GetMeasure(XFA_Attribute::H).ToUnit(XFA_Unit::Pt);
  if (fNextContentHeight < XFA_LAYOUT_FLOAT_PERCISION)
    return true;
  if (fNextContentHeight > fChildHeight)
    return true;
  return false;
}

void CXFA_LayoutPageMgr::ClearData() {
  if (!m_pTemplatePageSetRoot)
    return;

  auto sPos = m_ProposedContainerRecords.begin();
  while (sPos != m_ProposedContainerRecords.end()) {
    CXFA_ContainerRecord* pRecord = *sPos++;
    delete pRecord;
  }
  m_ProposedContainerRecords.clear();
  m_CurrentContainerRecordIter = m_ProposedContainerRecords.end();
  m_pCurPageArea = nullptr;
  m_nCurPageCount = 0;
  m_bCreateOverFlowPage = false;
  m_pPageSetMap.clear();
}

void CXFA_LayoutPageMgr::SaveLayoutItem(CXFA_LayoutItem* pParentLayoutItem) {
  CXFA_LayoutItem* pNextLayoutItem;
  CXFA_LayoutItem* pCurLayoutItem = pParentLayoutItem->m_pFirstChild;
  while (pCurLayoutItem) {
    pNextLayoutItem = pCurLayoutItem->m_pNextSibling;
    if (pCurLayoutItem->IsContentLayoutItem()) {
      if (pCurLayoutItem->m_pFormNode->HasRemovedChildren()) {
        CXFA_FFNotify* pNotify =
            m_pTemplatePageSetRoot->GetDocument()->GetNotify();
        CXFA_LayoutProcessor* pDocLayout =
            m_pTemplatePageSetRoot->GetDocument()->GetDocLayout();
        if (pCurLayoutItem->m_pFirstChild)
          SyncRemoveLayoutItem(pCurLayoutItem, pNotify, pDocLayout);

        pNotify->OnLayoutItemRemoving(pDocLayout, pCurLayoutItem);
        delete pCurLayoutItem;
        pCurLayoutItem = pNextLayoutItem;
        continue;
      }

      if (pCurLayoutItem->m_pFormNode->IsLayoutGeneratedNode()) {
        CXFA_NodeIteratorTemplate<CXFA_Node, CXFA_TraverseStrategy_XFANode>
            sIterator(pCurLayoutItem->m_pFormNode);
        for (CXFA_Node* pNode = sIterator.GetCurrent(); pNode;
             pNode = sIterator.MoveToNext()) {
          pNode->SetFlag(XFA_NodeFlag_UnusedNode, false);
        }
      }
    }

    if (pCurLayoutItem->m_pFirstChild)
      SaveLayoutItem(pCurLayoutItem);

    pCurLayoutItem->m_pParent = nullptr;
    pCurLayoutItem->m_pNextSibling = nullptr;
    pCurLayoutItem->m_pFirstChild = nullptr;
    if (!pCurLayoutItem->IsContentLayoutItem() &&
        pCurLayoutItem->m_pFormNode->GetElementType() !=
            XFA_Element::PageArea) {
      delete pCurLayoutItem;
    }
    pCurLayoutItem = pNextLayoutItem;
  }
}

CXFA_Node* CXFA_LayoutPageMgr::QueryOverflow(CXFA_Node* pFormNode) {
  for (CXFA_Node* pCurNode = pFormNode->GetNodeItem(XFA_NODEITEM_FirstChild);
       pCurNode; pCurNode = pCurNode->GetNodeItem((XFA_NODEITEM_NextSibling))) {
    if (pCurNode->GetElementType() == XFA_Element::Break) {
      WideString wsOverflowLeader =
          pCurNode->JSNode()->GetCData(XFA_Attribute::OverflowLeader);
      WideString wsOverflowTarget =
          pCurNode->JSNode()->GetCData(XFA_Attribute::OverflowTarget);
      WideString wsOverflowTrailer =
          pCurNode->JSNode()->GetCData(XFA_Attribute::OverflowTrailer);

      if (!wsOverflowLeader.IsEmpty() || !wsOverflowTrailer.IsEmpty() ||
          !wsOverflowTarget.IsEmpty()) {
        return pCurNode;
      }
      return nullptr;
    }
    if (pCurNode->GetElementType() == XFA_Element::Overflow)
      return pCurNode;
  }
  return nullptr;
}

void CXFA_LayoutPageMgr::MergePageSetContents() {
  CXFA_Document* pDocument = m_pTemplatePageSetRoot->GetDocument();
  CXFA_FFNotify* pNotify = pDocument->GetNotify();
  CXFA_LayoutProcessor* pDocLayout = pDocument->GetDocLayout();
  CXFA_ContainerLayoutItem* pRootLayout = GetRootLayoutItem();
  for (CXFA_Node* pPageNode : pDocument->m_pPendingPageSet) {
    CXFA_NodeIteratorTemplate<CXFA_Node, CXFA_TraverseStrategy_XFANode>
        sIterator(pPageNode);
    for (CXFA_Node* pNode = sIterator.GetCurrent(); pNode;
         pNode = sIterator.MoveToNext()) {
      if (pNode->IsContainerNode()) {
        CXFA_Node* pBindNode = pNode->GetBindData();
        if (pBindNode) {
          pBindNode->RemoveBindItem(pNode);
          pNode->JSNode()->SetBindingNode(nullptr);
        }
      }
      pNode->SetFlag(XFA_NodeFlag_UnusedNode, true);
    }
  }

  int32_t iIndex = 0;
  for (; pRootLayout; pRootLayout = static_cast<CXFA_ContainerLayoutItem*>(
                          pRootLayout->m_pNextSibling)) {
    CXFA_Node* pPendingPageSet = nullptr;
    CXFA_NodeIteratorTemplate<
        CXFA_ContainerLayoutItem,
        CXFA_TraverseStrategy_ContentAreaContainerLayoutItem>
        iterator(pRootLayout);
    CXFA_ContainerLayoutItem* pRootPageSetContainerItem = iterator.GetCurrent();
    ASSERT(pRootPageSetContainerItem->m_pFormNode->GetElementType() ==
           XFA_Element::PageSet);
    if (iIndex <
        pdfium::CollectionSize<int32_t>(pDocument->m_pPendingPageSet)) {
      pPendingPageSet = pDocument->m_pPendingPageSet[iIndex];
      iIndex++;
    }
    if (!pPendingPageSet) {
      if (pRootPageSetContainerItem->m_pFormNode->GetPacketID() ==
          XFA_XDPPACKET_Template) {
        pPendingPageSet =
            pRootPageSetContainerItem->m_pFormNode->CloneTemplateToForm(false);
      } else {
        pPendingPageSet = pRootPageSetContainerItem->m_pFormNode;
      }
    }
    if (pRootPageSetContainerItem->m_pFormNode->JSNode()->GetLayoutItem() ==
        pRootPageSetContainerItem) {
      pRootPageSetContainerItem->m_pFormNode->JSNode()->SetLayoutItem(nullptr);
    }
    pRootPageSetContainerItem->m_pFormNode = pPendingPageSet;
    pPendingPageSet->ClearFlag(XFA_NodeFlag_UnusedNode);
    for (CXFA_ContainerLayoutItem* pContainerItem = iterator.MoveToNext();
         pContainerItem; pContainerItem = iterator.MoveToNext()) {
      CXFA_Node* pNode = pContainerItem->m_pFormNode;
      if (pNode->GetPacketID() != XFA_XDPPACKET_Template)
        continue;

      switch (pNode->GetElementType()) {
        case XFA_Element::PageSet: {
          CXFA_Node* pParentNode = pContainerItem->m_pParent->m_pFormNode;
          pContainerItem->m_pFormNode = XFA_NodeMerge_CloneOrMergeContainer(
              pDocument, pParentNode, pContainerItem->m_pFormNode, true,
              nullptr);
          break;
        }
        case XFA_Element::PageArea: {
          CXFA_LayoutItem* pFormLayout = pContainerItem;
          CXFA_Node* pParentNode = pContainerItem->m_pParent->m_pFormNode;
          bool bIsExistForm = true;
          for (int32_t iLevel = 0; iLevel < 3; iLevel++) {
            pFormLayout = pFormLayout->m_pFirstChild;
            if (iLevel == 2) {
              while (pFormLayout &&
                     !XFA_ItemLayoutProcessor_IsTakingSpace(
                         pFormLayout->m_pFormNode)) {
                pFormLayout = pFormLayout->m_pNextSibling;
              }
            }
            if (!pFormLayout) {
              bIsExistForm = false;
              break;
            }
          }
          if (bIsExistForm) {
            CXFA_Node* pNewSubform = pFormLayout->m_pFormNode;
            if (pContainerItem->m_pOldSubform &&
                pContainerItem->m_pOldSubform != pNewSubform) {
              CXFA_Node* pExistingNode = XFA_DataMerge_FindFormDOMInstance(
                  pDocument, pContainerItem->m_pFormNode->GetElementType(),
                  pContainerItem->m_pFormNode->GetNameHash(), pParentNode);
              CXFA_ContainerIterator sIterator(pExistingNode);
              for (CXFA_Node* pIter = sIterator.GetCurrent(); pIter;
                   pIter = sIterator.MoveToNext()) {
                if (pIter->GetElementType() != XFA_Element::ContentArea) {
                  CXFA_LayoutItem* pLayoutItem =
                      pIter->JSNode()->GetLayoutItem();
                  if (pLayoutItem) {
                    pNotify->OnLayoutItemRemoving(pDocLayout, pLayoutItem);
                    delete pLayoutItem;
                  }
                }
              }
              if (pExistingNode) {
                pParentNode->RemoveChild(pExistingNode, true);
              }
            }
            pContainerItem->m_pOldSubform = pNewSubform;
          }
          pContainerItem->m_pFormNode = pDocument->DataMerge_CopyContainer(
              pContainerItem->m_pFormNode, pParentNode,
              ToNode(pDocument->GetXFAObject(XFA_HASHCODE_Record)), true, true,
              true);
          break;
        }
        case XFA_Element::ContentArea: {
          CXFA_Node* pParentNode = pContainerItem->m_pParent->m_pFormNode;
          for (CXFA_Node* pChildNode =
                   pParentNode->GetNodeItem(XFA_NODEITEM_FirstChild);
               pChildNode;
               pChildNode = pChildNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
            if (pChildNode->GetTemplateNode() != pContainerItem->m_pFormNode) {
              continue;
            }
            pContainerItem->m_pFormNode = pChildNode;
            break;
          }
          break;
        }
        default:
          break;
      }
    }
    if (!pPendingPageSet->GetNodeItem(XFA_NODEITEM_Parent)) {
      CXFA_Node* pFormToplevelSubform =
          pDocument->GetXFAObject(XFA_HASHCODE_Form)
              ->AsNode()
              ->GetFirstChildByClass(XFA_Element::Subform);
      pFormToplevelSubform->InsertChild(pPendingPageSet, nullptr);
    }
    pDocument->DataMerge_UpdateBindingRelations(pPendingPageSet);
    pPendingPageSet->SetFlag(XFA_NodeFlag_Initialized, true);
  }

  CXFA_Node* pPageSet = GetRootLayoutItem()->m_pFormNode;
  while (pPageSet) {
    CXFA_Node* pNextPageSet =
        pPageSet->GetNextSameClassSibling(XFA_Element::PageSet);
    CXFA_NodeIteratorTemplate<CXFA_Node, CXFA_TraverseStrategy_XFANode>
        sIterator(pPageSet);
    CXFA_Node* pNode = sIterator.GetCurrent();
    while (pNode) {
      if (pNode->IsUnusedNode()) {
        if (pNode->IsContainerNode()) {
          XFA_Element eType = pNode->GetElementType();
          if (eType == XFA_Element::PageArea || eType == XFA_Element::PageSet) {
            CXFA_ContainerIterator iteChild(pNode);
            CXFA_Node* pChildNode = iteChild.MoveToNext();
            for (; pChildNode; pChildNode = iteChild.MoveToNext()) {
              CXFA_LayoutItem* pLayoutItem =
                  pChildNode->JSNode()->GetLayoutItem();
              if (pLayoutItem) {
                pNotify->OnLayoutItemRemoving(pDocLayout, pLayoutItem);
                delete pLayoutItem;
              }
            }
          } else if (eType != XFA_Element::ContentArea) {
            CXFA_LayoutItem* pLayoutItem = pNode->JSNode()->GetLayoutItem();
            if (pLayoutItem) {
              pNotify->OnLayoutItemRemoving(pDocLayout, pLayoutItem);
              delete pLayoutItem;
            }
          }
          CXFA_Node* pNext = sIterator.SkipChildrenAndMoveToNext();
          pNode->GetNodeItem(XFA_NODEITEM_Parent)->RemoveChild(pNode, true);
          pNode = pNext;
        } else {
          pNode->ClearFlag(XFA_NodeFlag_UnusedNode);
          pNode->SetFlag(XFA_NodeFlag_Initialized, true);
          pNode = sIterator.MoveToNext();
        }
      } else {
        pNode->SetFlag(XFA_NodeFlag_Initialized, true);
        pNode = sIterator.MoveToNext();
      }
    }
    pPageSet = pNextPageSet;
  }
}

void CXFA_LayoutPageMgr::LayoutPageSetContents() {
  CXFA_ContainerLayoutItem* pRootLayoutItem = GetRootLayoutItem();
  for (; pRootLayoutItem;
       pRootLayoutItem = static_cast<CXFA_ContainerLayoutItem*>(
           pRootLayoutItem->m_pNextSibling)) {
    CXFA_NodeIteratorTemplate<
        CXFA_ContainerLayoutItem,
        CXFA_TraverseStrategy_ContentAreaContainerLayoutItem>
        iterator(pRootLayoutItem);
    for (CXFA_ContainerLayoutItem* pContainerItem = iterator.GetCurrent();
         pContainerItem; pContainerItem = iterator.MoveToNext()) {
      CXFA_Node* pNode = pContainerItem->m_pFormNode;
      switch (pNode->GetElementType()) {
        case XFA_Element::PageArea:
          m_pLayoutProcessor->GetRootRootItemLayoutProcessor()
              ->DoLayoutPageArea(pContainerItem);
          break;
        default:
          break;
      }
    }
  }
}

void CXFA_LayoutPageMgr::SyncLayoutData() {
  MergePageSetContents();
  LayoutPageSetContents();
  CXFA_FFNotify* pNotify = m_pTemplatePageSetRoot->GetDocument()->GetNotify();
  int32_t nPageIdx = -1;
  CXFA_ContainerLayoutItem* pRootLayoutItem = GetRootLayoutItem();
  for (; pRootLayoutItem;
       pRootLayoutItem = static_cast<CXFA_ContainerLayoutItem*>(
           pRootLayoutItem->m_pNextSibling)) {
    CXFA_NodeIteratorTemplate<
        CXFA_ContainerLayoutItem,
        CXFA_TraverseStrategy_ContentAreaContainerLayoutItem>
        iteratorParent(pRootLayoutItem);
    for (CXFA_ContainerLayoutItem* pContainerItem = iteratorParent.GetCurrent();
         pContainerItem; pContainerItem = iteratorParent.MoveToNext()) {
      switch (pContainerItem->m_pFormNode->GetElementType()) {
        case XFA_Element::PageArea: {
          nPageIdx++;
          uint32_t dwRelevant =
              XFA_WidgetStatus_Viewable | XFA_WidgetStatus_Printable;
          CXFA_NodeIteratorTemplate<CXFA_LayoutItem,
                                    CXFA_TraverseStrategy_LayoutItem>
              iterator(pContainerItem);
          CXFA_LayoutItem* pChildLayoutItem = iterator.GetCurrent();
          while (pChildLayoutItem) {
            CXFA_ContentLayoutItem* pContentItem =
                pChildLayoutItem->AsContentLayoutItem();
            if (!pContentItem) {
              pChildLayoutItem = iterator.MoveToNext();
              continue;
            }
            bool bVisible =
                (pContentItem->m_pFormNode->JSNode()->GetEnum(
                     XFA_Attribute::Presence) == XFA_ATTRIBUTEENUM_Visible);
            uint32_t dwRelevantChild =
                GetRelevant(pContentItem->m_pFormNode, dwRelevant);
            SyncContainer(pNotify, m_pLayoutProcessor, pContentItem,
                          dwRelevantChild, bVisible, nPageIdx);
            pChildLayoutItem = iterator.SkipChildrenAndMoveToNext();
          }
          break;
        }
        default:
          break;
      }
    }
  }

  int32_t nPage = pdfium::CollectionSize<int32_t>(m_PageArray);
  for (int32_t i = nPage - 1; i >= m_nAvailPages; i--) {
    CXFA_ContainerLayoutItem* pPage = m_PageArray[i];
    m_PageArray.erase(m_PageArray.begin() + i);
    pNotify->OnPageEvent(pPage, XFA_PAGEVIEWEVENT_PostRemoved);
    delete pPage;
  }
  ClearData();
}

void XFA_ReleaseLayoutItem_NoPageArea(CXFA_LayoutItem* pLayoutItem) {
  CXFA_LayoutItem *pNext, *pNode = pLayoutItem->m_pFirstChild;
  while (pNode) {
    pNext = pNode->m_pNextSibling;
    pNode->m_pParent = nullptr;
    XFA_ReleaseLayoutItem_NoPageArea(pNode);
    pNode = pNext;
  }
  if (pLayoutItem->m_pFormNode->GetElementType() != XFA_Element::PageArea)
    delete pLayoutItem;
}

void CXFA_LayoutPageMgr::PrepareLayout() {
  m_pPageSetCurRoot = nullptr;
  m_ePageSetMode = XFA_ATTRIBUTEENUM_OrderedOccurrence;
  m_nAvailPages = 0;
  ClearData();
  if (!m_pPageSetLayoutItemRoot)
    return;

  CXFA_ContainerLayoutItem* pRootLayoutItem = m_pPageSetLayoutItemRoot;
  if (pRootLayoutItem &&
      pRootLayoutItem->m_pFormNode->GetPacketID() == XFA_XDPPACKET_Form) {
    CXFA_Node* pPageSetFormNode = pRootLayoutItem->m_pFormNode;
    pRootLayoutItem->m_pFormNode->GetDocument()->m_pPendingPageSet.clear();
    if (pPageSetFormNode->HasRemovedChildren()) {
      XFA_ReleaseLayoutItem(pRootLayoutItem);
      m_pPageSetLayoutItemRoot = nullptr;
      pRootLayoutItem = nullptr;
      pPageSetFormNode = nullptr;
      m_PageArray.clear();
    }
    while (pPageSetFormNode) {
      CXFA_Node* pNextPageSet =
          pPageSetFormNode->GetNextSameClassSibling(XFA_Element::PageSet);
      pPageSetFormNode->GetNodeItem(XFA_NODEITEM_Parent)
          ->RemoveChild(pPageSetFormNode, false);
      pRootLayoutItem->m_pFormNode->GetDocument()->m_pPendingPageSet.push_back(
          pPageSetFormNode);
      pPageSetFormNode = pNextPageSet;
    }
  }
  pRootLayoutItem = m_pPageSetLayoutItemRoot;
  CXFA_ContainerLayoutItem* pNextLayout = nullptr;
  for (; pRootLayoutItem; pRootLayoutItem = pNextLayout) {
    pNextLayout =
        static_cast<CXFA_ContainerLayoutItem*>(pRootLayoutItem->m_pNextSibling);
    SaveLayoutItem(pRootLayoutItem);
    delete pRootLayoutItem;
  }
  m_pPageSetLayoutItemRoot = nullptr;
}
