// 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/fpdfdoc/cpdf_annotlist.h"

#include <algorithm>
#include <memory>
#include <utility>

#include "constants/annotation_common.h"
#include "constants/annotation_flags.h"
#include "constants/form_fields.h"
#include "constants/form_flags.h"
#include "core/fpdfapi/page/cpdf_occontext.h"
#include "core/fpdfapi/page/cpdf_page.h"
#include "core/fpdfapi/parser/cpdf_array.h"
#include "core/fpdfapi/parser/cpdf_dictionary.h"
#include "core/fpdfapi/parser/cpdf_document.h"
#include "core/fpdfapi/parser/cpdf_name.h"
#include "core/fpdfapi/parser/cpdf_number.h"
#include "core/fpdfapi/parser/cpdf_reference.h"
#include "core/fpdfapi/parser/cpdf_string.h"
#include "core/fpdfapi/render/cpdf_renderoptions.h"
#include "core/fpdfdoc/cpdf_annot.h"
#include "core/fpdfdoc/cpdf_formfield.h"
#include "core/fpdfdoc/cpdf_generateap.h"
#include "core/fpdfdoc/cpdf_interactiveform.h"
#include "core/fxge/cfx_renderdevice.h"

namespace {

bool PopupAppearsForAnnotType(CPDF_Annot::Subtype subtype) {
  switch (subtype) {
    case CPDF_Annot::Subtype::TEXT:
    case CPDF_Annot::Subtype::LINE:
    case CPDF_Annot::Subtype::SQUARE:
    case CPDF_Annot::Subtype::CIRCLE:
    case CPDF_Annot::Subtype::POLYGON:
    case CPDF_Annot::Subtype::POLYLINE:
    case CPDF_Annot::Subtype::HIGHLIGHT:
    case CPDF_Annot::Subtype::UNDERLINE:
    case CPDF_Annot::Subtype::SQUIGGLY:
    case CPDF_Annot::Subtype::STRIKEOUT:
    case CPDF_Annot::Subtype::STAMP:
    case CPDF_Annot::Subtype::CARET:
    case CPDF_Annot::Subtype::INK:
    case CPDF_Annot::Subtype::FILEATTACHMENT:
    case CPDF_Annot::Subtype::REDACT:
      return true;
    case CPDF_Annot::Subtype::UNKNOWN:
    case CPDF_Annot::Subtype::LINK:
    case CPDF_Annot::Subtype::FREETEXT:
    case CPDF_Annot::Subtype::POPUP:
    case CPDF_Annot::Subtype::SOUND:
    case CPDF_Annot::Subtype::MOVIE:
    case CPDF_Annot::Subtype::WIDGET:
    case CPDF_Annot::Subtype::SCREEN:
    case CPDF_Annot::Subtype::PRINTERMARK:
    case CPDF_Annot::Subtype::TRAPNET:
    case CPDF_Annot::Subtype::WATERMARK:
    case CPDF_Annot::Subtype::THREED:
    case CPDF_Annot::Subtype::RICHMEDIA:
    case CPDF_Annot::Subtype::XFAWIDGET:
    default:
      return false;
  }
}

std::unique_ptr<CPDF_Annot> CreatePopupAnnot(CPDF_Document* pDocument,
                                             CPDF_Page* pPage,
                                             CPDF_Annot* pAnnot) {
  if (!PopupAppearsForAnnotType(pAnnot->GetSubtype()))
    return nullptr;

  const CPDF_Dictionary* pParentDict = pAnnot->GetAnnotDict();
  if (!pParentDict)
    return nullptr;

  // TODO(jaepark): We shouldn't strip BOM for some strings and not for others.
  // See pdfium:593.
  WideString sContents =
      pParentDict->GetUnicodeTextFor(pdfium::annotation::kContents);
  if (sContents.IsEmpty())
    return nullptr;

  auto pAnnotDict = pDocument->New<CPDF_Dictionary>();
  pAnnotDict->SetNewFor<CPDF_Name>(pdfium::annotation::kType, "Annot");
  pAnnotDict->SetNewFor<CPDF_Name>(pdfium::annotation::kSubtype, "Popup");
  pAnnotDict->SetNewFor<CPDF_String>(
      pdfium::form_fields::kT,
      pParentDict->GetStringFor(pdfium::form_fields::kT), false);
  pAnnotDict->SetNewFor<CPDF_String>(pdfium::annotation::kContents,
                                     sContents.ToUTF8(), false);

  CFX_FloatRect rect = pParentDict->GetRectFor(pdfium::annotation::kRect);
  rect.Normalize();
  CFX_FloatRect popupRect(0, 0, 200, 200);
  // Note that if the popup can set its own dimensions, then we will need to
  // make sure that it isn't larger than the page size.
  if (rect.left + popupRect.Width() > pPage->GetPageWidth() &&
      rect.bottom - popupRect.Height() < 0) {
    // If the annotation is on the bottom-right corner of the page, then place
    // the popup above and to the left of the annotation.
    popupRect.Translate(rect.right - popupRect.Width(), rect.top);
  } else {
    // Place the popup below and to the right of the annotation without getting
    // clipped by page edges.
    popupRect.Translate(
        std::min(rect.left, pPage->GetPageWidth() - popupRect.Width()),
        std::max(rect.bottom - popupRect.Height(), 0.f));
  }

  pAnnotDict->SetRectFor(pdfium::annotation::kRect, popupRect);
  pAnnotDict->SetNewFor<CPDF_Number>(pdfium::annotation::kF, 0);

  auto pPopupAnnot = std::make_unique<CPDF_Annot>(pAnnotDict.Get(), pDocument);
  pAnnot->SetPopupAnnot(pPopupAnnot.get());
  return pPopupAnnot;
}

void GenerateAP(CPDF_Document* pDoc, CPDF_Dictionary* pAnnotDict) {
  if (!pAnnotDict ||
      pAnnotDict->GetStringFor(pdfium::annotation::kSubtype) != "Widget") {
    return;
  }

  CPDF_Object* pFieldTypeObj =
      CPDF_FormField::GetFieldAttr(pAnnotDict, pdfium::form_fields::kFT);
  if (!pFieldTypeObj)
    return;

  ByteString field_type = pFieldTypeObj->GetString();
  if (field_type == pdfium::form_fields::kTx) {
    CPDF_GenerateAP::GenerateFormAP(pDoc, pAnnotDict,
                                    CPDF_GenerateAP::kTextField);
    return;
  }

  CPDF_Object* pFieldFlagsObj =
      CPDF_FormField::GetFieldAttr(pAnnotDict, pdfium::form_fields::kFf);
  uint32_t flags = pFieldFlagsObj ? pFieldFlagsObj->GetInteger() : 0;
  if (field_type == pdfium::form_fields::kCh) {
    auto type = (flags & pdfium::form_flags::kChoiceCombo)
                    ? CPDF_GenerateAP::kComboBox
                    : CPDF_GenerateAP::kListBox;
    CPDF_GenerateAP::GenerateFormAP(pDoc, pAnnotDict, type);
    return;
  }

  if (field_type != pdfium::form_fields::kBtn)
    return;
  if (flags & pdfium::form_flags::kButtonPushbutton)
    return;
  if (pAnnotDict->KeyExist(pdfium::annotation::kAS))
    return;

  CPDF_Dictionary* pParentDict =
      pAnnotDict->GetDictFor(pdfium::form_fields::kParent);
  if (!pParentDict || !pParentDict->KeyExist(pdfium::annotation::kAS))
    return;

  pAnnotDict->SetNewFor<CPDF_String>(
      pdfium::annotation::kAS,
      pParentDict->GetStringFor(pdfium::annotation::kAS), false);
}

}  // namespace

