// 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/JS_Define.h"
#include "../../include/javascript/JS_Object.h"
#include "../../include/javascript/JS_Value.h"
#include "../../include/javascript/Document.h"

/* ---------------------------- CJS_Value ---------------------------- */

CJS_Value::CJS_Value(v8::Isolate* isolate) : m_eType(VT_unknown),m_isolate(isolate)
{
}
CJS_Value::CJS_Value(v8::Isolate* isolate, v8::Local<v8::Value> pValue,FXJSVALUETYPE t) :
	m_pValue(pValue), m_eType(t), m_isolate(isolate)
{
}

CJS_Value::CJS_Value(v8::Isolate* isolate, const int &iValue):m_isolate(isolate)
{
	operator =(iValue);
}

CJS_Value::CJS_Value(v8::Isolate* isolate, const bool &bValue):m_isolate(isolate)
{
	operator =(bValue);
}

CJS_Value::CJS_Value(v8::Isolate* isolate, const float &fValue):m_isolate(isolate)
{
	operator =(fValue);
}

CJS_Value::CJS_Value(v8::Isolate* isolate, const double &dValue):m_isolate(isolate) 
{
	operator =(dValue);
}

CJS_Value::CJS_Value(v8::Isolate* isolate, JSFXObject  pJsObj):m_isolate(isolate) 
{
	operator =(pJsObj);
}

CJS_Value::CJS_Value(v8::Isolate* isolate, CJS_Object* pJsObj):m_isolate(isolate) 
{
	operator =(pJsObj);
}

CJS_Value::CJS_Value(v8::Isolate* isolate, CJS_Document* pJsDoc):m_isolate(isolate) 
{
	m_eType = VT_object;
	if (pJsDoc)
		m_pValue = (JSFXObject)*pJsDoc;
}

CJS_Value::CJS_Value(v8::Isolate* isolate, FX_LPCWSTR pWstr):m_isolate(isolate) 
{
	operator =(pWstr);
}

CJS_Value::CJS_Value(v8::Isolate* isolate, FX_LPCSTR pStr):m_isolate(isolate) 
{
	operator = (pStr);
}

CJS_Value::CJS_Value(v8::Isolate* isolate, CJS_Array& array):m_isolate(isolate) 
{
	operator = (array);
}

CJS_Value::~CJS_Value()
{
}

void CJS_Value::Attach(v8::Local<v8::Value> pValue,FXJSVALUETYPE t)
{
	m_pValue = pValue;
	m_eType = t;
}

void CJS_Value::Attach(CJS_Value *pValue)
{
	if (pValue)
		Attach(pValue->ToV8Value(), pValue->GetType());
}

void CJS_Value::Detach()
{
	m_pValue = v8::Local<v8::Value>();
	m_eType = VT_unknown;
}

/* ---------------------------------------------------------------------------------------- */

int CJS_Value::ToInt() const
{
	return JS_ToInt32(m_isolate, m_pValue);
}

bool CJS_Value::ToBool() const
{
	return JS_ToBoolean(m_isolate, m_pValue);
}

double CJS_Value::ToDouble() const
{
	return JS_ToNumber(m_isolate, m_pValue);
}

float CJS_Value::ToFloat() const
{
	return (float)ToDouble();
}

CJS_Object* CJS_Value::ToCJSObject() const
{
	v8::Local<v8::Object>	pObj = JS_ToObject(m_isolate, m_pValue);
	return (CJS_Object*)JS_GetPrivate(m_isolate, pObj);
}

v8::Local<v8::Object> CJS_Value::ToV8Object() const
{
	return JS_ToObject(m_isolate, m_pValue);
}

CFX_WideString CJS_Value::ToCFXWideString() const
{
	return JS_ToString(m_isolate, m_pValue);
}

CFX_ByteString CJS_Value::ToCFXByteString() const
{
	return CFX_ByteString::FromUnicode(ToCFXWideString());
}

v8::Local<v8::Value> CJS_Value::ToV8Value() const
{
	return m_pValue;
}

v8::Local<v8::Array>CJS_Value::ToV8Array() const
{
	if (IsArrayObject())
		return v8::Local<v8::Array>::Cast(JS_ToObject(m_isolate, m_pValue));
	return v8::Local<v8::Array>();
}

/* ---------------------------------------------------------------------------------------- */

void CJS_Value::operator =(int iValue)
{
	m_pValue = JS_NewNumber(m_isolate, iValue);

	m_eType = VT_number;
}

void CJS_Value::operator =(bool bValue)
{
	m_pValue = JS_NewBoolean(m_isolate, bValue);

	m_eType = VT_boolean;
}

