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

/* -------------------------- CBA_ActionHandler -------------------------- */

CPDFSDK_ActionHandler::CPDFSDK_ActionHandler(CPDFDoc_Environment* pEvi)
    : m_pFormActionHandler(new CPDFSDK_FormActionHandler),
      m_pMediaActionHandler(NULL) {
}

void CPDFSDK_ActionHandler::SetMediaActionHandler(CPDFSDK_MediaActionHandler* pHandler)
{
	ASSERT(pHandler != NULL);
	ASSERT(m_pMediaActionHandler == NULL);
	m_pMediaActionHandler = pHandler;
}

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

//document open
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())
			{
				IFXJS_Runtime* pRuntime = pDocument->GetJsRuntime(); //????
				ASSERT(pRuntime != NULL);

				pRuntime->SetReaderDocument(pDocument);

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

				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())
			{
				IFXJS_Runtime* pRuntime = pDocument->GetJsRuntime();
				ASSERT(pRuntime != NULL);

				pRuntime->SetReaderDocument(pDocument);

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

	// 			switch (type)
	// 			{
	// 			case CPDF_AAction::CursorEnter:
	// 				pContext->OnScreen_MouseEnter(IsCTRLpressed(), IsSHIFTpressed(), pScreen);
	// 				break;
	// 			case CPDF_AAction::CursorExit:
	// 				pContext->OnScreen_MouseExit(IsCTRLpressed(), IsSHIFTpressed(), pScreen);
	// 				break;
	// 			case CPDF_AAction::ButtonDown:
	// 				pContext->OnScreen_MouseDown(IsCTRLpressed(), IsSHIFTpressed(), pScreen);
	// 				break;
	// 			case CPDF_AAction::ButtonUp:
	// 				pContext->OnScreen_MouseUp(IsCTRLpressed(), IsSHIFTpressed(), pScreen);
	// 				break;
	// 			case CPDF_AAction::GetFocus:
	// 				pContext->OnScreen_Focus(IsCTRLpressed(), IsSHIFTpressed(), pScreen);
	// 				break;
	// 			case CPDF_AAction::LoseFocus:
	// 				pContext->OnScreen_Blur(IsCTRLpressed(), IsSHIFTpressed(), pScreen);
	// 				break;
	// 			case CPDF_AAction::PageOpen:
	// 				pContext->OnScreen_Open(IsCTRLpressed(), IsSHIFTpressed(), pScreen);
	// 				break;
	// 			case CPDF_AAction::PageClose:
	// 				pContext->OnScreen_Close(IsCTRLpressed(), IsSHIFTpressed(), pScreen);
	// 				break;
	// 			case CPDF_AAction::PageVisible:
	// 				pContext->OnScreen_InView(IsCTRLpressed(), IsSHIFTpressed(), pScreen);
	// 				break;
	// 			case CPDF_AAction::PageInvisible:
	// 				pContext->OnScreen_OutView(IsCTRLpressed(), IsSHIFTpressed(), pScreen);
	// 				break;
	// 			default:
	// 				ASSERT(FALSE);
	// 				break;
	// 			}

				CFX_WideString csInfo;
				FX_BOOL bRet = pContext->RunScript(swJS, csInfo);
				if (!bRet)
				{
					//CBCL_FormNotify::MsgBoxJSError(pPageView->GetPageViewWnd(), csInfo);
				}

				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())
			{
				IFXJS_Runtime* pRuntime = pDocument->GetJsRuntime();
				ASSERT(pRuntime != NULL);

				pRuntime->SetReaderDocument(pDocument);

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

				pContext->OnBookmark_MouseUp(pBookmark);

				CFX_WideString csInfo;
				FX_BOOL bRet = pContext->RunScript(swJS, csInfo);
				if (!bRet)
				{
					//CBCL_FormNotify::MsgBoxJSError(pPageView->GetPageViewWnd(), csInfo);
				}

				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:
		if (m_pMediaActionHandler)
		{
			m_pMediaActionHandler->DoAction_Sound(action, pDocument);
		}
		break;
	case CPDF_Action::Movie:
		if (m_pMediaActionHandler)
		{
			m_pMediaActionHandler->DoAction_Movie(action, pDocument);
		}
		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:
		if (m_pMediaActionHandler)
		{
			m_pMediaActionHandler->DoAction_Rendition(action, pDocument);
		}
		break;
	case CPDF_Action::Trans:
		break;
	case CPDF_Action::GoTo3DView:
		break;
	default:
		break;
	}
}

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

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

	CPDF_Document* pPDFDocument = pDocument->GetDocument()->GetPDFDoc();
	ASSERT(pPDFDocument != NULL);
	CPDFDoc_Environment* pApp = pDocument->GetEnv();
	ASSERT(pApp != NULL);

	CPDF_Dest MyDest = action.GetDest(pPDFDocument);
	int nPageIndex = MyDest.GetPageIndex(pPDFDocument);
	int nFitType = MyDest.GetZoomMode();
	const CPDF_Array * pMyArray = (CPDF_Array*)MyDest.GetObject();
	float* pPosAry = NULL;
	int sizeOfAry = 0;
	if (pMyArray != NULL)
	{
		pPosAry = new float[pMyArray->GetCount()];
		int j = 0;
		for (int i = 2; i < (int)pMyArray->GetCount(); i++)
		{
			pPosAry[j++] = pMyArray->GetFloat(i);
		}
		sizeOfAry = j;
	}
	pApp->FFI_DoGoToAction(nPageIndex, nFitType, pPosAry, sizeOfAry);
	if(pPosAry)
		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);

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

	pRuntime->SetReaderDocument(pDocument);

	IFXJS_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)
	{
		//CBCL_FormNotify::MsgBoxJSError(pPageView->GetPageViewWnd(), csInfo);
	}

	pRuntime->ReleaseContext(pContext);
}

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

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

	pRuntime->SetReaderDocument(pDocument);

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

	pContext->OnDoc_Open(pDocument, sScriptName);

	CFX_WideString csInfo;
	FX_BOOL bRet = pContext->RunScript(script, csInfo);
	if (!bRet)
	{
		//CBCL_FormNotify::MsgBoxJSError(pPageView->GetPageViewWnd(), csInfo);
	}

	pRuntime->ReleaseContext(pContext);
}

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

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

	pRuntime->SetReaderDocument(pDocument);

	IFXJS_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)
	{
		//CBCL_FormNotify::MsgBoxJSError(pPageView->GetPageViewWnd(), csInfo);
	}

	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;
}

FX_BOOL	CPDFSDK_MediaActionHandler::DoAction_Rendition(const CPDF_Action& action, CPDFSDK_Document* pDocument)
{
	return FALSE;
}

FX_BOOL	CPDFSDK_MediaActionHandler::DoAction_Sound(const CPDF_Action& action, CPDFSDK_Document* pDocument)
{
	return FALSE;
}

FX_BOOL	CPDFSDK_MediaActionHandler::DoAction_Movie(const CPDF_Action& action, CPDFSDK_Document* pDocument)
{
	return FALSE;
}
