// 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 "core/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->GetStringBy("S");
  if (type != "GoTo" && type != "GoToR") {
    return CPDF_Dest();
  }
  CPDF_Object* pDest = m_pDict->GetElementValue("D");
  if (!pDest) {
    return CPDF_Dest();
  }
  if (pDest->IsString() || pDest->IsName()) {
    CPDF_NameTree name_tree(pDoc, "Dests");
    CFX_ByteStringC name = pDest->GetString();
    return CPDF_Dest(name_tree.LookupNamedDest(pDoc, name));
  }
  if (CPDF_Array* pArray = pDest->AsArray())
    return CPDF_Dest(pArray);
  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) {
    CFX_ByteString csType = m_pDict->GetStringBy("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->GetStringBy("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) {
    if (type == "Launch") {
      CPDF_Dictionary* pWinDict = m_pDict->GetDictBy("Win");
      if (pWinDict) {
        return CFX_WideString::FromLocal(pWinDict->GetStringBy("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) {
    return csURI;
  }
  if (m_pDict->GetStringBy("S") != "URI") {
    return csURI;
  }
  csURI = m_pDict->GetStringBy("URI");
  CPDF_Dictionary* pRoot = pDoc->GetRoot();
  CPDF_Dictionary* pURI = pRoot->GetDictBy("URI");
  if (pURI) {
    if (csURI.Find(":", 0) < 1) {
      csURI = pURI->GetStringBy("Base") + csURI;
    }
  }
  return csURI;
}
FX_DWORD CPDF_ActionFields::GetFieldsCount() const {
  if (!m_pAction) {
    return 0;
  }
  CPDF_Dictionary* pDict = m_pAction->GetDict();
  if (!pDict) {
    return 0;
  }
  CFX_ByteString csType = pDict->GetStringBy("S");
  CPDF_Object* pFields = NULL;
  if (csType == "Hide") {
    pFields = pDict->GetElementValue("T");
  } else {
    pFields = pDict->GetArrayBy("Fields");
  }
  if (!pFields)
    return 0;
  if (pFields->IsDictionary())
    return 1;
  if (pFields->IsString())
    return 1;
  if (CPDF_Array* pArray = pFields->AsArray())
    return pArray->GetCount();
  return 0;
}

std::vector<CPDF_Object*> CPDF_ActionFields::GetAllFields() const {
  std::vector<CPDF_Object*> fields;
  if (!m_pAction)
    return fields;

  CPDF_Dictionary* pDict = m_pAction->GetDict();
  if (!pDict)
    return fields;

  CFX_ByteString csType = pDict->GetStringBy("S");
  CPDF_Object* pFields;
  if (csType == "Hide")
    pFields = pDict->GetElementValue("T");
  else
    pFields = pDict->GetArrayBy("Fields");
  if (!pFields)
    return fields;

  if (pFields->IsDictionary() || pFields->IsString()) {
    fields.push_back(pFields);
  } else if (CPDF_Array* pArray = pFields->AsArray()) {
    FX_DWORD iCount = pArray->GetCount();
    for (FX_DWORD i = 0; i < iCount; ++i) {
      CPDF_Object* pObj = pArray->GetElementValue(i);
      if (pObj) {
        fields.push_back(pObj);
      }
    }
  }
  return fields;
}

CPDF_Object* CPDF_ActionFields::GetField(FX_DWORD iIndex) const {
  if (!m_pAction) {
    return NULL;
  }
  CPDF_Dictionary* pDict = m_pAction->GetDict();
  if (!pDict) {
    return NULL;
  }
  CFX_ByteString csType = pDict->GetStringBy("S");
  CPDF_Object* pFields = NULL;
  if (csType == "Hide") {
    pFields = pDict->GetElementValue("T");
  } else {
    pFields = pDict->GetArrayBy("Fields");
  }
  if (!pFields) {
    return NULL;
  }
  CPDF_Object* pFindObj = NULL;
  if (pFields->IsDictionary() || pFields->IsString()) {
    if (iIndex == 0)
      pFindObj = pFields;
  } else if (CPDF_Array* pArray = pFields->AsArray()) {
    pFindObj = pArray->GetElementValue(iIndex);
  }
  return pFindObj;
}

CFX_WideString CPDF_Action::GetJavaScript() const {
  CFX_WideString csJS;
  if (!m_pDict) {
    return csJS;
  }
  CPDF_Object* pJS = m_pDict->GetElementValue("JS");
  return pJS ? pJS->GetUnicodeText() : csJS;
}
CPDF_Dictionary* CPDF_Action::GetAnnot() const {
  if (!m_pDict) {
    return nullptr;
  }
  CFX_ByteString csType = m_pDict->GetStringBy("S");
  if (csType == "Rendition") {
    return m_pDict->GetDictBy("AN");
  }
  if (csType == "Movie") {
    return m_pDict->GetDictBy("Annotation");
  }
  return nullptr;
}
int32_t CPDF_Action::GetOperationType() const {
  if (!m_pDict) {
    return 0;
  }
  CFX_ByteString csType = m_pDict->GetStringBy("S");
  if (csType == "Rendition") {
    return m_pDict->GetIntegerBy("OP");
  }
  if (csType == "Movie") {
    CFX_ByteString csOP = m_pDict->GetStringBy("Operation");
    if (csOP == "Play") {
      return 0;
    }
    if (csOP == "Stop") {
      return 1;
    }
    if (csOP == "Pause") {
      return 2;
    }
    if (csOP == "Resume") {
      return 3;
    }
  }
  return 0;
}
FX_DWORD CPDF_Action::GetSubActionsCount() const {
  if (!m_pDict || !m_pDict->KeyExist("Next"))
    return 0;

  CPDF_Object* pNext = m_pDict->GetElementValue("Next");
  if (!pNext)
    return 0;
  if (pNext->IsDictionary())
    return 1;
  if (CPDF_Array* pArray = pNext->AsArray())
    return pArray->GetCount();
  return 0;
}
CPDF_Action CPDF_Action::GetSubAction(FX_DWORD iIndex) const {
  if (!m_pDict || !m_pDict->KeyExist("Next")) {
    return CPDF_Action();
  }
  CPDF_Object* pNext = m_pDict->GetElementValue("Next");
  if (CPDF_Dictionary* pDict = ToDictionary(pNext)) {
    if (iIndex == 0)
      return CPDF_Action(pDict);
  } else if (CPDF_Array* pArray = ToArray(pNext)) {
    return CPDF_Action(pArray->GetDictAt(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 {
  return m_pDict && 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->GetDictBy(g_sAATypes[(int)eType]));
}

CPDF_DocJSActions::CPDF_DocJSActions(CPDF_Document* pDoc) : m_pDocument(pDoc) {}

int CPDF_DocJSActions::CountJSActions() const {
  ASSERT(m_pDocument);
  CPDF_NameTree name_tree(m_pDocument, "JavaScript");
  return name_tree.GetCount();
}
CPDF_Action CPDF_DocJSActions::GetJSAction(int index,
                                           CFX_ByteString& csName) const {
  ASSERT(m_pDocument);
  CPDF_NameTree name_tree(m_pDocument, "JavaScript");
  CPDF_Object* pAction = name_tree.LookupValue(index, csName);
  if (!ToDictionary(pAction)) {
    return CPDF_Action();
  }
  return CPDF_Action(pAction->GetDict());
}
CPDF_Action CPDF_DocJSActions::GetJSAction(const CFX_ByteString& csName) const {
  ASSERT(m_pDocument);
  CPDF_NameTree name_tree(m_pDocument, "JavaScript");
  CPDF_Object* pAction = name_tree.LookupValue(csName);
  if (!ToDictionary(pAction)) {
    return CPDF_Action();
  }
  return CPDF_Action(pAction->GetDict());
}
int CPDF_DocJSActions::FindJSAction(const CFX_ByteString& csName) const {
  ASSERT(m_pDocument);
  CPDF_NameTree name_tree(m_pDocument, "JavaScript");
  return name_tree.GetIndex(csName);
}