void CJS_Value::operator =(double dValue)
{
	m_pValue = JS_NewNumber(m_isolate,dValue);

	m_eType = VT_number;
}

void CJS_Value::operator = (float fValue)
{
	m_pValue = JS_NewNumber(m_isolate,fValue);
	m_eType = VT_number;
}

void CJS_Value::operator =(v8::Local<v8::Object> pObj)
{

	m_pValue = JS_NewObject(m_isolate,pObj);

	m_eType = VT_fxobject;
}

void CJS_Value::operator =(CJS_Object * pObj)
{
	if (pObj)
		operator = ((JSFXObject)*pObj);
}

void CJS_Value::operator = (CJS_Document* pJsDoc)
{
	m_eType = VT_object;
	if (pJsDoc) {
		m_pValue = static_cast<JSFXObject>(*pJsDoc);
	}
}

void CJS_Value::operator =(FX_LPCWSTR pWstr)
{
	m_pValue = JS_NewString(m_isolate,(wchar_t *)pWstr);

	m_eType = VT_string;
}

void CJS_Value::SetNull()
{
	m_pValue = JS_NewNull();

	m_eType = VT_null;
}

void CJS_Value::operator = (FX_LPCSTR pStr)
{	
	operator = (CFX_WideString::FromLocal(pStr).c_str());
}

void CJS_Value::operator = (CJS_Array & array)
{
	m_pValue = JS_NewObject2(m_isolate,(v8::Local<v8::Array>)array);

	m_eType = VT_object;
}

void CJS_Value::operator = (CJS_Date & date)
{
	m_pValue = JS_NewDate(m_isolate, (double)date);

	m_eType = VT_date;
}

void CJS_Value::operator = (CJS_Value value)
{
	m_pValue = value.ToV8Value();

	m_eType = value.m_eType;
        m_isolate = value.m_isolate;
}

/* ---------------------------------------------------------------------------------------- */

FXJSVALUETYPE CJS_Value::GetType() const
{
	if(m_pValue.IsEmpty()) return VT_unknown;
	if(m_pValue->IsString()) return VT_string;
	if(m_pValue->IsNumber()) return VT_number;
	if(m_pValue->IsBoolean()) return VT_boolean;
	if(m_pValue->IsDate()) return VT_date;
	if(m_pValue->IsObject()) return VT_object;
	if(m_pValue->IsNull()) return VT_null;
	if(m_pValue->IsUndefined()) return VT_undefined;
	return VT_unknown;
}

FX_BOOL CJS_Value::IsArrayObject() const 
{
	if(m_pValue.IsEmpty()) return FALSE;
	return m_pValue->IsArray();
}

FX_BOOL CJS_Value::IsDateObject() const
{
	if(m_pValue.IsEmpty()) return FALSE;
	return m_pValue->IsDate();
}

//CJS_Value::operator CJS_Array()
FX_BOOL CJS_Value::ConvertToArray(CJS_Array &array) const
{
	if (IsArrayObject())
	{
		array.Attach(JS_ToArray(m_isolate, m_pValue));
		return TRUE;
	}

	return FALSE;
}

FX_BOOL CJS_Value::ConvertToDate(CJS_Date &date) const
{
// 	if (GetType() == VT_date)
// 	{
// 		date = (double)(*this);
// 		return TRUE;
// 	}

	if (IsDateObject())
	{
		date.Attach(m_pValue);
		return TRUE;
	}

	return FALSE;	
}

/* ---------------------------- CJS_PropValue ---------------------------- */

CJS_PropValue::CJS_PropValue(const CJS_Value &value) : 
	CJS_Value(value),
	m_bIsSetting(0)
{
}

CJS_PropValue::CJS_PropValue(v8::Isolate* isolate) : CJS_Value(isolate),
                                 m_bIsSetting(0)
{
}

CJS_PropValue::~CJS_PropValue()
{
}

FX_BOOL CJS_PropValue::IsSetting()
{
	return m_bIsSetting;
}

FX_BOOL CJS_PropValue::IsGetting()
{
	return !m_bIsSetting;
}

void CJS_PropValue::operator <<(int iValue)
{
	ASSERT(!m_bIsSetting);
	CJS_Value::operator =(iValue);
}

void CJS_PropValue::operator >>(int & iValue) const
{
	ASSERT(m_bIsSetting);
	iValue = CJS_Value::ToInt();
}


void CJS_PropValue::operator <<(bool bValue)
{
	ASSERT(!m_bIsSetting);
	CJS_Value::operator =(bValue);
}

