// 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 "../../../third_party/base/nonstd_unique_ptr.h"
#include "../../include/javascript/JavaScript.h"
#include "../../include/javascript/IJavaScript.h"
#include "../../include/javascript/JS_Define.h"
#include "../../include/javascript/JS_Object.h"
#include "../../include/javascript/JS_Value.h"
#include "../../include/javascript/app.h"
#include "../../include/javascript/JS_EventHandler.h"
#include "../../include/javascript/resource.h"
#include "../../include/javascript/JS_Context.h"
#include "../../include/javascript/JS_Runtime.h"
#include "../../include/javascript/Document.h"


static v8::Isolate* GetIsolate(IFXJS_Context* cc)
{
	CJS_Context* pContext = (CJS_Context *)cc;
	ASSERT(pContext != NULL);

	CJS_Runtime* pRuntime = pContext->GetJSRuntime();
	ASSERT(pRuntime != NULL);

	return pRuntime->GetIsolate();
}

/* ---------------------------- TimerObj ---------------------------- */

BEGIN_JS_STATIC_CONST(CJS_TimerObj)
END_JS_STATIC_CONST()

BEGIN_JS_STATIC_PROP(CJS_TimerObj)
END_JS_STATIC_PROP()

BEGIN_JS_STATIC_METHOD(CJS_TimerObj)
END_JS_STATIC_METHOD()

IMPLEMENT_JS_CLASS(CJS_TimerObj, TimerObj)

TimerObj::TimerObj(CJS_Object* pJSObject)
: CJS_EmbedObj(pJSObject),
m_pTimer(NULL)
{

}

TimerObj::~TimerObj()
{
}

void TimerObj::SetTimer(CJS_Timer* pTimer)
{
	m_pTimer = pTimer;
}

CJS_Timer* TimerObj::GetTimer() const
{
	return m_pTimer;
}

#define JS_STR_VIEWERTYPE_READER		L"Reader"
#define JS_STR_VIEWERTYPE_STANDARD		L"Exchange"
#define JS_STR_VIEWERVARIATION			L"Full"
#define JS_STR_PLATFORM					L"WIN"
#define JS_STR_LANGUANGE				L"ENU"
#define JS_STR_VIEWERVERSION			8
#define JS_NUM_FORMSVERSION				7

#define JS_FILEPATH_MAXLEN				2000

/* ---------------------------- app ---------------------------- */

BEGIN_JS_STATIC_CONST(CJS_App)
END_JS_STATIC_CONST()

BEGIN_JS_STATIC_PROP(CJS_App)
	JS_STATIC_PROP_ENTRY(activeDocs)
	JS_STATIC_PROP_ENTRY(calculate)
	JS_STATIC_PROP_ENTRY(formsVersion)
	JS_STATIC_PROP_ENTRY(fs)
	JS_STATIC_PROP_ENTRY(fullscreen)
	JS_STATIC_PROP_ENTRY(language)
	JS_STATIC_PROP_ENTRY(media)
	JS_STATIC_PROP_ENTRY(platform)
	JS_STATIC_PROP_ENTRY(runtimeHighlight)
	JS_STATIC_PROP_ENTRY(viewerType)
	JS_STATIC_PROP_ENTRY(viewerVariation)
	JS_STATIC_PROP_ENTRY(viewerVersion)
END_JS_STATIC_PROP()

