// 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/fpdfxfa/fpdfxfa_doc.h"
#include "fpdfsdk/include/fsdk_actionhandler.h"
#include "fpdfsdk/include/fsdk_define.h"
#include "fpdfsdk/include/fsdk_mgr.h"
#include "fpdfsdk/include/javascript/IJavaScript.h"

CPDFSDK_ActionHandler::CPDFSDK_ActionHandler()
    : m_pFormActionHandler(new CPDFSDK_FormActionHandler) {
}

FX_BOOL CPDFSDK_ActionHandler::DoAction_DocOpen(const CPDF_Action& action,
                                                CPDFSDK_Document* pDocument) {
  CFX_PtrList list;
  return ExecuteDocumentOpenAction(action, pDocument, list);
}

FX_BOOL CPDFSDK_ActionHandler::DoAction_JavaScript(
    const CPDF_Action& JsAction,
    CFX_WideString csJSName,
    CPDFSDK_Document* pDocument) {
  if (JsAction.GetType() == CPDF_Action::JavaScript) {
    CFX_WideString swJS = JsAction.GetJavaScript();
    if (!swJS.IsEmpty()) {
      RunDocumentOpenJavaScript(pDocument, csJSName, swJS);
      return TRUE;
    }
  }

  return FALSE;
}

FX_BOOL CPDFSDK_ActionHandler::DoAction_FieldJavaScript(
    const CPDF_Action& JsAction,
    CPDF_AAction::AActionType type,
    CPDFSDK_Document* pDocument,
    CPDF_FormField* pFormField,
    PDFSDK_FieldAction& data) {
  CPDFDoc_Environment* pEnv = pDocument->GetEnv();
  ASSERT(pEnv);
  if (pEnv->IsJSInitiated() && JsAction.GetType() == CPDF_Action::JavaScript) {
    CFX_WideString swJS = JsAction.GetJavaScript();
    if (!swJS.IsEmpty()) {
      RunFieldJavaScript(pDocument, pFormField, type, data, swJS);
      return TRUE;
    }
  }
  return FALSE;
}

FX_BOOL CPDFSDK_ActionHandler::DoAction_Page(
    const CPDF_Action& action,
    enum CPDF_AAction::AActionType eType,
    CPDFSDK_Document* pDocument) {
  CFX_PtrList list;
  return ExecuteDocumentPageAction(action, eType, pDocument, list);
}

FX_BOOL CPDFSDK_ActionHandler::DoAction_Document(
    const CPDF_Action& action,
    enum CPDF_AAction::AActionType eType,
    CPDFSDK_Document* pDocument) {
  CFX_PtrList list;
  return ExecuteDocumentPageAction(action, eType, pDocument, list);
}

FX_BOOL CPDFSDK_ActionHandler::DoAction_BookMark(CPDF_Bookmark* pBookMark,
                                                 const CPDF_Action& action,
                                                 CPDF_AAction::AActionType type,
                                                 CPDFSDK_Document* pDocument) {
  CFX_PtrList list;
  return ExecuteBookMark(action, pDocument, pBookMark, list);
}

FX_BOOL CPDFSDK_ActionHandler::DoAction_Screen(const CPDF_Action& action,
                                               CPDF_AAction::AActionType type,
                                               CPDFSDK_Document* pDocument,
                                               CPDFSDK_Annot* pScreen) {
  CFX_PtrList list;
  return ExecuteScreenAction(action, type, pDocument, pScreen, list);
}

FX_BOOL CPDFSDK_ActionHandler::DoAction_Link(const CPDF_Action& action,
                                             CPDFSDK_Document* pDocument) {
  CFX_PtrList list;
  return ExecuteLinkAction(action, pDocument, list);
}

FX_BOOL CPDFSDK_ActionHandler::DoAction_Field(const CPDF_Action& action,
                                              CPDF_AAction::AActionType type,
                                              CPDFSDK_Document* pDocument,
                                              CPDF_FormField* pFormField,
                                              PDFSDK_FieldAction& data) {
  CFX_PtrList list;
  return ExecuteFieldAction(action, type, pDocument, pFormField, data, list);
}