void CJS_PropValue::operator >>(bool& bValue) const
{
	ASSERT(m_bIsSetting);
	bValue = CJS_Value::ToBool();
}

void CJS_PropValue::operator <<(double dValue)
{
	ASSERT(!m_bIsSetting);
	CJS_Value::operator =(dValue);
}

void CJS_PropValue::operator >>(double& dValue) const
{
	ASSERT(m_bIsSetting);
	dValue = CJS_Value::ToDouble();
}

void CJS_PropValue::operator <<(CJS_Object* pObj)
{
	ASSERT(!m_bIsSetting);
	CJS_Value::operator = (pObj);
}

void CJS_PropValue::operator >>(CJS_Object*& ppObj) const
{
	ASSERT(m_bIsSetting);
	ppObj = CJS_Value::ToCJSObject();
}

void CJS_PropValue::operator <<(CJS_Document* pJsDoc)
{
	ASSERT(!m_bIsSetting);
	CJS_Value::operator = (pJsDoc);
}

void CJS_PropValue::operator >>(CJS_Document*& ppJsDoc) const
{
	ASSERT(m_bIsSetting);
	ppJsDoc = static_cast<CJS_Document*>(CJS_Value::ToCJSObject());
}

void CJS_PropValue::operator<<(JSFXObject pObj)
{
	ASSERT(!m_bIsSetting);
	CJS_Value::operator = (pObj);
}

void CJS_PropValue::operator>>(JSFXObject &ppObj) const
{
	ASSERT(m_bIsSetting);
	ppObj = CJS_Value::ToV8Object();
}


void CJS_PropValue::StartSetting()
{
	m_bIsSetting = 1;
}

void CJS_PropValue::StartGetting()
{
	m_bIsSetting = 0;
}
void CJS_PropValue::operator <<(CFX_ByteString string)
{
	ASSERT(!m_bIsSetting);
	CJS_Value::operator = (string.c_str());
}

void CJS_PropValue::operator >>(CFX_ByteString &string) const
{
	ASSERT(m_bIsSetting);
	string = CJS_Value::ToCFXByteString();
}

void CJS_PropValue::operator <<(FX_LPCWSTR c_string)
{
	ASSERT(!m_bIsSetting);
	CJS_Value::operator =(c_string);
}

void CJS_PropValue::operator >>(CFX_WideString &wide_string) const
{
	ASSERT(m_bIsSetting);
	wide_string = CJS_Value::ToCFXWideString();
}

void CJS_PropValue::operator <<(CFX_WideString wide_string)
{
	ASSERT(!m_bIsSetting);
	CJS_Value::operator = (wide_string.c_str());
}

void CJS_PropValue::operator >>(CJS_Array &array) const
{
	ASSERT(m_bIsSetting);
	ConvertToArray(array);
}

void CJS_PropValue::operator <<(CJS_Array &array)
{
	ASSERT(!m_bIsSetting);
	CJS_Value::operator=(array);
}

void CJS_PropValue::operator>>(CJS_Date &date) const
{
	ASSERT(m_bIsSetting);
	ConvertToDate(date);
}

void CJS_PropValue::operator<<(CJS_Date &date)
{
	ASSERT(!m_bIsSetting);
	CJS_Value::operator=(date);
}

CJS_PropValue::operator v8::Local<v8::Value>() const
{
	return m_pValue;
}

/* ======================================== CJS_Array ========================================= */
CJS_Array::CJS_Array(v8::Isolate* isolate):m_isolate(isolate)
{
}

CJS_Array::~CJS_Array()
{		
}

void CJS_Array::Attach(v8::Local<v8::Array> pArray)
{
	m_pArray = pArray;
}

FX_BOOL CJS_Array::IsAttached()
{
	return FALSE;
}

void CJS_Array::GetElement(unsigned index,CJS_Value &value)
{
	if (m_pArray.IsEmpty())
		return;
	v8::Local<v8::Value>  p = JS_GetArrayElement(m_isolate, m_pArray,index);
	value.Attach(p,VT_object);
}

void CJS_Array::SetElement(unsigned index,CJS_Value value)
{
	if (m_pArray.IsEmpty())
		m_pArray = JS_NewArray(m_isolate);

	JS_PutArrayElement(m_isolate, m_pArray, index, value.ToV8Value(), value.GetType());
}

int CJS_Array::GetLength()
{
	if (m_pArray.IsEmpty())
		return 0;
	return JS_GetArrayLength(m_pArray);
}

CJS_Array:: operator v8::Local<v8::Array>()
{
	if (m_pArray.IsEmpty())
		m_pArray = JS_NewArray(m_isolate);

	return m_pArray;
}

