// 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/javascript/JavaScript.h"
#include "../../include/javascript/IJavaScript.h"
//#include "../../include/javascript/JS_ResMgr.h"
#include "../../include/javascript/JS_Context.h"
#include "../../include/javascript/JS_EventHandler.h"
#include "../../include/javascript/JS_Runtime.h"
#include "../../include/javascript/resource.h"

/* -------------------------- CJS_Context -------------------------- */

CJS_Context::CJS_Context(CJS_Runtime* pRuntime)
    : m_pRuntime(pRuntime), m_bBusy(FALSE), m_bMsgBoxEnable(TRUE) {
  m_pEventHandler = new CJS_EventHandler(this);
}

CJS_Context::~CJS_Context() {
  delete m_pEventHandler;
}

CPDFSDK_Document* CJS_Context::GetReaderDocument() {
  ASSERT(m_pRuntime != NULL);

  return m_pRuntime->GetReaderDocument();
}

CPDFDoc_Environment* CJS_Context::GetReaderApp() {
  ASSERT(m_pRuntime != NULL);

  return m_pRuntime->GetReaderApp();
}

FX_BOOL CJS_Context::DoJob(int nMode,
                           const CFX_WideString& script,
                           CFX_WideString& info) {
  if (m_bBusy) {
    info = JSGetStringFromID(this, IDS_STRING_JSBUSY);
    return FALSE;
  }

  m_bBusy = TRUE;

  ASSERT(m_pRuntime != NULL);
  ASSERT(m_pEventHandler != NULL);
  ASSERT(m_pEventHandler->IsValid());

  if (!m_pRuntime->AddEventToLoop(m_pEventHandler->TargetName(),
                                  m_pEventHandler->EventType())) {
    info = JSGetStringFromID(this, IDS_STRING_JSEVENT);
    return FALSE;
  }

  FXJSErr error = {NULL, NULL, 0};
  int nRet = 0;

  if (script.GetLength() > 0) {
    if (nMode == 0) {
      nRet = JS_Execute(*m_pRuntime, this, script.c_str(), script.GetLength(),
                        &error);
    } else {
      nRet = JS_Parse(*m_pRuntime, this, script.c_str(), script.GetLength(),
                      &error);
    }
  }

  if (nRet < 0) {
    CFX_WideString sLine;
    sLine.Format(L"[ Line: %05d { %s } ] : %s", error.linnum - 1, error.srcline,
                 error.message);

    //			TRACE(L"/* -------------- JS Error --------------
    //*/\n");
    //			TRACE(sLine);
    //			TRACE(L"\n");
    // CFX_ByteString sTemp = CFX_ByteString::FromUnicode(error.message);
    info += sLine;
  } else {
    info = JSGetStringFromID(this, IDS_STRING_RUN);
  }

  m_pRuntime->RemoveEventInLoop(m_pEventHandler->TargetName(),
                                m_pEventHandler->EventType());

  m_pEventHandler->Destroy();
  m_bBusy = FALSE;

  return nRet >= 0;
}

FX_BOOL CJS_Context::RunScript(const CFX_WideString& script,
                               CFX_WideString& info) {
  v8::Isolate::Scope isolate_scope(m_pRuntime->GetIsolate());
  v8::HandleScope handle_scope(m_pRuntime->GetIsolate());
  v8::Local<v8::Context> context = m_pRuntime->NewJSContext();
  v8::Context::Scope context_scope(context);

  return DoJob(0, script, info);
}

FX_BOOL CJS_Context::Compile(const CFX_WideString& script,
                             CFX_WideString& info) {
  v8::Isolate::Scope isolate_scope(m_pRuntime->GetIsolate());
  v8::HandleScope handle_scope(m_pRuntime->GetIsolate());
  v8::Local<v8::Context> context = m_pRuntime->NewJSContext();
  v8::Context::Scope context_scope(context);

  return DoJob(1, script, info);
}

void CJS_Context::OnApp_Init() {
  ASSERT(m_pEventHandler != NULL);
  m_pEventHandler->OnApp_Init();
}

void CJS_Context::OnDoc_Open(CPDFSDK_Document* pDoc,
                             const CFX_WideString& strTargetName) {
  ASSERT(m_pEventHandler != NULL);
  m_pEventHandler->OnDoc_Open(pDoc, strTargetName);
}

void CJS_Context::OnDoc_WillPrint(CPDFSDK_Document* pDoc) {
  ASSERT(m_pEventHandler != NULL);
  m_pEventHandler->OnDoc_WillPrint(pDoc);
}

void CJS_Context::OnDoc_DidPrint(CPDFSDK_Document* pDoc) {
  ASSERT(m_pEventHandler != NULL);
  m_pEventHandler->OnDoc_DidPrint(pDoc);
}