FX_BOOL CPDFSDK_ActionHandler::ExecuteDocumentOpenAction(
    const CPDF_Action& action,
    CPDFSDK_Document* pDocument,
    CFX_PtrList& list) {
  CPDF_Dictionary* pDict = action.GetDict();
  if (list.Find(pDict))
    return FALSE;

  list.AddTail(pDict);

  CPDFDoc_Environment* pEnv = pDocument->GetEnv();
  ASSERT(pEnv);
  if (action.GetType() == CPDF_Action::JavaScript) {
    if (pEnv->IsJSInitiated()) {
      CFX_WideString swJS = action.GetJavaScript();
      if (!swJS.IsEmpty()) {
        RunDocumentOpenJavaScript(pDocument, L"", swJS);
      }
    }
  } else {
    DoAction_NoJs(action, pDocument);
  }

  for (int32_t i = 0, sz = action.GetSubActionsCount(); i < sz; i++) {
    CPDF_Action subaction = action.GetSubAction(i);
    if (!ExecuteDocumentOpenAction(subaction, pDocument, list))
      return FALSE;
  }

  return TRUE;
}

FX_BOOL CPDFSDK_ActionHandler::ExecuteLinkAction(const CPDF_Action& action,
                                                 CPDFSDK_Document* pDocument,
                                                 CFX_PtrList& list) {
  ASSERT(pDocument != NULL);

  CPDF_Dictionary* pDict = action.GetDict();
  if (list.Find(pDict))
    return FALSE;

  list.AddTail(pDict);

  CPDFDoc_Environment* pEnv = pDocument->GetEnv();
  ASSERT(pEnv);
  if (action.GetType() == CPDF_Action::JavaScript) {
    if (pEnv->IsJSInitiated()) {
      CFX_WideString swJS = action.GetJavaScript();
      if (!swJS.IsEmpty()) {
        IJS_Runtime* pRuntime = pDocument->GetJsRuntime();
        pRuntime->SetReaderDocument(pDocument);

        IJS_Context* pContext = pRuntime->NewContext();
        pContext->OnLink_MouseUp(pDocument);

        CFX_WideString csInfo;
        FX_BOOL bRet = pContext->RunScript(swJS, &csInfo);
        if (!bRet) {
          // FIXME: return error.
        }

        pRuntime->ReleaseContext(pContext);
      }
    }
  } else {
    DoAction_NoJs(action, pDocument);
  }

  for (int32_t i = 0, sz = action.GetSubActionsCount(); i < sz; i++) {
    CPDF_Action subaction = action.GetSubAction(i);
    if (!ExecuteLinkAction(subaction, pDocument, list))
      return FALSE;
  }

  return TRUE;
}

FX_BOOL CPDFSDK_ActionHandler::ExecuteDocumentPageAction(
    const CPDF_Action& action,
    CPDF_AAction::AActionType type,
    CPDFSDK_Document* pDocument,
    CFX_PtrList& list) {
  ASSERT(pDocument != NULL);

  CPDF_Dictionary* pDict = action.GetDict();
  if (list.Find(pDict))
    return FALSE;

  list.AddTail(pDict);

  CPDFDoc_Environment* pEnv = pDocument->GetEnv();
  ASSERT(pEnv);
  if (action.GetType() == CPDF_Action::JavaScript) {
    if (pEnv->IsJSInitiated()) {
      CFX_WideString swJS = action.GetJavaScript();
      if (!swJS.IsEmpty()) {
        RunDocumentPageJavaScript(pDocument, type, swJS);
      }
    }
  } else {
    DoAction_NoJs(action, pDocument);
  }

  if (!IsValidDocView(pDocument))
    return FALSE;

  for (int32_t i = 0, sz = action.GetSubActionsCount(); i < sz; i++) {
    CPDF_Action subaction = action.GetSubAction(i);
    if (!ExecuteDocumentPageAction(subaction, type, pDocument, list))
      return FALSE;
  }

  return TRUE;
}