/* ======================================== CJS_Date ========================================= */

CJS_Date::CJS_Date(v8::Isolate* isolate) :m_isolate(isolate)
{
}

CJS_Date::CJS_Date(v8::Isolate* isolate,double dMsec_time) 
{
	m_isolate = isolate;
	m_pDate = JS_NewDate(isolate,dMsec_time);		
}

CJS_Date::CJS_Date(v8::Isolate* isolate,int year, int mon, int day,int hour, int min, int sec) 
{
	m_isolate = isolate;
	m_pDate = JS_NewDate(isolate,MakeDate(year,mon,day,hour,min,sec,0));	
}

double CJS_Date::MakeDate(int year, int mon, int day,int hour, int min, int sec,int ms)
{
	return JS_MakeDate(JS_MakeDay(year,mon,day), JS_MakeTime(hour,min,sec,ms));
}

CJS_Date::~CJS_Date()
{
}

FX_BOOL	CJS_Date::IsValidDate()
{
	if(m_pDate.IsEmpty()) return FALSE;
	return !JS_PortIsNan(JS_ToNumber(m_isolate, m_pDate));
}

void CJS_Date::Attach(v8::Local<v8::Value> pDate)
{
	m_pDate = pDate;
}

int CJS_Date::GetYear()
{
	if (IsValidDate())
		return JS_GetYearFromTime(JS_LocalTime(JS_ToNumber(m_isolate, m_pDate)));

	return 0;
}

void CJS_Date::SetYear(int iYear)
{
	double date = MakeDate(iYear,GetMonth(),GetDay(),GetHours(),GetMinutes(),GetSeconds(),0);
	JS_ValueCopy(m_pDate, JS_NewDate(m_isolate,date));
}

int CJS_Date::GetMonth()
{
	if (IsValidDate())
		return JS_GetMonthFromTime(JS_LocalTime(JS_ToNumber(m_isolate, m_pDate)));

	return 0;
}

void CJS_Date::SetMonth(int iMonth)
{

	double date = MakeDate(GetYear(),iMonth,GetDay(),GetHours(),GetMinutes(),GetSeconds(),0);
	JS_ValueCopy(m_pDate, JS_NewDate(m_isolate,date));

}

int CJS_Date::GetDay()
{
	if (IsValidDate())
		return JS_GetDayFromTime(JS_LocalTime(JS_ToNumber(m_isolate, m_pDate)));

	return 0;
}

void CJS_Date::SetDay(int iDay)
{

	double date = MakeDate(GetYear(),GetMonth(),iDay,GetHours(),GetMinutes(),GetSeconds(),0);
	JS_ValueCopy(m_pDate,JS_NewDate(m_isolate,date));

}

int CJS_Date::GetHours()
{
	if (IsValidDate())
		return JS_GetHourFromTime(JS_LocalTime(JS_ToNumber(m_isolate, m_pDate)));

	return 0;
}

void CJS_Date::SetHours(int iHours)
{
	double date = MakeDate(GetYear(),GetMonth(),GetDay(),iHours,GetMinutes(),GetSeconds(),0);
	JS_ValueCopy(m_pDate,JS_NewDate(m_isolate,date));
}

int CJS_Date::GetMinutes()
{
	if (IsValidDate())
		return JS_GetMinFromTime(JS_LocalTime(JS_ToNumber(m_isolate, m_pDate)));

	return 0;
}

void CJS_Date::SetMinutes(int minutes)
{
	double date = MakeDate(GetYear(),GetMonth(),GetDay(),GetHours(),minutes,GetSeconds(),0);
	JS_ValueCopy(m_pDate,JS_NewDate(m_isolate,date));
}

int CJS_Date::GetSeconds()
{
	if (IsValidDate())
		return JS_GetSecFromTime(JS_LocalTime(JS_ToNumber(m_isolate, m_pDate)));

	return 0;
}

void CJS_Date::SetSeconds(int seconds)
{
	double date = MakeDate(GetYear(),GetMonth(),GetDay(),GetHours(),GetMinutes(),seconds,0);
	JS_ValueCopy(m_pDate,JS_NewDate(m_isolate,date));
}

CJS_Date::operator v8::Local<v8::Value>()
{
	return m_pDate;
}

CJS_Date::operator double() const
{
	if(m_pDate.IsEmpty())
		return 0.0;
	return JS_ToNumber(m_isolate, m_pDate);
}

CFX_WideString CJS_Date::ToString() const
{
	if(m_pDate.IsEmpty())
		return L"";
	return JS_ToString(m_isolate, m_pDate);
}
