// 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, (const wchar_t*)(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;
}
