// 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"
CPDF_Dest CPDF_Action::GetDest(CPDF_Document* pDoc) const
{
    if (!m_pDict) {
        return CPDF_Dest();
    }
    CFX_ByteString type = m_pDict->GetString("S");
    if (type != "GoTo" && type != "GoToR") {
        return CPDF_Dest();
    }
    CPDF_Object* pDest = m_pDict->GetElementValue("D");
    if (!pDest) {
        return CPDF_Dest();
    }
    if (pDest->GetType() == PDFOBJ_STRING || pDest->GetType() == PDFOBJ_NAME) {
        CPDF_NameTree name_tree(pDoc, FX_BSTRC("Dests"));
        CFX_ByteStringC name = pDest->GetString();
        return CPDF_Dest(name_tree.LookupNamedDest(pDoc, name));
    }
    if (pDest->GetType() == PDFOBJ_ARRAY) {
        return CPDF_Dest((CPDF_Array*)pDest);
    }
    return CPDF_Dest();
}
const FX_CHAR* g_sATypes[] = {"Unknown", "GoTo", "GoToR", "GoToE", "Launch", "Thread", "URI", "Sound", "Movie",
                              "Hide",	"Named", "SubmitForm", "ResetForm", "ImportData", "JavaScript", "SetOCGState",
                              "Rendition", "Trans", "GoTo3DView", ""
                             };
