// 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_Define.h"
#include "../../include/javascript/JS_Object.h"
#include "../../include/javascript/JS_Value.h"
#include "../../include/javascript/JS_GlobalData.h"
#include "../../include/javascript/global.h"
#include "../../include/javascript/JS_EventHandler.h"
#include "../../include/javascript/JS_Context.h"

/* ---------------------------- global ---------------------------- */

BEGIN_JS_STATIC_CONST(CJS_Global)
END_JS_STATIC_CONST()

BEGIN_JS_STATIC_PROP(CJS_Global)
END_JS_STATIC_PROP()

BEGIN_JS_STATIC_METHOD(CJS_Global)
	JS_STATIC_METHOD_ENTRY(setPersistent, 2)
END_JS_STATIC_METHOD()

IMPLEMENT_SPECIAL_JS_CLASS(CJS_Global, global_alternate, global);

FX_BOOL	CJS_Global::InitInstance(IFXJS_Context* cc)
{
	CJS_Context* pContext = (CJS_Context*)cc;
	ASSERT(pContext != NULL);

	global_alternate* pGlobal = (global_alternate*)GetEmbedObject();
	ASSERT(pGlobal != NULL);
	
	pGlobal->Initial(pContext->GetReaderApp());
	
	return TRUE;
};

global_alternate::global_alternate(CJS_Object* pJSObject)
	: CJS_EmbedObj(pJSObject),
	m_pApp(NULL)
{
}

global_alternate::~global_alternate(void)
{
	ASSERT(m_pApp != NULL);

//	CommitGlobalPersisitentVariables();
	DestroyGlobalPersisitentVariables();

	CJS_RuntimeFactory* pFactory = m_pApp->m_pJSRuntimeFactory;
	ASSERT(pFactory);

	pFactory->ReleaseGlobalData();
}
  
void global_alternate::Initial(CPDFDoc_Environment* pApp)
{
	m_pApp = pApp;

	CJS_RuntimeFactory* pFactory = pApp->m_pJSRuntimeFactory;
	ASSERT(pFactory);
	m_pGlobalData = pFactory->NewGlobalData(pApp);
	UpdateGlobalPersistentVariables();
}

FX_BOOL	global_alternate::QueryProperty(FX_LPCWSTR propname)
{
	return CFX_WideString(propname) != L"setPersistent";
}

FX_BOOL	global_alternate::DelProperty(IFXJS_Context* cc, FX_LPCWSTR propname, JS_ErrorString& sError)
{
	js_global_data* pData = NULL;
	CFX_ByteString sPropName = CFX_ByteString::FromUnicode(propname);

	if (m_mapGlobal.Lookup(sPropName, (FX_LPVOID&)pData))
	{
		pData->bDeleted = TRUE;
		return TRUE;
	}

	return FALSE;
}

