// Copyright 2014 The PDFium Authors
// 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 "fpdfsdk/fpdfxfa/cpdfxfa_page.h"

#include <memory>
#include <utility>

#include "core/fpdfapi/page/cpdf_page.h"
#include "core/fpdfapi/page/cpdf_pageimagecache.h"
#include "core/fpdfapi/parser/cpdf_document.h"
#include "fpdfsdk/cpdfsdk_pageview.h"
#include "fpdfsdk/fpdfxfa/cpdfxfa_context.h"
#include "fpdfsdk/fpdfxfa/cpdfxfa_widget.h"
#include "third_party/base/check.h"
#include "xfa/fgas/graphics/cfgas_gegraphics.h"
#include "xfa/fxfa/cxfa_ffdocview.h"
#include "xfa/fxfa/cxfa_ffpageview.h"
#include "xfa/fxfa/cxfa_ffwidget.h"
#include "xfa/fxfa/cxfa_ffwidgethandler.h"

namespace {

constexpr Mask<XFA_WidgetStatus> kIteratorFilter = {
    XFA_WidgetStatus::kVisible,
    XFA_WidgetStatus::kViewable,
    XFA_WidgetStatus::kFocused,
};

CXFA_FFWidget::IteratorIface* GCedWidgetIteratorForPage(
    CXFA_FFPageView* pFFPageView,
    CPDFSDK_PageView* pPageView) {
  if (!pFFPageView)
    return nullptr;

  ObservedPtr<CPDFSDK_PageView> pWatchedPageView(pPageView);
  CXFA_FFWidget::IteratorIface* pIterator =
      pFFPageView->CreateGCedTraverseWidgetIterator(kIteratorFilter);

  // Check |pPageView| again because JS may have destroyed it.
  return pWatchedPageView ? pIterator : nullptr;
}

CXFA_FFWidget::IteratorIface* GCedWidgetIteratorForAnnot(
    CXFA_FFPageView* pFFPageView,
    CPDFSDK_Annot* pSDKAnnot) {
  if (!pFFPageView)
    return nullptr;

  CPDFXFA_Widget* pXFAWidget = ToXFAWidget(pSDKAnnot);
  if (!pXFAWidget)
    return nullptr;

  ObservedPtr<CPDFSDK_Annot> pObservedAnnot(pSDKAnnot);
  CXFA_FFWidget::IteratorIface* pWidgetIterator =
      pFFPageView->CreateGCedTraverseWidgetIterator(kIteratorFilter);

  // Check |pSDKAnnot| again because JS may have destroyed it.
  if (!pObservedAnnot)
    return nullptr;

  if (pWidgetIterator->GetCurrentWidget() != pXFAWidget->GetXFAFFWidget())
    pWidgetIterator->SetCurrentWidget(pXFAWidget->GetXFAFFWidget());

  return pWidgetIterator;
}

}  // namespace

CPDFXFA_Page::CPDFXFA_Page(CPDF_Document* pDocument, int page_index)
    : m_pDocument(pDocument), m_iPageIndex(page_index) {
  DCHECK(m_pDocument->GetExtension());
  DCHECK(m_iPageIndex >= 0);
}

CPDFXFA_Page::~CPDFXFA_Page() = default;

CPDF_Page* CPDFXFA_Page::AsPDFPage() {
  return m_pPDFPage.Get();
}

CPDFXFA_Page* CPDFXFA_Page::AsXFAPage() {
  return this;
}

CPDF_Document* CPDFXFA_Page::GetDocument() const {
  return m_pDocument;
}

bool CPDFXFA_Page::LoadPDFPage() {
  RetainPtr<CPDF_Dictionary> pDict =
      GetDocument()->GetMutablePageDictionary(m_iPageIndex);
  if (!pDict)
    return false;

  if (!m_pPDFPage || m_pPDFPage->GetDict() != pDict)
    LoadPDFPageFromDict(std::move(pDict));

  return true;
}

CXFA_FFPageView* CPDFXFA_Page::GetXFAPageView() const {
  auto* pContext = static_cast<CPDFXFA_Context*>(m_pDocument->GetExtension());
  CXFA_FFDocView* pXFADocView = pContext->GetXFADocView();
  return pXFADocView ? pXFADocView->GetPageView(m_iPageIndex) : nullptr;
}

