// Copyright 2014 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 "../../../third_party/base/nonstd_unique_ptr.h"
#include "../../include/fpdfdoc/fpdf_doc.h"
#include "../../include/fpdfapi/fpdf_pageobj.h"

CPDF_AnnotList::CPDF_AnnotList(CPDF_Page* pPage) {
  ASSERT(pPage != NULL);
  m_pPageDict = pPage->m_pFormDict;
  if (m_pPageDict == NULL) {
    return;
  }
  m_pDocument = pPage->m_pDocument;
  CPDF_Array* pAnnots = m_pPageDict->GetArray("Annots");
  if (pAnnots == NULL) {
    return;
  }
  CPDF_Dictionary* pRoot = m_pDocument->GetRoot();
  CPDF_Dictionary* pAcroForm = pRoot->GetDict("AcroForm");
  FX_BOOL bRegenerateAP = pAcroForm && pAcroForm->GetBoolean("NeedAppearances");
  for (FX_DWORD i = 0; i < pAnnots->GetCount(); ++i) {
    CPDF_Dictionary* pDict = (CPDF_Dictionary*)pAnnots->GetElementValue(i);
    if (pDict == NULL || pDict->GetType() != PDFOBJ_DICTIONARY) {
      continue;
    }
    FX_DWORD dwObjNum = pDict->GetObjNum();
    if (dwObjNum == 0) {
      dwObjNum = m_pDocument->AddIndirectObject(pDict);
      CPDF_Reference* pAction = CPDF_Reference::Create(m_pDocument, dwObjNum);
      if (pAction == NULL) {
        break;
      }
      pAnnots->InsertAt(i, pAction);
      pAnnots->RemoveAt(i + 1);
      pDict = pAnnots->GetDict(i);
    }
    CPDF_Annot* pAnnot = new CPDF_Annot(pDict, this);
    m_AnnotList.Add(pAnnot);
    if (bRegenerateAP &&
        pDict->GetConstString(FX_BSTRC("Subtype")) == FX_BSTRC("Widget"))
      if (CPDF_InterForm::UpdatingAPEnabled()) {
        FPDF_GenerateAP(m_pDocument, pDict);
      }
  }
}
CPDF_AnnotList::~CPDF_AnnotList() {
  int i = 0;
  for (i = 0; i < m_AnnotList.GetSize(); ++i) {
    delete (CPDF_Annot*)m_AnnotList[i];
  }
  for (i = 0; i < m_Borders.GetSize(); ++i) {
    delete (CPDF_PageObjects*)m_Borders[i];
  }
}
void CPDF_AnnotList::DisplayPass(const CPDF_Page* pPage,
                                 CFX_RenderDevice* pDevice,
                                 CPDF_RenderContext* pContext,
                                 FX_BOOL bPrinting,
                                 CFX_AffineMatrix* pMatrix,
                                 FX_BOOL bWidgetPass,
                                 CPDF_RenderOptions* pOptions,
                                 FX_RECT* clip_rect) {
  for (int i = 0; i < m_AnnotList.GetSize(); ++i) {
    CPDF_Annot* pAnnot = (CPDF_Annot*)m_AnnotList[i];
    FX_BOOL bWidget = pAnnot->GetSubType() == "Widget";
    if ((bWidgetPass && !bWidget) || (!bWidgetPass && bWidget)) {
      continue;
    }
    FX_DWORD annot_flags = pAnnot->GetFlags();
    if (annot_flags & ANNOTFLAG_HIDDEN) {
      continue;
    }
    if (bPrinting && (annot_flags & ANNOTFLAG_PRINT) == 0) {
      continue;
    }
    if (!bPrinting && (annot_flags & ANNOTFLAG_NOVIEW)) {
      continue;
    }
    if (pOptions != NULL) {
      IPDF_OCContext* pOCContext = pOptions->m_pOCContext;
      CPDF_Dictionary* pAnnotDict = pAnnot->GetAnnotDict();
      if (pOCContext != NULL && pAnnotDict != NULL &&
          !pOCContext->CheckOCGVisible(pAnnotDict->GetDict(FX_BSTRC("OC")))) {
        continue;
      }
    }
    CPDF_Rect annot_rect_f;
    pAnnot->GetRect(annot_rect_f);
    CFX_Matrix matrix;
    matrix = *pMatrix;
    if (clip_rect) {
      annot_rect_f.Transform(&matrix);
      FX_RECT annot_rect = annot_rect_f.GetOutterRect();
      annot_rect.Intersect(*clip_rect);
      if (annot_rect.IsEmpty()) {
        continue;
      }
    }
    if (pContext) {
      pAnnot->DrawInContext(pPage, pContext, &matrix, CPDF_Annot::Normal);
    } else if (!pAnnot->DrawAppearance(pPage, pDevice, &matrix,
                                       CPDF_Annot::Normal, pOptions)) {
      pAnnot->DrawBorder(pDevice, &matrix, pOptions);
    }
  }
}
void CPDF_AnnotList::DisplayAnnots(const CPDF_Page* pPage,
                                   CFX_RenderDevice* pDevice,
                                   CFX_AffineMatrix* pUser2Device,
                                   FX_BOOL bShowWidget,
                                   CPDF_RenderOptions* pOptions) {
  FX_RECT clip_rect;
  if (pDevice) {
    clip_rect = pDevice->GetClipBox();
  }
  FX_BOOL bPrinting = pDevice->GetDeviceClass() == FXDC_PRINTER ||
                      (pOptions && (pOptions->m_Flags & RENDER_PRINTPREVIEW));
  DisplayAnnots(pPage, pDevice, NULL, bPrinting, pUser2Device,
                bShowWidget ? 3 : 1, pOptions, &clip_rect);
}
void CPDF_AnnotList::DisplayAnnots(const CPDF_Page* pPage,
                                   CFX_RenderDevice* pDevice,
                                   CPDF_RenderContext* pContext,
                                   FX_BOOL bPrinting,
                                   CFX_AffineMatrix* pUser2Device,
                                   FX_DWORD dwAnnotFlags,
                                   CPDF_RenderOptions* pOptions,
                                   FX_RECT* pClipRect) {
  if (dwAnnotFlags & 0x01) {
    DisplayPass(pPage, pDevice, pContext, bPrinting, pUser2Device, FALSE,
                pOptions, pClipRect);
  }
  if (dwAnnotFlags & 0x02) {
    DisplayPass(pPage, pDevice, pContext, bPrinting, pUser2Device, TRUE,
                pOptions, pClipRect);
  }
}
int CPDF_AnnotList::GetIndex(CPDF_Annot* pAnnot) {
  for (int i = 0; i < m_AnnotList.GetSize(); ++i)
    if (m_AnnotList[i] == (void*)pAnnot) {
      return i;
    }
  return -1;
}
CPDF_Annot::CPDF_Annot(CPDF_Dictionary* pDict, CPDF_AnnotList* pList)
    : m_pAnnotDict(pDict),
      m_pList(pList),
      m_sSubtype(m_pAnnotDict->GetConstString(FX_BSTRC("Subtype"))) {}
