// 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 "core/fpdfapi/page/cpdf_form.h"

#include <algorithm>
#include <memory>

#include "core/fpdfapi/page/cpdf_contentparser.h"
#include "core/fpdfapi/page/cpdf_imageobject.h"
#include "core/fpdfapi/page/cpdf_pageobject.h"
#include "core/fpdfapi/page/cpdf_pageobjectholder.h"
#include "core/fpdfapi/parser/cpdf_dictionary.h"
#include "core/fpdfapi/parser/cpdf_stream.h"
#include "core/fxge/dib/cfx_dibitmap.h"
#include "third_party/base/check_op.h"

// static
CPDF_Dictionary* CPDF_Form::ChooseResourcesDict(
    CPDF_Dictionary* pResources,
    CPDF_Dictionary* pParentResources,
    CPDF_Dictionary* pPageResources) {
  if (pResources)
    return pResources;
  return pParentResources ? pParentResources : pPageResources;
}

CPDF_Form::CPDF_Form(CPDF_Document* pDoc,
                     CPDF_Dictionary* pPageResources,
                     CPDF_Stream* pFormStream)
    : CPDF_Form(pDoc, pPageResources, pFormStream, nullptr) {}

CPDF_Form::CPDF_Form(CPDF_Document* pDoc,
                     CPDF_Dictionary* pPageResources,
                     CPDF_Stream* pFormStream,
                     CPDF_Dictionary* pParentResources)
    : CPDF_PageObjectHolder(
          pDoc,
          pFormStream->GetDict(),
          pPageResources,
          ChooseResourcesDict(pFormStream->GetDict()->GetDictFor("Resources"),
                              pParentResources,
                              pPageResources)),
      m_pFormStream(pFormStream) {
  LoadTransparencyInfo();
}

CPDF_Form::~CPDF_Form() = default;

void CPDF_Form::ParseContent() {
  ParseContentInternal(nullptr, nullptr, nullptr, nullptr);
}

void CPDF_Form::ParseContent(const CPDF_AllStates* pGraphicStates,
                             const CFX_Matrix* pParentMatrix,
                             std::set<const uint8_t*>* pParsedSet) {
  ParseContentInternal(pGraphicStates, pParentMatrix, nullptr, pParsedSet);
}

void CPDF_Form::ParseContentForType3Char(CPDF_Type3Char* pType3Char) {
  ParseContentInternal(nullptr, nullptr, pType3Char, nullptr);
}

void CPDF_Form::ParseContentInternal(const CPDF_AllStates* pGraphicStates,
                                     const CFX_Matrix* pParentMatrix,
                                     CPDF_Type3Char* pType3Char,
                                     std::set<const uint8_t*>* pParsedSet) {
  if (GetParseState() == ParseState::kParsed)
    return;

  if (GetParseState() == ParseState::kNotParsed) {
    StartParse(std::make_unique<CPDF_ContentParser>(
        this, pGraphicStates, pParentMatrix, pType3Char,
        pParsedSet ? pParsedSet : &m_ParsedSet));
  }
  DCHECK_EQ(GetParseState(), ParseState::kParsing);
  ContinueParse(nullptr);
}

bool CPDF_Form::HasPageObjects() const {
  return GetPageObjectCount() != 0;
}

CFX_FloatRect CPDF_Form::CalcBoundingBox() const {
  if (GetPageObjectCount() == 0)
    return CFX_FloatRect();

  float left = 1000000.0f;
  float right = -1000000.0f;
  float bottom = 1000000.0f;
  float top = -1000000.0f;
  for (const auto& pObj : *this) {
    const auto& rect = pObj->GetRect();
    left = std::min(left, rect.left);
    right = std::max(right, rect.right);
    bottom = std::min(bottom, rect.bottom);
    top = std::max(top, rect.top);
  }
  return CFX_FloatRect(left, bottom, right, top);
}

const CPDF_Stream* CPDF_Form::GetStream() const {
  return m_pFormStream.Get();
}

absl::optional<std::pair<RetainPtr<CFX_DIBitmap>, CFX_Matrix>>
CPDF_Form::GetBitmapAndMatrixFromSoleImageOfForm() const {
  if (GetPageObjectCount() != 1)
    return absl::nullopt;

  CPDF_ImageObject* pImageObject = (*begin())->AsImage();
  if (!pImageObject)
    return absl::nullopt;

  return {{pImageObject->GetIndependentBitmap(), pImageObject->matrix()}};
}