BEGIN_JS_STATIC_METHOD(CJS_App)
	JS_STATIC_METHOD_ENTRY(alert)
	JS_STATIC_METHOD_ENTRY(beep)
	JS_STATIC_METHOD_ENTRY(browseForDoc)
	JS_STATIC_METHOD_ENTRY(clearInterval)
	JS_STATIC_METHOD_ENTRY(clearTimeOut)
	JS_STATIC_METHOD_ENTRY(execDialog)
	JS_STATIC_METHOD_ENTRY(execMenuItem)
	JS_STATIC_METHOD_ENTRY(findComponent)
	JS_STATIC_METHOD_ENTRY(goBack)
	JS_STATIC_METHOD_ENTRY(goForward)
	JS_STATIC_METHOD_ENTRY(launchURL)
	JS_STATIC_METHOD_ENTRY(mailMsg)
	JS_STATIC_METHOD_ENTRY(newFDF)
	JS_STATIC_METHOD_ENTRY(newDoc)
	JS_STATIC_METHOD_ENTRY(openDoc)
	JS_STATIC_METHOD_ENTRY(openFDF)
	JS_STATIC_METHOD_ENTRY(popUpMenuEx)
	JS_STATIC_METHOD_ENTRY(popUpMenu)
	JS_STATIC_METHOD_ENTRY(response)
	JS_STATIC_METHOD_ENTRY(setInterval)
	JS_STATIC_METHOD_ENTRY(setTimeOut)
END_JS_STATIC_METHOD()

IMPLEMENT_JS_CLASS(CJS_App,app)

app::app(CJS_Object * pJSObject)
   : CJS_EmbedObj(pJSObject),
     m_bCalculate(true),
     m_bRuntimeHighLight(false)
{
}

app::~app(void)
{
	for (int i=0,sz=m_aTimer.GetSize(); i<sz; i++)
		delete m_aTimer[i];

	m_aTimer.RemoveAll();
}

bool app::activeDocs(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError)
{
    if (!vp.IsGetting())
        return false;

    CJS_Context* pContext = (CJS_Context *)cc;
    CPDFDoc_Environment* pApp = pContext->GetReaderApp();
    CJS_Runtime* pRuntime = pContext->GetJSRuntime();
    CPDFSDK_Document* pCurDoc = pContext->GetReaderDocument();
    CJS_Array aDocs(pRuntime->GetIsolate());
    if (CPDFSDK_Document* pDoc = pApp->GetSDKDocument())
    {
        CJS_Document* pJSDocument = NULL;
        if (pDoc == pCurDoc)
        {
            JSFXObject pObj = JS_GetThisObj(*pRuntime);
            if (JS_GetObjDefnID(pObj) == JS_GetObjDefnID(*pRuntime, L"Document"))
                pJSDocument = (CJS_Document*)JS_GetPrivate(pRuntime->GetIsolate(),pObj);
        }
        else
        {
            JSFXObject pObj = JS_NewFxDynamicObj(*pRuntime, pContext, JS_GetObjDefnID(*pRuntime,L"Document"));
            pJSDocument = (CJS_Document*)JS_GetPrivate(pRuntime->GetIsolate(),pObj);
            ASSERT(pJSDocument != NULL);
        }
        aDocs.SetElement(0,CJS_Value(pRuntime->GetIsolate(),pJSDocument));
    }
    if (aDocs.GetLength() > 0)
        vp << aDocs;
    else
        vp.SetNull();

    return true;
}

bool app::calculate(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError)
{
	if (vp.IsSetting())
	{
		bool bVP;
		vp >> bVP;
		m_bCalculate = (bool)bVP;

		CJS_Context* pContext = (CJS_Context*)cc;
		CPDFDoc_Environment* pApp = pContext->GetReaderApp();
		CJS_Runtime* pRuntime = pContext->GetJSRuntime();
		CJS_Array aDocs(pRuntime->GetIsolate());
		if (CPDFSDK_Document* pDoc = pApp->GetSDKDocument())
			pDoc->GetInterForm()->EnableCalculate((bool)m_bCalculate);
	}
	else
	{
		vp << (bool)m_bCalculate;
	}
	return true;
}

bool app::formsVersion(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError)
{
	if (vp.IsGetting())
	{
		vp << JS_NUM_FORMSVERSION;
		return true;
	}

	return false;
}

bool app::viewerType(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError)
{
	if (vp.IsGetting())
	{
		vp << L"unknown";
		return true;
	}

	return false;
}

bool app::viewerVariation(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError)
{
	if (vp.IsGetting())
	{
		vp << JS_STR_VIEWERVARIATION;
		return true;
	}

	return false;
}