FX_BOOL CPDFSDK_ActionHandler::IsValidField(CPDFSDK_Document* pDocument,
                                            CPDF_Dictionary* pFieldDict) {
  ASSERT(pDocument != NULL);
  ASSERT(pFieldDict != NULL);

  CPDFSDK_InterForm* pInterForm = pDocument->GetInterForm();
  ASSERT(pInterForm != NULL);

  CPDF_InterForm* pPDFInterForm = pInterForm->GetInterForm();
  ASSERT(pPDFInterForm != NULL);

  return pPDFInterForm->GetFieldByDict(pFieldDict) != NULL;
}

FX_BOOL CPDFSDK_ActionHandler::ExecuteFieldAction(
    const CPDF_Action& action,
    CPDF_AAction::AActionType type,
    CPDFSDK_Document* pDocument,
    CPDF_FormField* pFormField,
    PDFSDK_FieldAction& data,
    CFX_PtrList& list) {
  ASSERT(pDocument != NULL);

  CPDF_Dictionary* pDict = action.GetDict();
  if (list.Find(pDict))
    return FALSE;

  list.AddTail(pDict);

  CPDFDoc_Environment* pEnv = pDocument->GetEnv();
  ASSERT(pEnv);
  if (action.GetType() == CPDF_Action::JavaScript) {
    if (pEnv->IsJSInitiated()) {
      CFX_WideString swJS = action.GetJavaScript();
      if (!swJS.IsEmpty()) {
        RunFieldJavaScript(pDocument, pFormField, type, data, swJS);
        if (!IsValidField(pDocument, pFormField->GetFieldDict()))
          return FALSE;
      }
    }
  } else {
    DoAction_NoJs(action, pDocument);
  }

  for (int32_t i = 0, sz = action.GetSubActionsCount(); i < sz; i++) {
    CPDF_Action subaction = action.GetSubAction(i);
    if (!ExecuteFieldAction(subaction, type, pDocument, pFormField, data, list))
      return FALSE;
  }

  return TRUE;
}

FX_BOOL CPDFSDK_ActionHandler::ExecuteScreenAction(
    const CPDF_Action& action,
    CPDF_AAction::AActionType type,
    CPDFSDK_Document* pDocument,
    CPDFSDK_Annot* pScreen,
    CFX_PtrList& list) {
  ASSERT(pDocument != NULL);

  CPDF_Dictionary* pDict = action.GetDict();
  if (list.Find(pDict))
    return FALSE;

  list.AddTail(pDict);

  CPDFDoc_Environment* pEnv = pDocument->GetEnv();
  ASSERT(pEnv);
  if (action.GetType() == CPDF_Action::JavaScript) {
    if (pEnv->IsJSInitiated()) {
      CFX_WideString swJS = action.GetJavaScript();
      if (!swJS.IsEmpty()) {
        IJS_Runtime* pRuntime = pDocument->GetJsRuntime();
        pRuntime->SetReaderDocument(pDocument);

        IJS_Context* pContext = pRuntime->NewContext();
        CFX_WideString csInfo;
        FX_BOOL bRet = pContext->RunScript(swJS, &csInfo);
        if (!bRet) {
          // FIXME: return error.
        }

        pRuntime->ReleaseContext(pContext);
      }
    }
  } else {
    DoAction_NoJs(action, pDocument);
  }

  for (int32_t i = 0, sz = action.GetSubActionsCount(); i < sz; i++) {
    CPDF_Action subaction = action.GetSubAction(i);
    if (!ExecuteScreenAction(subaction, type, pDocument, pScreen, list))
      return FALSE;
  }

  return TRUE;
}

FX_BOOL CPDFSDK_ActionHandler::ExecuteBookMark(const CPDF_Action& action,
                                               CPDFSDK_Document* pDocument,
                                               CPDF_Bookmark* pBookmark,
                                               CFX_PtrList& list) {
  ASSERT(pDocument != NULL);

  CPDF_Dictionary* pDict = action.GetDict();
  if (list.Find(pDict))
    return FALSE;

  list.AddTail(pDict);

  CPDFDoc_Environment* pEnv = pDocument->GetEnv();
  ASSERT(pEnv);
  if (action.GetType() == CPDF_Action::JavaScript) {
    if (pEnv->IsJSInitiated()) {
      CFX_WideString swJS = action.GetJavaScript();
      if (!swJS.IsEmpty()) {
        IJS_Runtime* pRuntime = pDocument->GetJsRuntime();
        pRuntime->SetReaderDocument(pDocument);

        IJS_Context* pContext = pRuntime->NewContext();
        pContext->OnBookmark_MouseUp(pBookmark);

        CFX_WideString csInfo;
        FX_BOOL bRet = pContext->RunScript(swJS, &csInfo);
        if (!bRet) {
          // FIXME: return error.
        }

        pRuntime->ReleaseContext(pContext);
      }
    }
  } else {
    DoAction_NoJs(action, pDocument);
  }

  for (int32_t i = 0, sz = action.GetSubActionsCount(); i < sz; i++) {
    CPDF_Action subaction = action.GetSubAction(i);
    if (!ExecuteBookMark(subaction, pDocument, pBookmark, list))
      return FALSE;
  }

  return TRUE;
}

