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

#include "xfa/fxfa/layout/cxfa_layoutprocessor.h"

#include "fxjs/xfa/cjx_object.h"
#include "third_party/base/stl_util.h"
#include "v8/include/cppgc/heap.h"
#include "xfa/fxfa/layout/cxfa_contentlayoutitem.h"
#include "xfa/fxfa/layout/cxfa_contentlayoutprocessor.h"
#include "xfa/fxfa/layout/cxfa_viewlayoutprocessor.h"
#include "xfa/fxfa/parser/cxfa_document.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_subform.h"
#include "xfa/fxfa/parser/xfa_document_datamerger_imp.h"
#include "xfa/fxfa/parser/xfa_utils.h"

// static
CXFA_LayoutProcessor* CXFA_LayoutProcessor::FromDocument(
    const CXFA_Document* pXFADoc) {
  return static_cast<CXFA_LayoutProcessor*>(pXFADoc->GetLayoutProcessor());
}

CXFA_LayoutProcessor::CXFA_LayoutProcessor(cppgc::Heap* pHeap)
    : m_pHeap(pHeap) {}

CXFA_LayoutProcessor::~CXFA_LayoutProcessor() = default;

void CXFA_LayoutProcessor::Trace(cppgc::Visitor* visitor) const {
  CXFA_Document::LayoutProcessorIface::Trace(visitor);
  visitor->Trace(m_pViewLayoutProcessor);
  visitor->Trace(m_pContentLayoutProcessor);
  for (const auto& container : m_rgChangedContainers)
    visitor->Trace(container);
}

void CXFA_LayoutProcessor::SetForceRelayout(bool bForceRestart) {
  m_bNeedLayout = bForceRestart;
}

int32_t CXFA_LayoutProcessor::StartLayout(bool bForceRestart) {
  if (!bForceRestart && !NeedLayout())
    return 100;

  m_pContentLayoutProcessor = nullptr;
  m_nProgressCounter = 0;
  CXFA_Node* pFormPacketNode =
      ToNode(GetDocument()->GetXFAObject(XFA_HASHCODE_Form));
  if (!pFormPacketNode)
    return -1;

  CXFA_Subform* pFormRoot =
      pFormPacketNode->GetFirstChildByClass<CXFA_Subform>(XFA_Element::Subform);
  if (!pFormRoot)
    return -1;

  if (!m_pViewLayoutProcessor) {
    m_pViewLayoutProcessor =
        cppgc::MakeGarbageCollected<CXFA_ViewLayoutProcessor>(
            GetHeap()->GetAllocationHandle(), GetHeap(), this);
  }
  if (!m_pViewLayoutProcessor->InitLayoutPage(pFormRoot))
    return -1;

  if (!m_pViewLayoutProcessor->PrepareFirstPage(pFormRoot))
    return -1;

  m_pContentLayoutProcessor =
      cppgc::MakeGarbageCollected<CXFA_ContentLayoutProcessor>(
          GetHeap()->GetAllocationHandle(), GetHeap(), pFormRoot,
          m_pViewLayoutProcessor);
  m_nProgressCounter = 1;
  return 0;
}

int32_t CXFA_LayoutProcessor::DoLayout() {
  if (m_nProgressCounter < 1)
    return -1;

  CXFA_ContentLayoutProcessor::Result eStatus;
  CXFA_Node* pFormNode = m_pContentLayoutProcessor->GetFormNode();
  float fPosX =
      pFormNode->JSObject()->GetMeasureInUnit(XFA_Attribute::X, XFA_Unit::Pt);
  float fPosY =
      pFormNode->JSObject()->GetMeasureInUnit(XFA_Attribute::Y, XFA_Unit::Pt);
  do {
    float fAvailHeight = m_pViewLayoutProcessor->GetAvailHeight();
    eStatus =
        m_pContentLayoutProcessor->DoLayout(true, fAvailHeight, fAvailHeight);
    if (eStatus != CXFA_ContentLayoutProcessor::Result::kDone)
      m_nProgressCounter++;

    CXFA_ContentLayoutItem* pLayoutItem =
        m_pContentLayoutProcessor->ExtractLayoutItem();
    if (pLayoutItem)
      pLayoutItem->m_sPos = CFX_PointF(fPosX, fPosY);

    m_pViewLayoutProcessor->SubmitContentItem(pLayoutItem, eStatus);
  } while (eStatus != CXFA_ContentLayoutProcessor::Result::kDone);

  if (eStatus == CXFA_ContentLayoutProcessor::Result::kDone) {
    m_pViewLayoutProcessor->FinishPaginatedPageSets();
    m_pViewLayoutProcessor->SyncLayoutData();
    m_bNeedLayout = false;
    m_rgChangedContainers.clear();
  }
  return 100 *
         (eStatus == CXFA_ContentLayoutProcessor::Result::kDone
              ? m_nProgressCounter
              : m_nProgressCounter - 1) /
         m_nProgressCounter;
}

bool CXFA_LayoutProcessor::IncrementLayout() {
  if (m_bNeedLayout) {
    StartLayout(true);
    return DoLayout() == 100;
  }
  return m_rgChangedContainers.empty();
}

int32_t CXFA_LayoutProcessor::CountPages() const {
  return m_pViewLayoutProcessor ? m_pViewLayoutProcessor->GetPageCount() : 0;
}

CXFA_ViewLayoutItem* CXFA_LayoutProcessor::GetPage(int32_t index) const {
  return m_pViewLayoutProcessor ? m_pViewLayoutProcessor->GetPage(index)
                                : nullptr;
}

CXFA_LayoutItem* CXFA_LayoutProcessor::GetLayoutItem(CXFA_Node* pFormItem) {
  return pFormItem->JSObject()->GetLayoutItem();
}

void CXFA_LayoutProcessor::AddChangedContainer(CXFA_Node* pContainer) {
  if (!pdfium::Contains(m_rgChangedContainers, pContainer))
    m_rgChangedContainers.push_back(pContainer);
}

bool CXFA_LayoutProcessor::NeedLayout() const {
  return m_bNeedLayout || !m_rgChangedContainers.empty();
}