FX_BOOL global_alternate::DoProperty(IFXJS_Context* cc, FX_LPCWSTR propname, CJS_PropValue& vp, JS_ErrorString& sError)
{
	if (vp.IsSetting())
	{
		CFX_ByteString sPropName = CFX_ByteString::FromUnicode(propname);
		switch (vp.GetType())
		{
		case VT_number:
			{
				double dData;
				vp >> dData;
				return SetGlobalVariables(sPropName, JS_GLOBALDATA_TYPE_NUMBER, dData, false, "", v8::Handle<v8::Object>(), FALSE);
			}
		case VT_boolean:
			{
				bool bData;
				vp >> bData;
				return SetGlobalVariables(sPropName, JS_GLOBALDATA_TYPE_BOOLEAN, 0, (bool)vp, "", v8::Handle<v8::Object>(), FALSE);
			}
		case VT_string:
			{
				CFX_ByteString sData;
				vp >> sData;
				return SetGlobalVariables(sPropName, JS_GLOBALDATA_TYPE_STRING, 0, false, sData, v8::Handle<v8::Object>(), FALSE);
			}
		case VT_object:
			{
				JSObject pData = (JSObject)vp;
				return SetGlobalVariables(sPropName, JS_GLOBALDATA_TYPE_OBJECT, 0, false, "", pData, FALSE);
// 				else
// 				{
// 					if (vp.IsArrayObject())
// 					{
// 						CJS_Array array;
// 						vp.ConvertToArray(array);
// 						return SetGlobalVariables(sPropName, JS_GLOBALDATA_TYPE_OBJECT, 0, false, "", 
// 							(Dobject*)(Darray*)array, FALSE);
// 					}
// 					else
// 						return FALSE;
// 				}
			}
		case VT_null:
			{
				return SetGlobalVariables(sPropName, JS_GLOBALDATA_TYPE_NULL, 0, false, "", v8::Handle<v8::Object>(), FALSE);
			}
		case VT_undefined:
			{
				DelProperty(cc, propname, sError);
				return TRUE;
			}
		default:
			return FALSE;
		}
	}
	else
	{
		js_global_data* pData = NULL;
		CFX_ByteString sPropName = CFX_ByteString::FromUnicode(propname);

		if (m_mapGlobal.Lookup(sPropName, (FX_LPVOID&)pData))
		{
			if (pData)
			{
				if (!pData->bDeleted)
				{
					switch (pData->nType)
					{
					case JS_GLOBALDATA_TYPE_NUMBER:
						vp << pData->dData;
						break;
					case JS_GLOBALDATA_TYPE_BOOLEAN:
						vp << pData->bData;
						break;
					case JS_GLOBALDATA_TYPE_STRING:
						vp << pData->sData;
						break;
					case JS_GLOBALDATA_TYPE_OBJECT:
						{
							v8::Handle<v8::Object> obj = v8::Local<v8::Object>::New(vp.GetIsolate(),pData->pData);
							vp << obj;
							break;
						}
					case JS_GLOBALDATA_TYPE_NULL:
						vp.SetNull();
						break;
					default:
						return FALSE;
					}
					return TRUE;
				}
				else
				{
					return TRUE;
				}
			}
			else
			{
				vp.SetNull();
				return TRUE;
			}
		}
		else
		{
			vp.SetNull();
			return TRUE;
		}
	}

	return FALSE;
}

FX_BOOL global_alternate::setPersistent(OBJ_METHOD_PARAMS)
{
	if (params.size() != 2)
	{
		//sError = JSGetStringFromID(IDS_STRING_JSPARAMERROR);	
		return FALSE;
	}

	CFX_ByteString sName = params[0];

	js_global_data* pData = NULL;
	if (m_mapGlobal.Lookup(sName, (FX_LPVOID&)pData))
	{
		if (pData && !pData->bDeleted)
		{
			pData->bPersistent = (bool)params[1];
			return TRUE;
		}
	}

	//sError = JSGetStringFromID(IDS_JSPARAM_INCORRECT);	
	return FALSE;
}

