// 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,
                     RetainPtr<CPDF_Dictionary> pPageResources,
                     RetainPtr<CPDF_Stream> pFormStream)
    : CPDF_Form(pDoc,
                std::move(pPageResources),
                std::move(pFormStream),
                nullptr) {}

CPDF_Form::CPDF_Form(CPDF_Document* pDoc,
                     RetainPtr<CPDF_Dictionary> pPageResources,
                     RetainPtr<CPDF_Stream> pFormStream,
                     CPDF_Dictionary* pParentResources)
    : CPDF_PageObjectHolder(pDoc,
                            pFormStream->GetMutableDict(),
                            pPageResources,
                            pdfium::WrapRetain(ChooseResourcesDict(
                                pFormStream->GetMutableDict()
                                    ->GetMutableDictFor("Resources")
                                    .Get(),
                                pParentResources,
                                pPageResources.Get()))),
      m_pFormStream(std::move(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()}};
}