CPDF_AnnotList::CPDF_AnnotList(CPDF_Page* pPage)
    : m_pDocument(pPage->GetDocument()) {
  CPDF_Array* pAnnots = pPage->GetDict()->GetArrayFor("Annots");
  if (!pAnnots)
    return;

  const CPDF_Dictionary* pRoot = m_pDocument->GetRoot();
  const CPDF_Dictionary* pAcroForm = pRoot->GetDictFor("AcroForm");
  bool bRegenerateAP =
      pAcroForm && pAcroForm->GetBooleanFor("NeedAppearances", false);
  for (size_t i = 0; i < pAnnots->size(); ++i) {
    RetainPtr<CPDF_Dictionary> pDict =
        ToDictionary(pAnnots->GetMutableDirectObjectAt(i));
    if (!pDict)
      continue;
    const ByteString subtype =
        pDict->GetStringFor(pdfium::annotation::kSubtype);
    if (subtype == "Popup") {
      // Skip creating Popup annotations in the PDF document since PDFium
      // provides its own Popup annotations.
      continue;
    }
    pAnnots->ConvertToIndirectObjectAt(i, m_pDocument.Get());
    m_AnnotList.push_back(
        std::make_unique<CPDF_Annot>(pDict.Get(), m_pDocument.Get()));
    if (bRegenerateAP && subtype == "Widget" &&
        CPDF_InteractiveForm::IsUpdateAPEnabled() &&
        !pDict->GetDictFor(pdfium::annotation::kAP)) {
      GenerateAP(m_pDocument.Get(), pDict.Get());
    }
  }

  m_nAnnotCount = m_AnnotList.size();
  for (size_t i = 0; i < m_nAnnotCount; ++i) {
    std::unique_ptr<CPDF_Annot> pPopupAnnot =
        CreatePopupAnnot(m_pDocument.Get(), pPage, m_AnnotList[i].get());
    if (pPopupAnnot)
      m_AnnotList.push_back(std::move(pPopupAnnot));
  }
}