bool CPDFXFA_Page::LoadPage() {
  auto* pContext = static_cast<CPDFXFA_Context*>(m_pDocument->GetExtension());
  switch (pContext->GetFormType()) {
    case FormType::kNone:
    case FormType::kAcroForm:
    case FormType::kXFAForeground:
      return LoadPDFPage();
    case FormType::kXFAFull:
      return !!GetXFAPageView();
  }
}

void CPDFXFA_Page::LoadPDFPageFromDict(RetainPtr<CPDF_Dictionary> pPageDict) {
  DCHECK(pPageDict);
  m_pPDFPage =
      pdfium::MakeRetain<CPDF_Page>(GetDocument(), std::move(pPageDict));
  m_pPDFPage->AddPageImageCache();
  m_pPDFPage->ParseContent();
}

float CPDFXFA_Page::GetPageWidth() const {
  CXFA_FFPageView* pPageView = GetXFAPageView();
  if (!m_pPDFPage && !pPageView)
    return 0.0f;

  auto* pContext = static_cast<CPDFXFA_Context*>(m_pDocument->GetExtension());
  switch (pContext->GetFormType()) {
    case FormType::kNone:
    case FormType::kAcroForm:
    case FormType::kXFAForeground:
      if (m_pPDFPage)
        return m_pPDFPage->GetPageWidth();
      [[fallthrough]];
    case FormType::kXFAFull:
      if (pPageView)
        return pPageView->GetPageViewRect().width;
      break;
  }

  return 0.0f;
}

float CPDFXFA_Page::GetPageHeight() const {
  CXFA_FFPageView* pPageView = GetXFAPageView();
  if (!m_pPDFPage && !pPageView)
    return 0.0f;

  auto* pContext = static_cast<CPDFXFA_Context*>(m_pDocument->GetExtension());
  switch (pContext->GetFormType()) {
    case FormType::kNone:
    case FormType::kAcroForm:
    case FormType::kXFAForeground:
      if (m_pPDFPage)
        return m_pPDFPage->GetPageHeight();
      [[fallthrough]];
    case FormType::kXFAFull:
      if (pPageView)
        return pPageView->GetPageViewRect().height;
      break;
  }

  return 0.0f;
}

absl::optional<CFX_PointF> CPDFXFA_Page::DeviceToPage(
    const FX_RECT& rect,
    int rotate,
    const CFX_PointF& device_point) const {
  CXFA_FFPageView* pPageView = GetXFAPageView();
  if (!m_pPDFPage && !pPageView)
    return absl::nullopt;

  CFX_Matrix page2device = GetDisplayMatrix(rect, rotate);
  return page2device.GetInverse().Transform(device_point);
}

absl::optional<CFX_PointF> CPDFXFA_Page::PageToDevice(
    const FX_RECT& rect,
    int rotate,
    const CFX_PointF& page_point) const {
  CXFA_FFPageView* pPageView = GetXFAPageView();
  if (!m_pPDFPage && !pPageView)
    return absl::nullopt;

  CFX_Matrix page2device = GetDisplayMatrix(rect, rotate);
  return page2device.Transform(page_point);
}

CFX_Matrix CPDFXFA_Page::GetDisplayMatrix(const FX_RECT& rect,
                                          int iRotate) const {
  CXFA_FFPageView* pPageView = GetXFAPageView();
  if (!m_pPDFPage && !pPageView)
    return CFX_Matrix();

  auto* pContext = static_cast<CPDFXFA_Context*>(m_pDocument->GetExtension());
  switch (pContext->GetFormType()) {
    case FormType::kNone:
    case FormType::kAcroForm:
    case FormType::kXFAForeground:
      if (m_pPDFPage)
        return m_pPDFPage->GetDisplayMatrix(rect, iRotate);
      [[fallthrough]];
    case FormType::kXFAFull:
      if (pPageView)
        return pPageView->GetDisplayMatrix(rect, iRotate);
      break;
  }

  return CFX_Matrix();
}

CPDFSDK_Annot* CPDFXFA_Page::GetNextXFAAnnot(CPDFSDK_Annot* pSDKAnnot) const {
  CXFA_FFWidget::IteratorIface* pWidgetIterator =
      GCedWidgetIteratorForAnnot(GetXFAPageView(), pSDKAnnot);
  if (!pWidgetIterator)
    return nullptr;

  return pSDKAnnot->GetPageView()->GetAnnotForFFWidget(
      pWidgetIterator->MoveToNext());
}