void global_alternate::UpdateGlobalPersistentVariables()
{
	ASSERT(m_pGlobalData != NULL);

	for (int i=0,sz=m_pGlobalData->GetSize(); i<sz; i++)
	{
		CJS_GlobalData_Element* pData = m_pGlobalData->GetAt(i);
		ASSERT(pData != NULL);

		switch (pData->data.nType)
		{
		case JS_GLOBALDATA_TYPE_NUMBER:
			this->SetGlobalVariables(pData->data.sKey, JS_GLOBALDATA_TYPE_NUMBER, pData->data.dData, false, "", v8::Handle<v8::Object>(), pData->bPersistent == 1);
			JS_PutObjectNumber(NULL,(JSFXObject)(*m_pJSObject),
				pData->data.sKey.UTF8Decode(), pData->data.dData);
			break;
		case JS_GLOBALDATA_TYPE_BOOLEAN:
			this->SetGlobalVariables(pData->data.sKey, JS_GLOBALDATA_TYPE_BOOLEAN, 0, (bool)(pData->data.bData == 1), "", v8::Handle<v8::Object>(), pData->bPersistent == 1);
			JS_PutObjectBoolean(NULL,(JSFXObject)(*m_pJSObject),
				pData->data.sKey.UTF8Decode(), (bool)(pData->data.bData == 1));
			break;
		case JS_GLOBALDATA_TYPE_STRING:
			this->SetGlobalVariables(pData->data.sKey, JS_GLOBALDATA_TYPE_STRING, 0, false, pData->data.sData, v8::Handle<v8::Object>(), pData->bPersistent == 1);
			JS_PutObjectString(NULL,(JSFXObject)(*m_pJSObject),
				pData->data.sKey.UTF8Decode(), 
				pData->data.sData.UTF8Decode());
			break;
		case JS_GLOBALDATA_TYPE_OBJECT:
			{
				IJS_Runtime* pRuntime = JS_GetRuntime((JSFXObject)(*m_pJSObject));
				v8::Handle<v8::Object> pObj = JS_NewFxDynamicObj(pRuntime, NULL, -1);

				PutObjectProperty(pObj, &pData->data);

				this->SetGlobalVariables(pData->data.sKey, JS_GLOBALDATA_TYPE_OBJECT, 0, false, "", 
					(JSObject)pObj, pData->bPersistent == 1);
				JS_PutObjectObject(NULL,(JSFXObject)(*m_pJSObject),
					pData->data.sKey.UTF8Decode(), (JSObject)pObj);
			}
			break;
		case JS_GLOBALDATA_TYPE_NULL:
			this->SetGlobalVariables(pData->data.sKey, JS_GLOBALDATA_TYPE_NULL, 0, false, "", v8::Handle<v8::Object>(), pData->bPersistent == 1);
			JS_PutObjectNull(NULL,(JSFXObject)(*m_pJSObject),
				pData->data.sKey.UTF8Decode());
			break;
		}
	}
}

void global_alternate::CommitGlobalPersisitentVariables()
{
	ASSERT(m_pGlobalData != NULL);

	FX_POSITION	 pos = m_mapGlobal.GetStartPosition();
	while (pos)
	{
		CFX_ByteString name; 
		js_global_data* pData = NULL;
		m_mapGlobal.GetNextAssoc(pos, name, (FX_LPVOID&)pData);
		
		if (pData)
		{
			if (pData->bDeleted)
			{
				m_pGlobalData->DeleteGlobalVariable(name);
			}
			else
			{
				switch (pData->nType)
				{
				case JS_GLOBALDATA_TYPE_NUMBER:
					m_pGlobalData->SetGlobalVariableNumber(name, pData->dData);
					m_pGlobalData->SetGlobalVariablePersistent(name, pData->bPersistent);
					break;
				case JS_GLOBALDATA_TYPE_BOOLEAN:
					m_pGlobalData->SetGlobalVariableBoolean(name, pData->bData);
					m_pGlobalData->SetGlobalVariablePersistent(name, pData->bPersistent);
					break;
				case JS_GLOBALDATA_TYPE_STRING:
					m_pGlobalData->SetGlobalVariableString(name, pData->sData);
					m_pGlobalData->SetGlobalVariablePersistent(name, pData->bPersistent);
					break;
				case JS_GLOBALDATA_TYPE_OBJECT:
					//if (pData->pData)
					{
						CJS_GlobalVariableArray array;
						v8::Handle<v8::Object> obj = v8::Local<v8::Object>::New(GetJSObject()->GetIsolate(),pData->pData);
						ObjectToArray(obj, array);
						m_pGlobalData->SetGlobalVariableObject(name, array);
						m_pGlobalData->SetGlobalVariablePersistent(name, pData->bPersistent);
					}
					break;
				case JS_GLOBALDATA_TYPE_NULL:
					m_pGlobalData->SetGlobalVariableNull(name);
					m_pGlobalData->SetGlobalVariablePersistent(name, pData->bPersistent);
					break;
				}
			}
		}
	}
}