void CJS_Context::OnDoc_WillSave(CPDFSDK_Document* pDoc) {
  ASSERT(m_pEventHandler != NULL);
  m_pEventHandler->OnDoc_WillSave(pDoc);
}

void CJS_Context::OnDoc_DidSave(CPDFSDK_Document* pDoc) {
  ASSERT(m_pEventHandler != NULL);
  m_pEventHandler->OnDoc_DidSave(pDoc);
}

void CJS_Context::OnDoc_WillClose(CPDFSDK_Document* pDoc) {
  ASSERT(m_pEventHandler != NULL);
  m_pEventHandler->OnDoc_WillClose(pDoc);
}

void CJS_Context::OnPage_Open(CPDFSDK_Document* pTarget) {
  ASSERT(m_pEventHandler != NULL);
  m_pEventHandler->OnPage_Open(pTarget);
}

void CJS_Context::OnPage_Close(CPDFSDK_Document* pTarget) {
  ASSERT(m_pEventHandler != NULL);
  m_pEventHandler->OnPage_Close(pTarget);
}

void CJS_Context::OnPage_InView(CPDFSDK_Document* pTarget) {
  ASSERT(m_pEventHandler != NULL);
  m_pEventHandler->OnPage_InView(pTarget);
}

void CJS_Context::OnPage_OutView(CPDFSDK_Document* pTarget) {
  ASSERT(m_pEventHandler != NULL);
  m_pEventHandler->OnPage_OutView(pTarget);
}

void CJS_Context::OnField_MouseDown(FX_BOOL bModifier,
                                    FX_BOOL bShift,
                                    CPDF_FormField* pTarget) {
  ASSERT(m_pEventHandler != NULL);
  m_pEventHandler->OnField_MouseDown(bModifier, bShift, pTarget);
}

void CJS_Context::OnField_MouseEnter(FX_BOOL bModifier,
                                     FX_BOOL bShift,
                                     CPDF_FormField* pTarget) {
  ASSERT(m_pEventHandler != NULL);
  m_pEventHandler->OnField_MouseEnter(bModifier, bShift, pTarget);
}

void CJS_Context::OnField_MouseExit(FX_BOOL bModifier,
                                    FX_BOOL bShift,
                                    CPDF_FormField* pTarget) {
  ASSERT(m_pEventHandler != NULL);
  m_pEventHandler->OnField_MouseExit(bModifier, bShift, pTarget);
}

void CJS_Context::OnField_MouseUp(FX_BOOL bModifier,
                                  FX_BOOL bShift,
                                  CPDF_FormField* pTarget) {
  ASSERT(m_pEventHandler != NULL);
  m_pEventHandler->OnField_MouseUp(bModifier, bShift, pTarget);
}

void CJS_Context::OnField_Focus(FX_BOOL bModifier,
                                FX_BOOL bShift,
                                CPDF_FormField* pTarget,
                                const CFX_WideString& Value) {
  ASSERT(m_pEventHandler != NULL);
  m_pEventHandler->OnField_Focus(bModifier, bShift, pTarget, Value);
}

void CJS_Context::OnField_Blur(FX_BOOL bModifier,
                               FX_BOOL bShift,
                               CPDF_FormField* pTarget,
                               const CFX_WideString& Value) {
  ASSERT(m_pEventHandler != NULL);
  m_pEventHandler->OnField_Blur(bModifier, bShift, pTarget, Value);
}

void CJS_Context::OnField_Calculate(CPDF_FormField* pSource,
                                    CPDF_FormField* pTarget,
                                    CFX_WideString& Value,
                                    FX_BOOL& bRc) {
  ASSERT(m_pEventHandler != NULL);
  m_pEventHandler->OnField_Calculate(pSource, pTarget, Value, bRc);
}

void CJS_Context::OnField_Format(CPDF_FormField* pTarget,
                                 CFX_WideString& Value,
                                 FX_BOOL bWillCommit) {
  m_pEventHandler->OnField_Format(pTarget, Value, bWillCommit);
}

void CJS_Context::OnField_Keystroke(CFX_WideString& strChange,
                                    const CFX_WideString& strChangeEx,
                                    FX_BOOL bKeyDown,
                                    FX_BOOL bModifier,
                                    int& nSelEnd,
                                    int& nSelStart,
                                    FX_BOOL bShift,
                                    CPDF_FormField* pTarget,
                                    CFX_WideString& Value,
                                    FX_BOOL bWillCommit,
                                    FX_BOOL bFieldFull,
                                    FX_BOOL& bRc) {
  m_pEventHandler->OnField_Keystroke(
      strChange, strChangeEx, bKeyDown, bModifier, nSelEnd, nSelStart, bShift,
      pTarget, Value, bWillCommit, bFieldFull, bRc);
}

