// 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 "../../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 = FX_NEW CPDF_Annot(pDict);
        if (pAnnot == NULL) {
            break;
        }
        pAnnot->m_pList = 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->m_pAnnotDict;
            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] == (FX_LPVOID)pAnnot) {
            return i;
        }
    return -1;
}
CPDF_Annot::CPDF_Annot(CPDF_Dictionary* pDict)
{
    m_pList = NULL;
    m_pAnnotDict = pDict;
}
CPDF_Annot::~CPDF_Annot()
{
    ClearCachedAP();
}
CPDF_Reference* CPDF_Annot::NewAnnotRef()
{
    if (m_pAnnotDict->GetObjNum() == 0) {
        m_pList->m_pDocument->AddIndirectObject(m_pAnnotDict);
    }
    return CPDF_Reference::Create(m_pList->m_pDocument, m_pAnnotDict->GetObjNum());
}
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_pAnnotDict->GetConstString(FX_BSTRC("Subtype"));
}
void CPDF_Annot::GetRect(CPDF_Rect& rect) const
{
    if (m_pAnnotDict == NULL) {
        return;
    }
    rect = m_pAnnotDict->GetRect("Rect");
    rect.Normalize();
}
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()) {
                value = pAnnotDict->GetDict(FX_BSTRC("Parent"))->GetString(FX_BSTRC("V"));
            }
            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 = FX_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;
}
CPDF_PageObject* CPDF_Annot::GetBorder(FX_BOOL bPrint, const CPDF_RenderOptions* pOptions)
{
    if (GetSubType() == "Popup") {
        return NULL;
    }
    FX_DWORD annot_flags = GetFlags();
    if (annot_flags & ANNOTFLAG_HIDDEN) {
        return NULL;
    }
    FX_BOOL bPrinting = bPrint || (pOptions && (pOptions->m_Flags & RENDER_PRINTPREVIEW));
    if (bPrinting && (annot_flags & ANNOTFLAG_PRINT) == 0) {
        return NULL;
    }
    if (!bPrinting && (annot_flags & ANNOTFLAG_NOVIEW)) {
        return NULL;
    }
    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 NULL;
                }
                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 NULL;
    }
    CPDF_Array* pColor = m_pAnnotDict->GetArray("C");
    FX_DWORD argb = 0xff000000;
    if (pColor != NULL) {
        int R = (FX_INT32)(pColor->GetNumber(0) * 255);
        int G = (FX_INT32)(pColor->GetNumber(1) * 255);
        int B = (FX_INT32)(pColor->GetNumber(2) * 255);
        argb = ArgbEncode(0xff, R, G, B);
    }
    CPDF_PathObject *pPathObject = FX_NEW CPDF_PathObject();
    if (!pPathObject) {
        return NULL;
    }
    CPDF_GraphStateData *pGraphState = pPathObject->m_GraphState.GetModify();
    if (!pGraphState) {
        pPathObject->Release();
        return NULL;
    }
    pGraphState->m_LineWidth = width;
    CPDF_ColorStateData *pColorData = pPathObject->m_ColorState.GetModify();
    if (!pColorData) {
        pPathObject->Release();
        return NULL;
    }
    pColorData->m_StrokeRGB = argb;
    pPathObject->m_bStroke = TRUE;
    pPathObject->m_FillType = 0;
    if (style_char == 'D') {
        if (pDashArray) {
            FX_DWORD dash_count = pDashArray->GetCount();
            if (dash_count % 2) {
                dash_count ++;
            }
            pGraphState->m_DashArray = FX_Alloc(FX_FLOAT, dash_count);
            if (pGraphState->m_DashArray == NULL) {
                pPathObject->Release();
                return NULL;
            }
            pGraphState->m_DashCount = dash_count;
            FX_DWORD i;
            for (i = 0; i < pDashArray->GetCount(); i ++) {
                pGraphState->m_DashArray[i] = pDashArray->GetNumber(i);
            }
            if (i < dash_count) {
                pGraphState->m_DashArray[i] = pGraphState->m_DashArray[i - 1];
            }
        } else {
            pGraphState->m_DashArray = FX_Alloc(FX_FLOAT, 2);
            if (pGraphState->m_DashArray == NULL) {
                pPathObject->Release();
                return NULL;
            }
            pGraphState->m_DashCount = 2;
            pGraphState->m_DashArray[0] = pGraphState->m_DashArray[1] = 3 * 1.0f;
        }
    }
    CFX_FloatRect rect;
    GetRect(rect);
    width /= 2;
    CPDF_PathData *pPathData = pPathObject->m_Path.GetModify();
    if (pPathData) {
        pPathData->AppendRect(rect.left + width, rect.bottom + width, rect.right - width, rect.top - width);
    }
    pPathObject->CalcBoundingBox();
    return pPathObject;
}
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 = (FX_INT32)(pColor->GetNumber(0) * 255);
        int G = (FX_INT32)(pColor->GetNumber(1) * 255);
        int B = (FX_INT32)(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);
            if (graph_state.m_DashArray == NULL) {
                return ;
            }
            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);
            if (graph_state.m_DashArray == NULL) {
                return ;
            }
            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);
}
int CPDF_Annot::CountIRTNotes()
{
    int count = 0;
    for (int i = 0; i < m_pList->Count(); i ++) {
        CPDF_Annot* pAnnot = m_pList->GetAt(i);
        if (pAnnot == NULL) {
            continue;
        }
        CPDF_Dictionary* pIRT = pAnnot->m_pAnnotDict->GetDict("IRT");
        if (pIRT != m_pAnnotDict) {
            continue;
        }
        count ++;
    }
    return count;
}
CPDF_Annot* CPDF_Annot::GetIRTNote(int index)
{
    int count = 0;
    for (int i = 0; i < m_pList->Count(); i ++) {
        CPDF_Annot* pAnnot = m_pList->GetAt(i);
        if (pAnnot == NULL) {
            continue;
        }
        CPDF_Dictionary* pIRT = pAnnot->m_pAnnotDict->GetDict("IRT");
        if (pIRT != m_pAnnotDict) {
            continue;
        }
        if (count == index) {
            return pAnnot;
        }
        count ++;
    }
    return NULL;
}