void CPDFSDK_ActionHandler::DoAction_NoJs(const CPDF_Action& action,
                                          CPDFSDK_Document* pDocument) {
  ASSERT(pDocument != NULL);

  switch (action.GetType()) {
    case CPDF_Action::GoTo:
      DoAction_GoTo(pDocument, action);
      break;
    case CPDF_Action::GoToR:
      DoAction_GoToR(pDocument, action);
      break;
    case CPDF_Action::GoToE:
      break;
    case CPDF_Action::Launch:
      DoAction_Launch(pDocument, action);
      break;
    case CPDF_Action::Thread:
      break;
    case CPDF_Action::URI:
      DoAction_URI(pDocument, action);
      break;
    case CPDF_Action::Sound:
      break;
    case CPDF_Action::Movie:
      break;
    case CPDF_Action::Hide:
      if (m_pFormActionHandler) {
        m_pFormActionHandler->DoAction_Hide(action, pDocument);
      }
      break;
    case CPDF_Action::Named:
      DoAction_Named(pDocument, action);
      break;
    case CPDF_Action::SubmitForm:
      if (m_pFormActionHandler) {
        m_pFormActionHandler->DoAction_SubmitForm(action, pDocument);
      }
      break;
    case CPDF_Action::ResetForm:
      if (m_pFormActionHandler) {
        m_pFormActionHandler->DoAction_ResetForm(action, pDocument);
      }
      break;
    case CPDF_Action::ImportData:
      if (m_pFormActionHandler) {
        m_pFormActionHandler->DoAction_ImportData(action, pDocument);
      }
      break;
    case CPDF_Action::JavaScript:
      ASSERT(FALSE);
      break;
    case CPDF_Action::SetOCGState:
      DoAction_SetOCGState(pDocument, action);
      break;
    case CPDF_Action::Rendition:
      break;
    case CPDF_Action::Trans:
      break;
    case CPDF_Action::GoTo3DView:
      break;
    default:
      break;
  }
}

FX_BOOL CPDFSDK_ActionHandler::IsValidDocView(CPDFSDK_Document* pDocument) {
  ASSERT(pDocument);
  return TRUE;
}

void CPDFSDK_ActionHandler::DoAction_GoTo(CPDFSDK_Document* pDocument,
                                          const CPDF_Action& action) {
  ASSERT(action);

  CPDF_Document* pPDFDocument = pDocument->GetDocument()->GetPDFDoc();
  ASSERT(pPDFDocument);

  CPDF_Dest MyDest = action.GetDest(pPDFDocument);
  int nPageIndex = MyDest.GetPageIndex(pPDFDocument);
  int nFitType = MyDest.GetZoomMode();
  const CPDF_Array* pMyArray = ToArray(MyDest.GetObject());
  float* pPosAry = nullptr;
  int sizeOfAry = 0;
  if (pMyArray) {
    pPosAry = new float[pMyArray->GetCount()];
    int j = 0;
    for (int i = 2; i < (int)pMyArray->GetCount(); i++) {
      pPosAry[j++] = pMyArray->GetFloat(i);
    }
    sizeOfAry = j;
  }

  CPDFDoc_Environment* pApp = pDocument->GetEnv();
  pApp->FFI_DoGoToAction(nPageIndex, nFitType, pPosAry, sizeOfAry);
  delete[] pPosAry;
}