void global_alternate::ObjectToArray(v8::Handle<v8::Object> pObj, CJS_GlobalVariableArray& array)
{
	v8::Handle<v8::Array> pKeyList = JS_GetObjectElementNames(pObj);
	int	nObjElements = pKeyList->Length();

	v8::Local<v8::Context> context = pObj->CreationContext();
	v8::Isolate* isolate = context->GetIsolate();

	for (int i=0; i<nObjElements; i++)
	{
		
		CFX_WideString ws = JS_ToString(JS_GetArrayElemnet(pKeyList, i));
		CFX_ByteString sKey = ws.UTF8Encode();

		v8::Handle<v8::Value> v = JS_GetObjectElement(isolate, pObj, (FX_LPCWSTR)ws);
		FXJSVALUETYPE vt = GET_VALUE_TYPE(v);
		switch (vt)
		{
		case VT_number:
			{
				CJS_KeyValue* pObjElement = new CJS_KeyValue;
				pObjElement->nType = JS_GLOBALDATA_TYPE_NUMBER;
				pObjElement->sKey = sKey;
				pObjElement->dData = JS_ToNumber(v);
				array.Add(pObjElement);
			}
			break;
		case VT_boolean:
			{
				CJS_KeyValue* pObjElement = new CJS_KeyValue;
				pObjElement->nType = JS_GLOBALDATA_TYPE_BOOLEAN;
				pObjElement->sKey = sKey;
				pObjElement->dData = JS_ToBoolean(v);
				array.Add(pObjElement);
			}
			break;
		case VT_string:
			{
				CFX_ByteString sValue = CJS_Value(isolate, v, VT_string);
				CJS_KeyValue* pObjElement = new CJS_KeyValue;
				pObjElement->nType = JS_GLOBALDATA_TYPE_STRING;
				pObjElement->sKey = sKey;
				pObjElement->sData = sValue;
				array.Add(pObjElement);
			}
			break;
		case VT_object:
			{
				CJS_KeyValue* pObjElement = new CJS_KeyValue;
				pObjElement->nType = JS_GLOBALDATA_TYPE_OBJECT;
				pObjElement->sKey = sKey;
				ObjectToArray(JS_ToObject(v), pObjElement->objData);
				array.Add(pObjElement);
			}
			break;
		case VT_null:
			{
				CJS_KeyValue* pObjElement = new CJS_KeyValue;
				pObjElement->nType = JS_GLOBALDATA_TYPE_NULL;
				pObjElement->sKey = sKey;
				array.Add(pObjElement);
			}
			break;
		default:
			break;
		}
	}
}

void global_alternate::PutObjectProperty(v8::Handle<v8::Object> pObj, CJS_KeyValue* pData)
{
	ASSERT(pData != NULL);

	for (int i=0,sz=pData->objData.Count(); i<sz; i++)
	{
		CJS_KeyValue* pObjData = pData->objData.GetAt(i);
		ASSERT(pObjData != NULL);

		switch (pObjData->nType)
		{
		case JS_GLOBALDATA_TYPE_NUMBER:
			JS_PutObjectNumber(NULL,(JSObject)pObj, pObjData->sKey.UTF8Decode(), pObjData->dData);
			break;
		case JS_GLOBALDATA_TYPE_BOOLEAN:
			JS_PutObjectBoolean(NULL,(JSObject)pObj, pObjData->sKey.UTF8Decode(), (bool)(pObjData->bData == 1));
			break;
		case JS_GLOBALDATA_TYPE_STRING:
			JS_PutObjectString(NULL,(JSObject)pObj, pObjData->sKey.UTF8Decode(), pObjData->sData.UTF8Decode());
			break;
		case JS_GLOBALDATA_TYPE_OBJECT:
			{
				IJS_Runtime* pRuntime = JS_GetRuntime((JSFXObject)(*m_pJSObject));
				v8::Handle<v8::Object> pNewObj = JS_NewFxDynamicObj(pRuntime, NULL, -1);
				PutObjectProperty(pNewObj, pObjData);
				JS_PutObjectObject(NULL, (JSObject)pObj, pObjData->sKey.UTF8Decode(), (JSObject)pNewObj);
			}
			break;
		case JS_GLOBALDATA_TYPE_NULL:
			JS_PutObjectNull(NULL,(JSObject)pObj, pObjData->sKey.UTF8Decode());
			break;
		}
	}
}