bool app::viewerVersion(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError)
{
	if (vp.IsGetting())
	{
		vp << JS_STR_VIEWERVERSION;
		return true;
	}

	return false;
}

bool app::platform(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError)
{
	if (vp.IsGetting())
	{
		vp << JS_STR_PLATFORM;
		return true;
	}

	return false;
}

bool app::language(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError)
{
	if (vp.IsGetting())
	{
		vp << JS_STR_LANGUANGE;
		return true;
	}

	return false;
}

//creates a new fdf object that contains no data
//comment: need reader support
//note:
//CFDF_Document * CPDFDoc_Environment::NewFDF();
bool app::newFDF(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
{
	return true;
}
//opens a specified pdf document and returns its document object
//comment:need reader support
//note: as defined in js reference, the proto of this function's fourth parmeters, how old an fdf document while do not show it.
//CFDF_Document * CPDFDoc_Environment::OpenFDF(string strPath,bool bUserConv);

bool app::openFDF(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
{
	return true;
}

bool app::alert(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
{
	int iSize = params.size();
	if (iSize < 1)
		return false;

	CFX_WideString swMsg = L"";
	CFX_WideString swTitle = L"";
	int iIcon = 0;
	int iType = 0;

	v8::Isolate* isolate = GetIsolate(cc);

	if (iSize == 1)
	{
		if (params[0].GetType() == VT_object)
		{
			JSObject pObj = params[0].ToV8Object();
			{
				v8::Local<v8::Value> pValue = JS_GetObjectElement(isolate, pObj, L"cMsg");
				swMsg = CJS_Value(isolate, pValue, VT_unknown).ToCFXWideString();

				pValue = JS_GetObjectElement(isolate, pObj, L"cTitle");
				swTitle = CJS_Value(isolate, pValue, VT_unknown).ToCFXWideString();

				pValue = JS_GetObjectElement(isolate, pObj, L"nIcon");
				iIcon = CJS_Value(isolate, pValue, VT_unknown).ToInt();

				pValue = JS_GetObjectElement(isolate, pObj, L"nType");
				iType = CJS_Value(isolate, pValue, VT_unknown).ToInt();
			}

			if (swMsg == L"")
			{
				CJS_Array carray(isolate);
				if (params[0].ConvertToArray(carray))
				{
					int iLenth = carray.GetLength();
					CJS_Value* pValue = new CJS_Value(isolate);
//					if (iLenth == 1)
//						pValue = new CJS_Value(isolate);
//					else if (iLenth > 1)
//						pValue = new CJS_Value[iLenth];

					for(int i = 0; i < iLenth; i++)
					{
						carray.GetElement(i, *pValue);
						swMsg += (*pValue).ToCFXWideString();
						if (i < iLenth - 1)
							swMsg += L",  ";
					}

                                        delete pValue;
				}
			}

			if (swTitle == L"")
				swTitle = JSGetStringFromID((CJS_Context*)cc, IDS_STRING_JSALERT);
		}
		else if (params[0].GetType() == VT_boolean)
		{
			bool bGet = params[0].ToBool();
			if (bGet)
				swMsg = L"true";
			else
				swMsg = L"false";

			swTitle = JSGetStringFromID((CJS_Context*)cc, IDS_STRING_JSALERT);
		}
		else
		{
			swMsg = params[0].ToCFXWideString();
			swTitle = JSGetStringFromID((CJS_Context*)cc, IDS_STRING_JSALERT);
		}
	}
	else
	{
		if (params[0].GetType() == VT_boolean)
		{
			bool bGet = params[0].ToBool();
			if (bGet)
				swMsg = L"true";
			else
				swMsg = L"false";
		}
		else
		{
			swMsg = params[0].ToCFXWideString();
		}
		swTitle = JSGetStringFromID((CJS_Context*)cc, IDS_STRING_JSALERT);

		for(int i = 1;i<iSize;i++)
		{
			if (i == 1)
				iIcon = params[i].ToInt();
			if (i == 2)
				iType = params[i].ToInt();
			if (i == 3)
				swTitle = params[i].ToCFXWideString();
		}
	}


	CJS_Context* pContext = (CJS_Context*)cc;
	ASSERT(pContext != NULL);
	CJS_Runtime* pRuntime = pContext->GetJSRuntime();
	ASSERT(pRuntime != NULL);
	pRuntime->BeginBlock();
	vRet = MsgBox(pRuntime->GetReaderApp(), JSGetPageView(cc), swMsg.c_str(), swTitle.c_str(), iType, iIcon);
	pRuntime->EndBlock();

	return true;
}


bool app::beep(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
{
	if (params.size() == 1)
	{
		CJS_Context* pContext = (CJS_Context*)cc;
		CJS_Runtime* pRuntime = pContext->GetJSRuntime();
		CPDFDoc_Environment * pEnv = pRuntime->GetReaderApp();
		pEnv->JS_appBeep(params[0].ToInt());
		return true;
	}

	sError = JSGetStringFromID((CJS_Context*)cc, IDS_STRING_JSPARAMERROR);
	return false;
}

bool app::findComponent(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
{
	return true;
}

bool app::popUpMenuEx(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
{
	return false;
}

bool app::fs(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError)
{
	return false;
}

bool app::setInterval(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
{
	CJS_Context* pContext = (CJS_Context*)cc;
	if (params.size() > 2 || params.size() == 0)
	{
		sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
		return false;
	}

	CFX_WideString script = params.size() > 0 ?  params[0].ToCFXWideString() : L"";
	if (script.IsEmpty())
	{
		sError = JSGetStringFromID(pContext, IDS_STRING_JSAFNUMBER_KEYSTROKE);
		return true;
	}

	CJS_Runtime* pRuntime = pContext->GetJSRuntime();
	FX_DWORD dwInterval = params.size() > 1 ? params[1].ToInt() : 1000;

	CPDFDoc_Environment* pApp = pRuntime->GetReaderApp();
	ASSERT(pApp);
	CJS_Timer* pTimer = new CJS_Timer(this, pApp);
	m_aTimer.Add(pTimer);

	pTimer->SetType(0);
	pTimer->SetRuntime(pRuntime);
	pTimer->SetJScript(script);
	pTimer->SetTimeOut(0);
//	pTimer->SetStartTime(GetTickCount());
	pTimer->SetJSTimer(dwInterval);

	JSFXObject pRetObj = JS_NewFxDynamicObj(*pRuntime, pContext, JS_GetObjDefnID(*pRuntime, L"TimerObj"));

	CJS_TimerObj* pJS_TimerObj = (CJS_TimerObj*)JS_GetPrivate(pRuntime->GetIsolate(),pRetObj);
	ASSERT(pJS_TimerObj != NULL);

	TimerObj* pTimerObj = (TimerObj*)pJS_TimerObj->GetEmbedObject();
	ASSERT(pTimerObj != NULL);

	pTimerObj->SetTimer(pTimer);

	vRet = pRetObj;

	return true;
}

bool app::setTimeOut(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
{
	if (params.size() > 2 || params.size() == 0)
	{
		sError = JSGetStringFromID((CJS_Context*)cc, IDS_STRING_JSPARAMERROR);
		return false;
	}

	CJS_Context* pContext = (CJS_Context*)cc;
	ASSERT(pContext != NULL);
	CJS_Runtime* pRuntime = pContext->GetJSRuntime();
	ASSERT(pRuntime != NULL);

	CFX_WideString script = params.size() > 0 ? params[0].ToCFXWideString() : L"";
	if (script.IsEmpty())
	{
		sError = JSGetStringFromID((CJS_Context*)cc, IDS_STRING_JSAFNUMBER_KEYSTROKE);
		return true;
	}

	FX_DWORD dwTimeOut = params.size() > 1 ? params[1].ToInt() : 1000;

	CPDFDoc_Environment* pApp = pRuntime->GetReaderApp();
	ASSERT(pApp);

	CJS_Timer* pTimer = new CJS_Timer(this, pApp);
	m_aTimer.Add(pTimer);

	pTimer->SetType(1);
	pTimer->SetRuntime(pRuntime);
	pTimer->SetJScript(script);
	pTimer->SetTimeOut(dwTimeOut);
	pTimer->SetJSTimer(dwTimeOut);

	JSFXObject pRetObj = JS_NewFxDynamicObj(*pRuntime, pContext, JS_GetObjDefnID(*pRuntime, L"TimerObj"));

	CJS_TimerObj* pJS_TimerObj = (CJS_TimerObj*)JS_GetPrivate(pRuntime->GetIsolate(),pRetObj);
	ASSERT(pJS_TimerObj != NULL);

	TimerObj* pTimerObj = (TimerObj*)pJS_TimerObj->GetEmbedObject();
	ASSERT(pTimerObj != NULL);

	pTimerObj->SetTimer(pTimer);

	vRet = pRetObj;

	return true;
}

bool app::clearTimeOut(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
{
	CJS_Context* pContext = (CJS_Context*)cc;
	ASSERT(pContext != NULL);
	CJS_Runtime* pRuntime = pContext->GetJSRuntime();
	ASSERT(pRuntime != NULL);

	if (params.size() != 1)
	{
		sError = JSGetStringFromID((CJS_Context*)cc, IDS_STRING_JSPARAMERROR);
		return false;
	}

	if (params[0].GetType() == VT_fxobject)
	{
		JSFXObject pObj = params[0].ToV8Object();
		{
			if (JS_GetObjDefnID(pObj) == JS_GetObjDefnID(*pRuntime, L"TimerObj"))
			{
				if (CJS_Object* pJSObj = params[0].ToCJSObject())
				{
					if (TimerObj* pTimerObj = (TimerObj*)pJSObj->GetEmbedObject())
					{
						if (CJS_Timer* pTimer = pTimerObj->GetTimer())
						{
							pTimer->KillJSTimer();

							for (int i=0,sz=m_aTimer.GetSize(); i<sz; i++)
							{
								if (m_aTimer[i] == pTimer)
								{
									m_aTimer.RemoveAt(i);
									break;
								}
							}

							delete pTimer;
							pTimerObj->SetTimer(NULL);
						}
					}
				}
			}
		}
	}

	return true;
}

bool app::clearInterval(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
{
	CJS_Context* pContext = (CJS_Context*)cc;
	ASSERT(pContext != NULL);
	CJS_Runtime* pRuntime = pContext->GetJSRuntime();
	ASSERT(pRuntime != NULL);

	if (params.size() != 1)
	{
		sError = JSGetStringFromID((CJS_Context*)cc, IDS_STRING_JSPARAMERROR);
		return false;
	}

	if (params[0].GetType() == VT_fxobject)
	{
		JSFXObject pObj = params[0].ToV8Object();
		{
			if (JS_GetObjDefnID(pObj) == JS_GetObjDefnID(*pRuntime, L"TimerObj"))
			{
				if (CJS_Object* pJSObj = params[0].ToCJSObject())
				{
					if (TimerObj* pTimerObj = (TimerObj*)pJSObj->GetEmbedObject())
					{
						if (CJS_Timer* pTimer = pTimerObj->GetTimer())
						{
							pTimer->KillJSTimer();

							for (int i=0,sz=m_aTimer.GetSize(); i<sz; i++)
							{
								if (m_aTimer[i] == pTimer)
								{
									m_aTimer.RemoveAt(i);
									break;
								}
							}

							delete pTimer;
							pTimerObj->SetTimer(NULL);
						}
					}
				}
			}
		}
	}

	return true;
}

bool app::execMenuItem(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
{
	return false;
}

void app::TimerProc(CJS_Timer* pTimer)
{
	ASSERT(pTimer != NULL);

	switch (pTimer->GetType())
	{
	case 0: //interval
		RunJsScript(pTimer->GetRuntime(), pTimer->GetJScript());
		break;
	case 1:
		if (pTimer->GetTimeOut() > 0)
		{
			RunJsScript(pTimer->GetRuntime(), pTimer->GetJScript());
			pTimer->KillJSTimer();
		}
		break;
	}

}

void app::RunJsScript(CJS_Runtime* pRuntime,const CFX_WideString& wsScript)
{
	ASSERT(pRuntime != NULL);

	if (!pRuntime->IsBlocking())
	{
		IFXJS_Context* pContext = pRuntime->NewContext();
		ASSERT(pContext != NULL);
		pContext->OnExternal_Exec();
		CFX_WideString wtInfo;
		pContext->RunScript(wsScript,wtInfo);
		pRuntime->ReleaseContext(pContext);
	}
}

bool app::goBack(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
{
  // Not supported.
  return true;
}

bool app::goForward(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
{
  // Not supported.
  return true;
}

bool app::mailMsg(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
{
	CJS_Context* pContext = (CJS_Context*)cc;
	v8::Isolate* isolate = GetIsolate(cc);

	bool bUI = true;
	CFX_WideString cTo = L"";
	CFX_WideString cCc = L"";
	CFX_WideString cBcc = L"";
	CFX_WideString cSubject = L"";
	CFX_WideString cMsg = L"";

	if (params.size() < 1)
		return false;

	if (params[0].GetType() == VT_object)
	{
		JSObject pObj = params[0].ToV8Object();

		v8::Local<v8::Value> pValue = JS_GetObjectElement(isolate, pObj, L"bUI");
		bUI = CJS_Value(isolate, pValue, GET_VALUE_TYPE(pValue)).ToBool();

		pValue = JS_GetObjectElement(isolate, pObj, L"cTo");
		cTo = CJS_Value(isolate, pValue, GET_VALUE_TYPE(pValue)).ToCFXWideString();

		pValue = JS_GetObjectElement(isolate, pObj, L"cCc");
		cCc = CJS_Value(isolate, pValue, GET_VALUE_TYPE(pValue)).ToCFXWideString();

		pValue = JS_GetObjectElement(isolate, pObj, L"cBcc");
		cBcc = CJS_Value(isolate, pValue, GET_VALUE_TYPE(pValue)).ToCFXWideString();

		pValue = JS_GetObjectElement(isolate, pObj, L"cSubject");
		cSubject = CJS_Value(isolate, pValue, GET_VALUE_TYPE(pValue)).ToCFXWideString();

		pValue = JS_GetObjectElement(isolate, pObj, L"cMsg");
		cMsg = CJS_Value(isolate, pValue, GET_VALUE_TYPE(pValue)).ToCFXWideString();
	} else {
		if (params.size() < 2)
			return false;

		bUI = params[0].ToBool();
		cTo = params[1].ToCFXWideString();

		if (params.size() >= 3)
			cCc = params[2].ToCFXWideString();
		if (params.size() >= 4)
			cBcc = params[3].ToCFXWideString();
		if (params.size() >= 5)
			cSubject = params[4].ToCFXWideString();
		if (params.size() >= 6)
			cMsg = params[5].ToCFXWideString();
	}

	CJS_Runtime* pRuntime = pContext->GetJSRuntime();
	ASSERT(pRuntime != NULL);

	CPDFDoc_Environment* pApp = pContext->GetReaderApp();
	ASSERT(pApp != NULL);

	pRuntime->BeginBlock();
	pApp->JS_docmailForm(NULL, 0, bUI, cTo.c_str(), cSubject.c_str(), cCc.c_str(), cBcc.c_str(), cMsg.c_str());
	pRuntime->EndBlock();

	return false;
}

bool app::launchURL(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
{
  // Unsafe, not supported.
  return true;
}

bool app::runtimeHighlight(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError)
{
	if (vp.IsSetting())
	{
		vp>>m_bRuntimeHighLight;
	}
	else
	{
		vp<<m_bRuntimeHighLight;
	}

	return true;
}

bool app::fullscreen(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError)
{
	return false;
}

bool app::popUpMenu(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
{
	return false;
}


bool app::browseForDoc(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
{
  // Unsafe, not supported.
  return true;
}

CFX_WideString app::SysPathToPDFPath(const CFX_WideString& sOldPath)
{
	CFX_WideString sRet = L"/";

	for (int i=0,sz=sOldPath.GetLength(); i<sz; i++)
	{
		wchar_t c = sOldPath.GetAt(i);
		if (c == L':')
		{
		}
		else
		{
			if (c == L'\\')
			{
				sRet += L"/";
			}
			else
			{
				sRet += c;
			}
		}
	}

	return sRet;
}

bool app::newDoc(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
{
	return false;
}

bool app::openDoc(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
{
	return false;
}

bool app::response(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
{
	CFX_WideString swQuestion = L"";
	CFX_WideString swLabel = L"";
	CFX_WideString swTitle = L"PDF";
	CFX_WideString swDefault = L"";
	bool bPassWord = false;

	v8::Isolate* isolate = GetIsolate(cc);

	int iLength = params.size();
	if (iLength > 0 && params[0].GetType() == VT_object)
	{
		JSObject pObj = params[0].ToV8Object();
		v8::Local<v8::Value> pValue = JS_GetObjectElement(isolate,pObj,L"cQuestion");
		swQuestion = CJS_Value(isolate,pValue,GET_VALUE_TYPE(pValue)).ToCFXWideString();

		pValue = JS_GetObjectElement(isolate,pObj,L"cTitle");
		swTitle = CJS_Value(isolate,pValue,GET_VALUE_TYPE(pValue)).ToCFXWideString();

		pValue = JS_GetObjectElement(isolate,pObj,L"cDefault");
		swDefault = CJS_Value(isolate,pValue,GET_VALUE_TYPE(pValue)).ToCFXWideString();

		pValue = JS_GetObjectElement(isolate,pObj,L"cLabel");
		swLabel = CJS_Value(isolate,pValue,GET_VALUE_TYPE(pValue)).ToCFXWideString();

		pValue = JS_GetObjectElement(isolate,pObj,L"bPassword");
		bPassWord = CJS_Value(isolate,pValue,GET_VALUE_TYPE(pValue)).ToBool();
	}
	else
	{
		switch(iLength)
		{
		case 5:
			swLabel = params[4].ToCFXWideString();
			// FALLTHROUGH
		case 4:
			bPassWord = params[3].ToBool();
			// FALLTHROUGH
		case 3:
			swDefault = params[2].ToCFXWideString();
			// FALLTHROUGH
		case 2:
			swTitle = params[1].ToCFXWideString();
			// FALLTHROUGH
		case 1:
			swQuestion = params[0].ToCFXWideString();
			// FALLTHROUGH
		default:
			break;
		}
	}

	CJS_Context* pContext = (CJS_Context *)cc;
	ASSERT(pContext != NULL);

	CPDFDoc_Environment* pApp = pContext->GetReaderApp();
	ASSERT(pApp != NULL);

    const int MAX_INPUT_BYTES = 2048;
    nonstd::unique_ptr<char[]> pBuff(new char[MAX_INPUT_BYTES + 2]);
    memset(pBuff.get(), 0, MAX_INPUT_BYTES + 2);
    int nLengthBytes = pApp->JS_appResponse(swQuestion.c_str(),
                                            swTitle.c_str(),
                                            swDefault.c_str(),
                                            swLabel.c_str(),
                                            bPassWord,
                                            pBuff.get(),
                                            MAX_INPUT_BYTES);
    if (nLengthBytes <= 0) {
        vRet.SetNull();
        return false;
    }
    nLengthBytes = std::min(nLengthBytes, MAX_INPUT_BYTES);

    CFX_WideString ret_string =
        CFX_WideString::FromUTF16LE((unsigned short*)pBuff.get(),
                                    nLengthBytes / sizeof(unsigned short));
    vRet = ret_string.c_str();
    return true;
}

bool app::media(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError)
{
	return false;
}

bool app::execDialog(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
{
	return true;
}
