// 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

#ifndef _JS_CONTEXT_H_
#define _JS_CONTEXT_H_

#include "../../../core/include/fxcrt/fx_system.h"
#include "../../../core/include/fxcrt/fx_string.h"
#include "IJavaScript.h"

class CJS_EventHandler;
class CJS_Runtime;

class CJS_Context : public IFXJS_Context
{
public:
	CJS_Context(CJS_Runtime* pRuntime);
	virtual ~CJS_Context();

public:
	virtual FX_BOOL				Compile(const CFX_WideString& script, CFX_WideString& info);
	virtual FX_BOOL				RunScript(const CFX_WideString& script, CFX_WideString& info);

public:
	virtual void				OnApp_Init();

	virtual void				OnDoc_Open(CPDFSDK_Document* pDoc, const CFX_WideString& strTargetName);
	virtual void				OnDoc_WillPrint(CPDFSDK_Document* pDoc);
	virtual void				OnDoc_DidPrint(CPDFSDK_Document* pDoc);
	virtual void				OnDoc_WillSave(CPDFSDK_Document* pDoc);
	virtual void				OnDoc_DidSave(CPDFSDK_Document* pDoc);
	virtual void				OnDoc_WillClose(CPDFSDK_Document* pDoc);

	virtual void				OnPage_Open(CPDFSDK_Document* pTarget);
	virtual void				OnPage_Close(CPDFSDK_Document* pTarget);
	virtual void				OnPage_InView(CPDFSDK_Document* pTarget);
	virtual void				OnPage_OutView(CPDFSDK_Document* pTarget);
	
	virtual void				OnField_MouseDown(FX_BOOL bModifier, FX_BOOL bShift, CPDF_FormField *pTarget);
	virtual void				OnField_MouseEnter(FX_BOOL bModifier, FX_BOOL bShift, CPDF_FormField *pTarget);
	virtual void				OnField_MouseExit(FX_BOOL bModifier, FX_BOOL bShift, CPDF_FormField *pTarget);
	virtual void				OnField_MouseUp(FX_BOOL bModifier, FX_BOOL bShift, CPDF_FormField *pTarget);
	virtual void				OnField_Focus(FX_BOOL bModifier, FX_BOOL bShift, CPDF_FormField* pTarget, const CFX_WideString& Value);
	virtual void				OnField_Blur(FX_BOOL bModifier, FX_BOOL bShift, CPDF_FormField* pTarget, const CFX_WideString& Value);

	virtual void				OnField_Calculate(CPDF_FormField* pSource, CPDF_FormField* pTarget, CFX_WideString& Value, FX_BOOL& bRc);
	virtual void				OnField_Format(int nCommitKey, CPDF_FormField* pTarget, CFX_WideString& Value, FX_BOOL bWillCommit);
	virtual void				OnField_Keystroke(int nCommitKey, 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);
	virtual void				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);

	virtual void				OnScreen_Focus(FX_BOOL bModifier, FX_BOOL bShift, CPDFSDK_Annot* pScreen);
	virtual void				OnScreen_Blur(FX_BOOL bModifier, FX_BOOL bShift, CPDFSDK_Annot* pScreen);
	virtual void				OnScreen_Open(FX_BOOL bModifier, FX_BOOL bShift, CPDFSDK_Annot* pScreen);
	virtual void				OnScreen_Close(FX_BOOL bModifier, FX_BOOL bShift, CPDFSDK_Annot* pScreen);
	virtual void				OnScreen_MouseDown(FX_BOOL bModifier, FX_BOOL bShift, CPDFSDK_Annot* pScreen);
	virtual void				OnScreen_MouseUp(FX_BOOL bModifier, FX_BOOL bShift, CPDFSDK_Annot* pScreen);
	virtual void				OnScreen_MouseEnter(FX_BOOL bModifier, FX_BOOL bShift, CPDFSDK_Annot* pScreen);
	virtual void				OnScreen_MouseExit(FX_BOOL bModifier, FX_BOOL bShift, CPDFSDK_Annot* pScreen);
	virtual void				OnScreen_InView(FX_BOOL bModifier, FX_BOOL bShift, CPDFSDK_Annot* pScreen);
	virtual void				OnScreen_OutView(FX_BOOL bModifier, FX_BOOL bShift, CPDFSDK_Annot* pScreen);

	virtual void				OnBookmark_MouseUp(CPDF_Bookmark* pBookMark);
	virtual void				OnLink_MouseUp(CPDFSDK_Document* pTarget);

	virtual void				OnMenu_Exec(CPDFSDK_Document* pTarget, const CFX_WideString& strTargetName);
	virtual void				OnBatchExec(CPDFSDK_Document* pTarget);
	virtual void				OnConsole_Exec();
	virtual void				OnExternal_Exec();

	virtual void				EnableMessageBox(FX_BOOL bEnable) {m_bMsgBoxEnable = bEnable;}
	FX_BOOL						IsMsgBoxEnabled() const {return m_bMsgBoxEnable;}

public:
	CPDFDoc_Environment*		GetReaderApp();
	CJS_Runtime*				GetJSRuntime(){return m_pRuntime;}

	FX_BOOL						DoJob(int nMode, const CFX_WideString& script, CFX_WideString& info);

	CJS_EventHandler*			GetEventHandler(){return m_pEventHandler;};	
	CPDFSDK_Document*			GetReaderDocument();

private:
	CJS_Runtime*				m_pRuntime;	
	CJS_EventHandler*			m_pEventHandler;	

	FX_BOOL						m_bBusy;	
	FX_BOOL						m_bMsgBoxEnable;
};

// static CFX_WideString JSGetStringFromID(CJS_Context* pContext, UINT ID)
// {
// 	ASSERT(pContext != NULL);
// 
// 	return JS_LoadString(pContext->GetReaderApp(), ID);
// }

#endif //_JS_CONTEXT_H_