void CPDFSDK_ActionHandler::DoAction_GoToR(CPDFSDK_Document* pDocument,
                                           const CPDF_Action& action) {}

void CPDFSDK_ActionHandler::DoAction_Launch(CPDFSDK_Document* pDocument,
                                            const CPDF_Action& action) {}

void CPDFSDK_ActionHandler::DoAction_URI(CPDFSDK_Document* pDocument,
                                         const CPDF_Action& action) {
  ASSERT(action);

  CPDFDoc_Environment* pApp = pDocument->GetEnv();
  ASSERT(pApp != NULL);

  CFX_ByteString sURI = action.GetURI(pDocument->GetDocument()->GetPDFDoc());
  pApp->FFI_DoURIAction(sURI.c_str());
}

void CPDFSDK_ActionHandler::DoAction_Named(CPDFSDK_Document* pDocument,
                                           const CPDF_Action& action) {
  ASSERT(action);

  CFX_ByteString csName = action.GetNamedAction();
  pDocument->GetEnv()->FFI_ExecuteNamedAction(csName);
}

void CPDFSDK_ActionHandler::DoAction_SetOCGState(CPDFSDK_Document* pDocument,
                                                 const CPDF_Action& action) {}

void CPDFSDK_ActionHandler::RunFieldJavaScript(CPDFSDK_Document* pDocument,
                                               CPDF_FormField* pFormField,
                                               CPDF_AAction::AActionType type,
                                               PDFSDK_FieldAction& data,
                                               const CFX_WideString& script) {
  ASSERT(type != CPDF_AAction::Calculate);
  ASSERT(type != CPDF_AAction::Format);

  ASSERT(pDocument != NULL);

  IJS_Runtime* pRuntime = pDocument->GetJsRuntime();
  ASSERT(pRuntime != NULL);

  pRuntime->SetReaderDocument(pDocument);

  IJS_Context* pContext = pRuntime->NewContext();
  ASSERT(pContext != NULL);

  switch (type) {
    case CPDF_AAction::CursorEnter:
      pContext->OnField_MouseEnter(data.bModifier, data.bShift, pFormField);
      break;
    case CPDF_AAction::CursorExit:
      pContext->OnField_MouseExit(data.bModifier, data.bShift, pFormField);
      break;
    case CPDF_AAction::ButtonDown:
      pContext->OnField_MouseDown(data.bModifier, data.bShift, pFormField);
      break;
    case CPDF_AAction::ButtonUp:
      pContext->OnField_MouseUp(data.bModifier, data.bShift, pFormField);
      break;
    case CPDF_AAction::GetFocus:
      pContext->OnField_Focus(data.bModifier, data.bShift, pFormField,
                              data.sValue);
      break;
    case CPDF_AAction::LoseFocus:
      pContext->OnField_Blur(data.bModifier, data.bShift, pFormField,
                             data.sValue);
      break;
    case CPDF_AAction::KeyStroke:
      pContext->OnField_Keystroke(data.sChange, data.sChangeEx, data.bKeyDown,
                                  data.bModifier, data.nSelEnd, data.nSelStart,
                                  data.bShift, pFormField, data.sValue,
                                  data.bWillCommit, data.bFieldFull, data.bRC);
      break;
    case CPDF_AAction::Validate:
      pContext->OnField_Validate(data.sChange, data.sChangeEx, data.bKeyDown,
                                 data.bModifier, data.bShift, pFormField,
                                 data.sValue, data.bRC);
      break;
    default:
      ASSERT(FALSE);
      break;
  }

  CFX_WideString csInfo;
  FX_BOOL bRet = pContext->RunScript(script, &csInfo);
  if (!bRet) {
    // FIXME: return error.
  }

  pRuntime->ReleaseContext(pContext);
}

void CPDFSDK_ActionHandler::RunDocumentOpenJavaScript(
    CPDFSDK_Document* pDocument,
    const CFX_WideString& sScriptName,
    const CFX_WideString& script) {
  ASSERT(pDocument != NULL);

  IJS_Runtime* pRuntime = pDocument->GetJsRuntime();
  ASSERT(pRuntime != NULL);

  pRuntime->SetReaderDocument(pDocument);

  IJS_Context* pContext = pRuntime->NewContext();
  ASSERT(pContext != NULL);

  pContext->OnDoc_Open(pDocument, sScriptName);

  CFX_WideString csInfo;
  FX_BOOL bRet = pContext->RunScript(script, &csInfo);
  if (!bRet) {
    // FIXME: return error.
  }

  pRuntime->ReleaseContext(pContext);
}