void CJS_Context::OnField_Validate(CFX_WideString& strChange,
                                   const CFX_WideString& strChangeEx,
                                   FX_BOOL bKeyDown,
                                   FX_BOOL bModifier,
                                   FX_BOOL bShift,
                                   CPDF_FormField* pTarget,
                                   CFX_WideString& Value,
                                   FX_BOOL& bRc) {
  ASSERT(m_pEventHandler != NULL);
  m_pEventHandler->OnField_Validate(strChange, strChangeEx, bKeyDown, bModifier,
                                    bShift, pTarget, Value, bRc);
}

void CJS_Context::OnScreen_Focus(FX_BOOL bModifier,
                                 FX_BOOL bShift,
                                 CPDFSDK_Annot* pScreen) {
  ASSERT(m_pEventHandler != NULL);
  m_pEventHandler->OnScreen_Focus(bModifier, bShift, pScreen);
}

void CJS_Context::OnScreen_Blur(FX_BOOL bModifier,
                                FX_BOOL bShift,
                                CPDFSDK_Annot* pScreen) {
  ASSERT(m_pEventHandler != NULL);
  m_pEventHandler->OnScreen_Blur(bModifier, bShift, pScreen);
}

void CJS_Context::OnScreen_Open(FX_BOOL bModifier,
                                FX_BOOL bShift,
                                CPDFSDK_Annot* pScreen) {
  ASSERT(m_pEventHandler != NULL);
  m_pEventHandler->OnScreen_Open(bModifier, bShift, pScreen);
}

void CJS_Context::OnScreen_Close(FX_BOOL bModifier,
                                 FX_BOOL bShift,
                                 CPDFSDK_Annot* pScreen) {
  ASSERT(m_pEventHandler != NULL);
  m_pEventHandler->OnScreen_Close(bModifier, bShift, pScreen);
}

void CJS_Context::OnScreen_MouseDown(FX_BOOL bModifier,
                                     FX_BOOL bShift,
                                     CPDFSDK_Annot* pScreen) {
  ASSERT(m_pEventHandler != NULL);
  m_pEventHandler->OnScreen_MouseDown(bModifier, bShift, pScreen);
}

void CJS_Context::OnScreen_MouseUp(FX_BOOL bModifier,
                                   FX_BOOL bShift,
                                   CPDFSDK_Annot* pScreen) {
  ASSERT(m_pEventHandler != NULL);
  m_pEventHandler->OnScreen_MouseUp(bModifier, bShift, pScreen);
}

void CJS_Context::OnScreen_MouseEnter(FX_BOOL bModifier,
                                      FX_BOOL bShift,
                                      CPDFSDK_Annot* pScreen) {
  ASSERT(m_pEventHandler != NULL);
  m_pEventHandler->OnScreen_MouseEnter(bModifier, bShift, pScreen);
}

void CJS_Context::OnScreen_MouseExit(FX_BOOL bModifier,
                                     FX_BOOL bShift,
                                     CPDFSDK_Annot* pScreen) {
  ASSERT(m_pEventHandler != NULL);
  m_pEventHandler->OnScreen_MouseExit(bModifier, bShift, pScreen);
}

void CJS_Context::OnScreen_InView(FX_BOOL bModifier,
                                  FX_BOOL bShift,
                                  CPDFSDK_Annot* pScreen) {
  ASSERT(m_pEventHandler != NULL);
  m_pEventHandler->OnScreen_InView(bModifier, bShift, pScreen);
}

void CJS_Context::OnScreen_OutView(FX_BOOL bModifier,
                                   FX_BOOL bShift,
                                   CPDFSDK_Annot* pScreen) {
  ASSERT(m_pEventHandler != NULL);
  m_pEventHandler->OnScreen_OutView(bModifier, bShift, pScreen);
}

void CJS_Context::OnBookmark_MouseUp(CPDF_Bookmark* pBookMark) {
  ASSERT(m_pEventHandler != NULL);
  m_pEventHandler->OnBookmark_MouseUp(pBookMark);
}

void CJS_Context::OnLink_MouseUp(CPDFSDK_Document* pTarget) {
  ASSERT(m_pEventHandler != NULL);
  m_pEventHandler->OnLink_MouseUp(pTarget);
}

void CJS_Context::OnConsole_Exec() {
  ASSERT(m_pEventHandler != NULL);
  m_pEventHandler->OnConsole_Exec();
}

void CJS_Context::OnExternal_Exec() {
  ASSERT(m_pEventHandler != NULL);
  m_pEventHandler->OnExternal_Exec();
}

void CJS_Context::OnBatchExec(CPDFSDK_Document* pTarget) {
  ASSERT(m_pEventHandler != NULL);
  m_pEventHandler->OnBatchExec(pTarget);
}

void CJS_Context::OnMenu_Exec(CPDFSDK_Document* pTarget,
                              const CFX_WideString& strTargetName) {
  ASSERT(m_pEventHandler != NULL);
  m_pEventHandler->OnMenu_Exec(pTarget, strTargetName);
}