CPDF_Action::ActionType CPDF_Action::GetType() const
{
    ActionType eType = Unknown;
    if (m_pDict != NULL) {
        CFX_ByteString csType = m_pDict->GetString("S");
        if (!csType.IsEmpty()) {
            int i = 0;
            while (g_sATypes[i][0] != '\0') {
                if (csType == g_sATypes[i]) {
                    return (ActionType)i;
                }
                i ++;
            }
        }
    }
    return eType;
}
CFX_WideString CPDF_Action::GetFilePath() const
{
    CFX_ByteString type = m_pDict->GetString("S");
    if (type != "GoToR" && type != "Launch" &&
            type != "SubmitForm" && type != "ImportData") {
        return CFX_WideString();
    }
    CPDF_Object* pFile = m_pDict->GetElementValue("F");
    CFX_WideString path;
    if (pFile == NULL) {
        if (type == "Launch") {
            CPDF_Dictionary* pWinDict = m_pDict->GetDict(FX_BSTRC("Win"));
            if (pWinDict) {
                return CFX_WideString::FromLocal(pWinDict->GetString(FX_BSTRC("F")));
            }
        }
        return path;
    }
    CPDF_FileSpec filespec(pFile);
    filespec.GetFileName(path);
    return path;
}
CFX_ByteString CPDF_Action::GetURI(CPDF_Document* pDoc) const
{
    CFX_ByteString csURI;
    if (m_pDict == NULL) {
        return csURI;
    }
    if (m_pDict->GetString("S") != "URI") {
        return csURI;
    }
    csURI = m_pDict->GetString("URI");
    CPDF_Dictionary* pRoot = pDoc->GetRoot();
    CPDF_Dictionary* pURI = pRoot->GetDict("URI");
    if (pURI != NULL) {
        if (csURI.Find(FX_BSTRC(":"), 0) < 1) {
            csURI = pURI->GetString("Base") + csURI;
        }
    }
    return csURI;
}
FX_DWORD CPDF_ActionFields::GetFieldsCount() const
{
    if (m_pAction == NULL) {
        return 0;
    }
    CPDF_Dictionary* pDict = m_pAction->GetDict();
    if (pDict == NULL) {
        return 0;
    }
    CFX_ByteString csType = pDict->GetString("S");
    CPDF_Object* pFields = NULL;
    if (csType == "Hide") {
        pFields = pDict->GetElementValue("T");
    } else {
        pFields = pDict->GetArray("Fields");
    }
    if (pFields == NULL) {
        return 0;
    }
    int iType = pFields->GetType();
    if (iType == PDFOBJ_DICTIONARY) {
        return 1;
    } else if (iType == PDFOBJ_STRING) {
        return 1;
    } else if (iType == PDFOBJ_ARRAY) {
        return ((CPDF_Array*)pFields)->GetCount();
    }
    return 0;
}
void CPDF_ActionFields::GetAllFields(CFX_PtrArray& fieldObjects) const
{
    fieldObjects.RemoveAll();
    if (m_pAction == NULL) {
        return;
    }
    CPDF_Dictionary* pDict = m_pAction->GetDict();
    if (pDict == NULL) {
        return;
    }
    CFX_ByteString csType = pDict->GetString("S");
    CPDF_Object* pFields = NULL;
    if (csType == "Hide") {
        pFields = pDict->GetElementValue("T");
    } else {
        pFields = pDict->GetArray("Fields");
    }
    if (pFields == NULL) {
        return;
    }
    int iType = pFields->GetType();
    if (iType == PDFOBJ_DICTIONARY || iType == PDFOBJ_STRING) {
        fieldObjects.Add(pFields);
    } else if (iType == PDFOBJ_ARRAY) {
        CPDF_Array* pArray = (CPDF_Array*)pFields;
        FX_DWORD iCount = pArray->GetCount();
        for (FX_DWORD i = 0; i < iCount; i ++) {
            CPDF_Object* pObj = pArray->GetElementValue(i);
            if (pObj != NULL) {
                fieldObjects.Add(pObj);
            }
        }
    }
}
CPDF_Object* CPDF_ActionFields::GetField(FX_DWORD iIndex) const
{
    if (m_pAction == NULL) {
        return NULL;
    }
    CPDF_Dictionary* pDict = m_pAction->GetDict();
    if (pDict == NULL) {
        return NULL;
    }
    CFX_ByteString csType = pDict->GetString("S");
    CPDF_Object* pFields = NULL;
    if (csType == "Hide") {
        pFields = pDict->GetElementValue("T");
    } else {
        pFields = pDict->GetArray("Fields");
    }
    if (pFields == NULL) {
        return NULL;
    }
    CPDF_Object* pFindObj = NULL;
    int iType = pFields->GetType();
    if (iType == PDFOBJ_DICTIONARY || iType == PDFOBJ_STRING) {
        if (iIndex == 0) {
            pFindObj = pFields;
        }
    } else if (iType == PDFOBJ_ARRAY) {
        pFindObj = ((CPDF_Array*)pFields)->GetElementValue(iIndex);
    }
    return pFindObj;
}
CPDF_LWinParam CPDF_Action::GetWinParam() const
{
    if (m_pDict == NULL) {
        return NULL;
    }
    if (m_pDict->GetString("S") != "Launch") {
        return NULL;
    }
    return m_pDict->GetDict("Win");
}
CFX_WideString CPDF_Action::GetJavaScript() const
{
    CFX_WideString csJS;
    if (m_pDict == NULL) {
        return csJS;
    }
    CPDF_Object* pJS = m_pDict->GetElementValue("JS");
    if (pJS != NULL) {
        return pJS->GetUnicodeText();
    }
    return csJS;
}
CPDF_Dictionary* CPDF_Action::GetAnnot() const
{
    if (m_pDict == NULL) {
        return NULL;
    }
    CFX_ByteString csType = m_pDict->GetString("S");
    if (csType == FX_BSTRC("Rendition")) {
        return m_pDict->GetDict("AN");
    } else if (csType == FX_BSTRC("Movie")) {
        return m_pDict->GetDict("Annotation");
    }
    return NULL;
}
int32_t CPDF_Action::GetOperationType() const
{
    if (m_pDict == NULL) {
        return 0;
    }
    CFX_ByteString csType = m_pDict->GetString("S");
    if (csType == FX_BSTRC("Rendition")) {
        return m_pDict->GetInteger("OP");
    } else if (csType == FX_BSTRC("Movie")) {
        CFX_ByteString csOP = m_pDict->GetString("Operation");
        if (csOP == FX_BSTRC("Play")) {
            return 0;
        } else if (csOP == FX_BSTRC("Stop")) {
            return 1;
        } else if (csOP == FX_BSTRC("Pause")) {
            return 2;
        } else if (csOP == FX_BSTRC("Resume")) {
            return 3;
        }
    }
    return 0;
}
FX_DWORD CPDF_Action::GetSubActionsCount() const
{
    if (m_pDict == NULL || !m_pDict->KeyExist("Next")) {
        return 0;
    }
    CPDF_Object* pNext = m_pDict->GetElementValue("Next");
    if (!pNext) {
        return 0;
    }
    int iObjType = pNext->GetType();
    if (iObjType == PDFOBJ_DICTIONARY) {
        return 1;
    }
    if (iObjType == PDFOBJ_ARRAY) {
        return ((CPDF_Array*)pNext)->GetCount();
    }
    return 0;
}
CPDF_Action CPDF_Action::GetSubAction(FX_DWORD iIndex) const
{
    if (m_pDict == NULL || !m_pDict->KeyExist("Next")) {
        return CPDF_Action();
    }
    CPDF_Object* pNext = m_pDict->GetElementValue("Next");
    int iObjType = pNext->GetType();
    if (iObjType == PDFOBJ_DICTIONARY) {
        CPDF_Dictionary *pDict = static_cast<CPDF_Dictionary*>(pNext);
        if (iIndex == 0) {
            return CPDF_Action(pDict);
        }
    } else if (iObjType == PDFOBJ_ARRAY) {
        CPDF_Array* pArray = static_cast<CPDF_Array*>(pNext);
        return CPDF_Action(pArray->GetDict(iIndex));
    }
    return CPDF_Action();
}
const FX_CHAR* g_sAATypes[] = {"E", "X", "D", "U", "Fo", "Bl", "PO", "PC", "PV", "PI",
                               "O", "C",
                               "K", "F", "V", "C",
                               "WC", "WS", "DS", "WP", "DP",
                               ""
                              };