void CPDFSDK_ActionHandler::RunDocumentPageJavaScript(
    CPDFSDK_Document* pDocument,
    CPDF_AAction::AActionType type,
    const CFX_WideString& script) {
  ASSERT(pDocument != NULL);

  IJS_Runtime* pRuntime = pDocument->GetJsRuntime();
  ASSERT(pRuntime != NULL);

  pRuntime->SetReaderDocument(pDocument);

  IJS_Context* pContext = pRuntime->NewContext();
  ASSERT(pContext != NULL);

  switch (type) {
    case CPDF_AAction::OpenPage:
      pContext->OnPage_Open(pDocument);
      break;
    case CPDF_AAction::ClosePage:
      pContext->OnPage_Close(pDocument);
      break;
    case CPDF_AAction::CloseDocument:
      pContext->OnDoc_WillClose(pDocument);
      break;
    case CPDF_AAction::SaveDocument:
      pContext->OnDoc_WillSave(pDocument);
      break;
    case CPDF_AAction::DocumentSaved:
      pContext->OnDoc_DidSave(pDocument);
      break;
    case CPDF_AAction::PrintDocument:
      pContext->OnDoc_WillPrint(pDocument);
      break;
    case CPDF_AAction::DocumentPrinted:
      pContext->OnDoc_DidPrint(pDocument);
      break;
    case CPDF_AAction::PageVisible:
      pContext->OnPage_InView(pDocument);
      break;
    case CPDF_AAction::PageInvisible:
      pContext->OnPage_OutView(pDocument);
      break;
    default:
      ASSERT(FALSE);
      break;
  }

  CFX_WideString csInfo;
  FX_BOOL bRet = pContext->RunScript(script, &csInfo);
  if (!bRet) {
    // FIXME: return error.
  }

  pRuntime->ReleaseContext(pContext);
}

FX_BOOL CPDFSDK_FormActionHandler::DoAction_Hide(const CPDF_Action& action,
                                                 CPDFSDK_Document* pDocument) {
  ASSERT(pDocument != NULL);

  CPDFSDK_InterForm* pInterForm = (CPDFSDK_InterForm*)pDocument->GetInterForm();
  ASSERT(pInterForm != NULL);

  if (pInterForm->DoAction_Hide(action)) {
    pDocument->SetChangeMark();
    return TRUE;
  }

  return FALSE;
}

FX_BOOL CPDFSDK_FormActionHandler::DoAction_SubmitForm(
    const CPDF_Action& action,
    CPDFSDK_Document* pDocument) {
  ASSERT(pDocument != NULL);

  CPDFSDK_InterForm* pInterForm = (CPDFSDK_InterForm*)pDocument->GetInterForm();
  ASSERT(pInterForm != NULL);

  return pInterForm->DoAction_SubmitForm(action);
}

FX_BOOL CPDFSDK_FormActionHandler::DoAction_ResetForm(
    const CPDF_Action& action,
    CPDFSDK_Document* pDocument) {
  ASSERT(pDocument != NULL);

  CPDFSDK_InterForm* pInterForm = (CPDFSDK_InterForm*)pDocument->GetInterForm();
  ASSERT(pInterForm != NULL);

  if (pInterForm->DoAction_ResetForm(action)) {
    return TRUE;
  }

  return FALSE;
}

FX_BOOL CPDFSDK_FormActionHandler::DoAction_ImportData(
    const CPDF_Action& action,
    CPDFSDK_Document* pDocument) {
  ASSERT(pDocument != NULL);

  CPDFSDK_InterForm* pInterForm = (CPDFSDK_InterForm*)pDocument->GetInterForm();
  ASSERT(pInterForm != NULL);

  if (pInterForm->DoAction_ImportData(action)) {
    pDocument->SetChangeMark();
    return TRUE;
  }

  return FALSE;
}
