// 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::Handle<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::Handle<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::Handle<v8::Value>();
	m_eType = VT_unknown;
}

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

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

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

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

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

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

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

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

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

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

v8::Handle<v8::Array>CJS_Value::ToV8Array() const
{
	if (IsArrayObject())
		return v8::Handle<v8::Array>::Cast(JS_ToObject(m_pValue));
	return v8::Handle<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::Handle<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));
}

void CJS_Value::operator = (CJS_Array & array)
{
	m_pValue = JS_NewObject2(m_isolate,(v8::Handle<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;
}

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

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_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);
}

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::Handle<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::Handle<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::Handle<v8::Value>  p = JS_GetArrayElemnet(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_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::Handle<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_pDate));
}

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

int CJS_Date::GetYear()
{
	if (IsValidDate())
		return JS_GetYearFromTime(JS_LocalTime(JS_ToNumber(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_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_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_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_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_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::Handle<v8::Value>()
{
	return m_pDate;
}

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

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