void global_alternate::DestroyGlobalPersisitentVariables()
{
	FX_POSITION	 pos = m_mapGlobal.GetStartPosition();
	while (pos)
	{
		CFX_ByteString name; 
		js_global_data* pData = NULL;
		m_mapGlobal.GetNextAssoc(pos, name, (FX_LPVOID&)pData);
		delete pData;
	}

	m_mapGlobal.RemoveAll();
}


FX_BOOL global_alternate::SetGlobalVariables(FX_LPCSTR propname, int nType, 
				double dData, bool bData, const CFX_ByteString& sData, JSObject pData, bool bDefaultPersistent)
{
	if (propname == NULL) return FALSE;

	js_global_data* pTemp = NULL;
	m_mapGlobal.Lookup(propname, (FX_LPVOID&)pTemp);

	if (pTemp)
	{
		if (pTemp->bDeleted || pTemp->nType != nType)
		{
			pTemp->dData = 0;
			pTemp->bData = 0;
			pTemp->sData = "";
			pTemp->nType = nType;
		}

		pTemp->bDeleted = FALSE;

		switch (nType)
		{
		case JS_GLOBALDATA_TYPE_NUMBER:
			{
				pTemp->dData = dData;
			}
			break;
		case JS_GLOBALDATA_TYPE_BOOLEAN:
			{
				pTemp->bData = bData;
			}
			break;
		case JS_GLOBALDATA_TYPE_STRING:
			{
				pTemp->sData = sData;
			}
			break;
		case JS_GLOBALDATA_TYPE_OBJECT:
			{
				pTemp->pData.Reset(JS_GetRuntime(pData), pData);
			}
			break;
		case JS_GLOBALDATA_TYPE_NULL:
			break;
		default:
			return FALSE;
		}	

		return TRUE;
	}

	js_global_data* pNewData = NULL;

	switch (nType)
	{
	case JS_GLOBALDATA_TYPE_NUMBER:
		{
			pNewData = new js_global_data;
			pNewData->nType = JS_GLOBALDATA_TYPE_NUMBER;
			pNewData->dData = dData;
			pNewData->bPersistent = bDefaultPersistent;
		}
		break;
	case JS_GLOBALDATA_TYPE_BOOLEAN:
		{
			pNewData = new js_global_data;
			pNewData->nType = JS_GLOBALDATA_TYPE_BOOLEAN;
			pNewData->bData = bData;
			pNewData->bPersistent = bDefaultPersistent;
		}
		break;
	case JS_GLOBALDATA_TYPE_STRING:
		{
			pNewData = new js_global_data;
			pNewData->nType = JS_GLOBALDATA_TYPE_STRING;
			pNewData->sData = sData;
			pNewData->bPersistent = bDefaultPersistent;
		}
		break;
	case JS_GLOBALDATA_TYPE_OBJECT:
		{
			pNewData = new js_global_data;
			pNewData->nType = JS_GLOBALDATA_TYPE_OBJECT;
			pNewData->pData.Reset(JS_GetRuntime(pData), pData);
			pNewData->bPersistent = bDefaultPersistent;
		}
		break;
	case JS_GLOBALDATA_TYPE_NULL:
		{
			pNewData = new js_global_data;
			pNewData->nType = JS_GLOBALDATA_TYPE_NULL;
			pNewData->bPersistent = bDefaultPersistent;
		}
		break;
	default:
		return FALSE;
	}	

	m_mapGlobal.SetAt(propname, (FX_LPVOID)pNewData);

	return TRUE;
}