FX_BOOL CPDF_AAction::ActionExist(AActionType eType) const
{
    if (m_pDict == NULL) {
        return FALSE;
    }
    return m_pDict->KeyExist(g_sAATypes[(int)eType]);
}
CPDF_Action CPDF_AAction::GetAction(AActionType eType) const
{
    if (!m_pDict) {
        return CPDF_Action();
    }
    return CPDF_Action(m_pDict->GetDict(g_sAATypes[(int)eType]));
}
FX_POSITION CPDF_AAction::GetStartPos() const
{
    if (m_pDict == NULL) {
        return NULL;
    }
    return m_pDict->GetStartPos();
}
CPDF_Action CPDF_AAction::GetNextAction(FX_POSITION& pos, AActionType& eType) const
{
    if (m_pDict == NULL) {
        return CPDF_Action();
    }
    CFX_ByteString csKey;
    CPDF_Object* pObj = m_pDict->GetNextElement(pos, csKey);
    if (!pObj) {
        return CPDF_Action();
    }
    CPDF_Object* pDirect = pObj->GetDirect();
    if (!pDirect || pDirect->GetType() != PDFOBJ_DICTIONARY) {
        return CPDF_Action();
    }
    int i = 0;
    while (g_sAATypes[i][0] != '\0') {
        if (csKey == g_sAATypes[i]) {
            break;
        }
        i++;
    }
    eType = (AActionType)i;
    return CPDF_Action(static_cast<CPDF_Dictionary*>(pDirect));
}
CPDF_DocJSActions::CPDF_DocJSActions(CPDF_Document* pDoc)
{
    m_pDocument = pDoc;
}
int CPDF_DocJSActions::CountJSActions() const
{
    ASSERT(m_pDocument != NULL);
    CPDF_NameTree name_tree(m_pDocument, FX_BSTRC("JavaScript"));
    return name_tree.GetCount();
}
CPDF_Action CPDF_DocJSActions::GetJSAction(int index, CFX_ByteString& csName) const
{
    ASSERT(m_pDocument != NULL);
    CPDF_NameTree name_tree(m_pDocument, FX_BSTRC("JavaScript"));
    CPDF_Object *pAction = name_tree.LookupValue(index, csName);
    if (pAction == NULL || pAction->GetType() != PDFOBJ_DICTIONARY) {
        return CPDF_Action();
    }
    return CPDF_Action(pAction->GetDict());
}
CPDF_Action CPDF_DocJSActions::GetJSAction(const CFX_ByteString& csName) const
{
    ASSERT(m_pDocument != NULL);
    CPDF_NameTree name_tree(m_pDocument, FX_BSTRC("JavaScript"));
    CPDF_Object *pAction = name_tree.LookupValue(csName);
    if (pAction == NULL || pAction->GetType() != PDFOBJ_DICTIONARY) {
        return CPDF_Action();
    }
    return CPDF_Action(pAction->GetDict());
}
int CPDF_DocJSActions::FindJSAction(const CFX_ByteString& csName) const
{
    ASSERT(m_pDocument != NULL);
    CPDF_NameTree name_tree(m_pDocument, FX_BSTRC("JavaScript"));
    return name_tree.GetIndex(csName);
}
