// 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/fpdf_page/cpdf_contentmark.h"

#include "core/fpdfapi/fpdf_parser/include/cpdf_dictionary.h"
#include "third_party/base/stl_util.h"

CPDF_ContentMark::CPDF_ContentMark() {}

CPDF_ContentMark::CPDF_ContentMark(const CPDF_ContentMark& that)
    : m_Ref(that.m_Ref) {}

CPDF_ContentMark::~CPDF_ContentMark() {}

void CPDF_ContentMark::SetNull() {
  m_Ref.SetNull();
}

int CPDF_ContentMark::CountItems() const {
  return m_Ref.GetObject()->CountItems();
}

const CPDF_ContentMarkItem& CPDF_ContentMark::GetItem(int i) const {
  return m_Ref.GetObject()->GetItem(i);
}

int CPDF_ContentMark::GetMCID() const {
  const MarkData* pData = m_Ref.GetObject();
  return pData ? pData->GetMCID() : -1;
}

void CPDF_ContentMark::AddMark(const CFX_ByteString& name,
                               CPDF_Dictionary* pDict,
                               FX_BOOL bDirect) {
  m_Ref.GetPrivateCopy()->AddMark(name, pDict, bDirect);
}

void CPDF_ContentMark::DeleteLastMark() {
  m_Ref.GetPrivateCopy()->DeleteLastMark();
  if (CountItems() == 0)
    m_Ref.SetNull();
}

bool CPDF_ContentMark::HasMark(const CFX_ByteStringC& mark) const {
  const MarkData* pData = m_Ref.GetObject();
  if (!pData)
    return false;

  for (int i = 0; i < pData->CountItems(); i++) {
    if (pData->GetItem(i).GetName() == mark)
      return true;
  }
  return false;
}

bool CPDF_ContentMark::LookupMark(const CFX_ByteStringC& mark,
                                  CPDF_Dictionary*& pDict) const {
  const MarkData* pData = m_Ref.GetObject();
  if (!pData)
    return false;

  for (int i = 0; i < pData->CountItems(); i++) {
    const CPDF_ContentMarkItem& item = pData->GetItem(i);
    if (item.GetName() == mark) {
      pDict = nullptr;
      if (item.GetParamType() == CPDF_ContentMarkItem::PropertiesDict ||
          item.GetParamType() == CPDF_ContentMarkItem::DirectDict) {
        pDict = item.GetParam();
      }
      return true;
    }
  }
  return false;
}

CPDF_ContentMark::MarkData::MarkData() {}

CPDF_ContentMark::MarkData::MarkData(const MarkData& src)
    : m_Marks(src.m_Marks) {}

CPDF_ContentMark::MarkData::~MarkData() {}

int CPDF_ContentMark::MarkData::CountItems() const {
  return pdfium::CollectionSize<int>(m_Marks);
}

CPDF_ContentMarkItem& CPDF_ContentMark::MarkData::GetItem(int index) {
  return m_Marks[index];
}

const CPDF_ContentMarkItem& CPDF_ContentMark::MarkData::GetItem(
    int index) const {
  return m_Marks[index];
}

int CPDF_ContentMark::MarkData::GetMCID() const {
  for (const auto& mark : m_Marks) {
    CPDF_ContentMarkItem::ParamType type = mark.GetParamType();
    if (type == CPDF_ContentMarkItem::PropertiesDict ||
        type == CPDF_ContentMarkItem::DirectDict) {
      CPDF_Dictionary* pDict = mark.GetParam();
      if (pDict->KeyExist("MCID"))
        return pDict->GetIntegerBy("MCID");
    }
  }
  return -1;
}

void CPDF_ContentMark::MarkData::AddMark(const CFX_ByteString& name,
                                         CPDF_Dictionary* pDict,
                                         FX_BOOL bDirect) {
  CPDF_ContentMarkItem item;
  item.SetName(name);
  if (pDict) {
    if (bDirect) {
      item.SetParam(CPDF_ContentMarkItem::DirectDict,
                    ToDictionary(pDict->Clone()));
    } else {
      item.SetParam(CPDF_ContentMarkItem::PropertiesDict, pDict);
    }
  }
  m_Marks.push_back(item);
}

void CPDF_ContentMark::MarkData::DeleteLastMark() {
  if (!m_Marks.empty())
    m_Marks.pop_back();
}