CPDFSDK_Annot* CPDFXFA_Page::GetPrevXFAAnnot(CPDFSDK_Annot* pSDKAnnot) const {
  CXFA_FFWidget::IteratorIface* pWidgetIterator =
      GCedWidgetIteratorForAnnot(GetXFAPageView(), pSDKAnnot);
  if (!pWidgetIterator)
    return nullptr;

  return pSDKAnnot->GetPageView()->GetAnnotForFFWidget(
      pWidgetIterator->MoveToPrevious());
}

CPDFSDK_Annot* CPDFXFA_Page::GetFirstXFAAnnot(
    CPDFSDK_PageView* page_view) const {
  CXFA_FFWidget::IteratorIface* pWidgetIterator =
      GCedWidgetIteratorForPage(GetXFAPageView(), page_view);
  if (!pWidgetIterator)
    return nullptr;

  return page_view->GetAnnotForFFWidget(pWidgetIterator->MoveToFirst());
}

CPDFSDK_Annot* CPDFXFA_Page::GetLastXFAAnnot(
    CPDFSDK_PageView* page_view) const {
  CXFA_FFWidget::IteratorIface* pWidgetIterator =
      GCedWidgetIteratorForPage(GetXFAPageView(), page_view);
  if (!pWidgetIterator)
    return nullptr;

  return page_view->GetAnnotForFFWidget(pWidgetIterator->MoveToLast());
}

int CPDFXFA_Page::HasFormFieldAtPoint(const CFX_PointF& point) const {
  CXFA_FFPageView* pPageView = GetXFAPageView();
  if (!pPageView)
    return -1;

  CXFA_FFDocView* pDocView = pPageView->GetDocView();
  if (!pDocView)
    return -1;

  CXFA_FFWidgetHandler* pWidgetHandler = pDocView->GetWidgetHandler();
  if (!pWidgetHandler)
    return -1;

  CXFA_FFWidget::IteratorIface* pWidgetIterator =
      pPageView->CreateGCedFormWidgetIterator(XFA_WidgetStatus::kViewable);

  CXFA_FFWidget* pXFAAnnot;
  while ((pXFAAnnot = pWidgetIterator->MoveToNext()) != nullptr) {
    if (pXFAAnnot->GetFormFieldType() == FormFieldType::kXFA)
      continue;

    CFX_FloatRect rcWidget = pXFAAnnot->GetWidgetRect().ToFloatRect();
    rcWidget.Inflate(1.0f, 1.0f);
    if (rcWidget.Contains(point))
      return static_cast<int>(pXFAAnnot->GetFormFieldType());
  }

  return -1;
}

void CPDFXFA_Page::DrawFocusAnnot(CFX_RenderDevice* pDevice,
                                  CPDFSDK_Annot* pAnnot,
                                  const CFX_Matrix& mtUser2Device,
                                  const FX_RECT& rtClip) {
  CFX_RectF rectClip(rtClip);
  CFGAS_GEGraphics gs(pDevice);
  gs.SetClipRect(rectClip);

  CXFA_FFPageView* xfaView = GetXFAPageView();
  CXFA_FFWidget::IteratorIface* pWidgetIterator =
      xfaView->CreateGCedFormWidgetIterator(Mask<XFA_WidgetStatus>{
          XFA_WidgetStatus::kVisible, XFA_WidgetStatus::kViewable});

  while (true) {
    CXFA_FFWidget* pWidget = pWidgetIterator->MoveToNext();
    if (!pWidget)
      break;

    CFX_RectF rtWidgetBox = pWidget->GetBBox(CXFA_FFWidget::kDoNotDrawFocus);
    ++rtWidgetBox.width;
    ++rtWidgetBox.height;
    if (rtWidgetBox.IntersectWith(rectClip))
      pWidget->RenderWidget(&gs, mtUser2Device, CXFA_FFWidget::kHighlight);
  }

  CPDFXFA_Widget* pXFAWidget = ToXFAWidget(pAnnot);
  if (!pXFAWidget)
    return;

  CXFA_FFDocView* docView = xfaView->GetDocView();
  if (!docView)
    return;

  docView->GetWidgetHandler()->RenderWidget(pXFAWidget->GetXFAFFWidget(), &gs,
                                            mtUser2Device, false);
}