CPDF_AnnotList::~CPDF_AnnotList() {
  // Move the pop-up annotations out of |m_AnnotList| into |popups|. Then
  // destroy |m_AnnotList| first. This prevents dangling pointers to the pop-up
  // annotations.
  size_t nPopupCount = m_AnnotList.size() - m_nAnnotCount;
  std::vector<std::unique_ptr<CPDF_Annot>> popups(nPopupCount);
  for (size_t i = 0; i < nPopupCount; ++i)
    popups[i] = std::move(m_AnnotList[m_nAnnotCount + i]);
  m_AnnotList.clear();
}

void CPDF_AnnotList::DisplayPass(CPDF_Page* pPage,
                                 CFX_RenderDevice* pDevice,
                                 CPDF_RenderContext* pContext,
                                 bool bPrinting,
                                 const CFX_Matrix& mtMatrix,
                                 bool bWidgetPass) {
  for (const auto& pAnnot : m_AnnotList) {
    bool bWidget = pAnnot->GetSubtype() == CPDF_Annot::Subtype::WIDGET;
    if ((bWidgetPass && !bWidget) || (!bWidgetPass && bWidget))
      continue;

    uint32_t annot_flags = pAnnot->GetFlags();
    if (annot_flags & pdfium::annotation_flags::kHidden)
      continue;

    if (bPrinting && (annot_flags & pdfium::annotation_flags::kPrint) == 0)
      continue;

    if (!bPrinting && (annot_flags & pdfium::annotation_flags::kNoView))
      continue;

    if (pContext) {
      pAnnot->DrawInContext(pPage, pContext, mtMatrix,
                            CPDF_Annot::AppearanceMode::kNormal);
    } else if (!pAnnot->DrawAppearance(pPage, pDevice, mtMatrix,
                                       CPDF_Annot::AppearanceMode::kNormal)) {
      pAnnot->DrawBorder(pDevice, &mtMatrix);
    }
  }
}

void CPDF_AnnotList::DisplayAnnots(CPDF_Page* pPage,
                                   CFX_RenderDevice* pDevice,
                                   CPDF_RenderContext* pContext,
                                   bool bPrinting,
                                   const CFX_Matrix& mtUser2Device,
                                   bool bShowWidget) {
  DisplayPass(pPage, pDevice, pContext, bPrinting, mtUser2Device, false);
  if (bShowWidget)
    DisplayPass(pPage, pDevice, pContext, bPrinting, mtUser2Device, true);
}