CPDF_Annot::~CPDF_Annot() {
  ClearCachedAP();
}
void CPDF_Annot::ClearCachedAP() {
  FX_POSITION pos = m_APMap.GetStartPosition();
  while (pos) {
    void* pForm;
    void* pObjects;
    m_APMap.GetNextAssoc(pos, pForm, pObjects);
    delete (CPDF_PageObjects*)pObjects;
  }
  m_APMap.RemoveAll();
}
CFX_ByteString CPDF_Annot::GetSubType() const {
  return m_sSubtype;
}

void CPDF_Annot::GetRect(CPDF_Rect& rect) const {
  if (m_pAnnotDict == NULL) {
    return;
  }
  rect = m_pAnnotDict->GetRect("Rect");
  rect.Normalize();
}

FX_DWORD CPDF_Annot::GetFlags() const {
  return m_pAnnotDict->GetInteger("F");
}

CPDF_Dictionary* CPDF_Annot::GetAnnotDict() {
  return m_pAnnotDict;
}

CPDF_Stream* FPDFDOC_GetAnnotAP(CPDF_Dictionary* pAnnotDict,
                                CPDF_Annot::AppearanceMode mode) {
  CPDF_Dictionary* pAP = pAnnotDict->GetDict("AP");
  if (pAP == NULL) {
    return NULL;
  }
  const FX_CHAR* ap_entry = "N";
  if (mode == CPDF_Annot::Down) {
    ap_entry = "D";
  } else if (mode == CPDF_Annot::Rollover) {
    ap_entry = "R";
  }
  if (!pAP->KeyExist(ap_entry)) {
    ap_entry = "N";
  }
  CPDF_Object* psub = pAP->GetElementValue(ap_entry);
  if (psub == NULL) {
    return NULL;
  }
  CPDF_Stream* pStream = NULL;
  if (psub->GetType() == PDFOBJ_STREAM) {
    pStream = (CPDF_Stream*)psub;
  } else if (psub->GetType() == PDFOBJ_DICTIONARY) {
    CFX_ByteString as = pAnnotDict->GetString("AS");
    if (as.IsEmpty()) {
      CFX_ByteString value = pAnnotDict->GetString(FX_BSTRC("V"));
      if (value.IsEmpty()) {
        CPDF_Dictionary* pDict = pAnnotDict->GetDict(FX_BSTRC("Parent"));
        value = pDict ? pDict->GetString(FX_BSTRC("V")) : CFX_ByteString();
      }
      if (value.IsEmpty() || !((CPDF_Dictionary*)psub)->KeyExist(value)) {
        as = FX_BSTRC("Off");
      } else {
        as = value;
      }
    }
    pStream = ((CPDF_Dictionary*)psub)->GetStream(as);
  }
  return pStream;
}
CPDF_Form* CPDF_Annot::GetAPForm(const CPDF_Page* pPage, AppearanceMode mode) {
  CPDF_Stream* pStream = FPDFDOC_GetAnnotAP(m_pAnnotDict, mode);
  if (pStream == NULL) {
    return NULL;
  }
  CPDF_Form* pForm;
  if (m_APMap.Lookup(pStream, (void*&)pForm)) {
    return pForm;
  }
  pForm = new CPDF_Form(m_pList->m_pDocument, pPage->m_pResources, pStream);
  if (pForm == NULL) {
    return NULL;
  }
  pForm->ParseContent(NULL, NULL, NULL, NULL);
  m_APMap.SetAt(pStream, pForm);
  return pForm;
}
static CPDF_Form* FPDFDOC_Annot_GetMatrix(const CPDF_Page* pPage,
                                          CPDF_Annot* pAnnot,
                                          CPDF_Annot::AppearanceMode mode,
                                          const CFX_AffineMatrix* pUser2Device,
                                          CFX_Matrix& matrix) {
  CPDF_Form* pForm = pAnnot->GetAPForm(pPage, mode);
  if (!pForm) {
    return NULL;
  }
  CFX_FloatRect form_bbox = pForm->m_pFormDict->GetRect(FX_BSTRC("BBox"));
  CFX_Matrix form_matrix = pForm->m_pFormDict->GetMatrix(FX_BSTRC("Matrix"));
  form_matrix.TransformRect(form_bbox);
  CPDF_Rect arect;
  pAnnot->GetRect(arect);
  matrix.MatchRect(arect, form_bbox);
  matrix.Concat(*pUser2Device);
  return pForm;
}
FX_BOOL CPDF_Annot::DrawAppearance(const CPDF_Page* pPage,
                                   CFX_RenderDevice* pDevice,
                                   const CFX_AffineMatrix* pUser2Device,
                                   AppearanceMode mode,
                                   const CPDF_RenderOptions* pOptions) {
  CFX_Matrix matrix;
  CPDF_Form* pForm =
      FPDFDOC_Annot_GetMatrix(pPage, this, mode, pUser2Device, matrix);
  if (!pForm) {
    return FALSE;
  }
  CPDF_RenderContext context;
  context.Create((CPDF_Page*)pPage);
  context.DrawObjectList(pDevice, pForm, &matrix, pOptions);
  return TRUE;
}
FX_BOOL CPDF_Annot::DrawInContext(const CPDF_Page* pPage,
                                  const CPDF_RenderContext* pContext,
                                  const CFX_AffineMatrix* pUser2Device,
                                  AppearanceMode mode) {
  CFX_Matrix matrix;
  CPDF_Form* pForm =
      FPDFDOC_Annot_GetMatrix(pPage, this, mode, pUser2Device, matrix);
  if (!pForm) {
    return FALSE;
  }
  ((CPDF_RenderContext*)pContext)->AppendObjectList(pForm, &matrix);
  return TRUE;
}
void CPDF_Annot::DrawBorder(CFX_RenderDevice* pDevice,
                            const CFX_AffineMatrix* pUser2Device,
                            const CPDF_RenderOptions* pOptions) {
  if (GetSubType() == "Popup") {
    return;
  }
  FX_DWORD annot_flags = GetFlags();
  if (annot_flags & ANNOTFLAG_HIDDEN) {
    return;
  }
  FX_BOOL bPrinting = pDevice->GetDeviceClass() == FXDC_PRINTER ||
                      (pOptions && (pOptions->m_Flags & RENDER_PRINTPREVIEW));
  if (bPrinting && (annot_flags & ANNOTFLAG_PRINT) == 0) {
    return;
  }
  if (!bPrinting && (annot_flags & ANNOTFLAG_NOVIEW)) {
    return;
  }
  CPDF_Dictionary* pBS = m_pAnnotDict->GetDict("BS");
  char style_char;
  FX_FLOAT width;
  CPDF_Array* pDashArray = NULL;
  if (pBS == NULL) {
    CPDF_Array* pBorderArray = m_pAnnotDict->GetArray("Border");
    style_char = 'S';
    if (pBorderArray) {
      width = pBorderArray->GetNumber(2);
      if (pBorderArray->GetCount() == 4) {
        pDashArray = pBorderArray->GetArray(3);
        if (pDashArray == NULL) {
          return;
        }
        int nLen = pDashArray->GetCount();
        int i = 0;
        for (; i < nLen; ++i) {
          CPDF_Object* pObj = pDashArray->GetElementValue(i);
          if (pObj && pObj->GetInteger()) {
            break;
          }
        }
        if (i == nLen) {
          return;
        }
        style_char = 'D';
      }
    } else {
      width = 1;
    }
  } else {
    CFX_ByteString style = pBS->GetString("S");
    pDashArray = pBS->GetArray("D");
    style_char = style[1];
    width = pBS->GetNumber("W");
  }
  if (width <= 0) {
    return;
  }
  CPDF_Array* pColor = m_pAnnotDict->GetArray("C");
  FX_DWORD argb = 0xff000000;
  if (pColor != NULL) {
    int R = (int32_t)(pColor->GetNumber(0) * 255);
    int G = (int32_t)(pColor->GetNumber(1) * 255);
    int B = (int32_t)(pColor->GetNumber(2) * 255);
    argb = ArgbEncode(0xff, R, G, B);
  }
  CPDF_GraphStateData graph_state;
  graph_state.m_LineWidth = width;
  if (style_char == 'D') {
    if (pDashArray) {
      FX_DWORD dash_count = pDashArray->GetCount();
      if (dash_count % 2) {
        dash_count++;
      }
      graph_state.m_DashArray = FX_Alloc(FX_FLOAT, dash_count);
      graph_state.m_DashCount = dash_count;
      FX_DWORD i;
      for (i = 0; i < pDashArray->GetCount(); ++i) {
        graph_state.m_DashArray[i] = pDashArray->GetNumber(i);
      }
      if (i < dash_count) {
        graph_state.m_DashArray[i] = graph_state.m_DashArray[i - 1];
      }
    } else {
      graph_state.m_DashArray = FX_Alloc(FX_FLOAT, 2);
      graph_state.m_DashCount = 2;
      graph_state.m_DashArray[0] = graph_state.m_DashArray[1] = 3 * 1.0f;
    }
  }
  CFX_FloatRect rect;
  GetRect(rect);
  CPDF_PathData path;
  width /= 2;
  path.AppendRect(rect.left + width, rect.bottom + width, rect.right - width,
                  rect.top - width);
  int fill_type = 0;
  if (pOptions && (pOptions->m_Flags & RENDER_NOPATHSMOOTH)) {
    fill_type |= FXFILL_NOPATHSMOOTH;
  }
  pDevice->DrawPath(&path, pUser2Device, &graph_state, argb, argb, fill_type);
}
