// 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);
    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);
}
