// 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

#ifndef _JS_VALUE_H_
#define _JS_VALUE_H_

#include "../jsapi/fxjs_v8.h"
#include "../../../core/include/fxcrt/fx_basic.h"

class CJS_Array;
class CJS_Date;
class CJS_Document;
class CJS_Object;

class CJS_Value
{
public:
	CJS_Value(v8::Isolate* isolate);
	CJS_Value(v8::Isolate* isolate, v8::Handle<v8::Value> pValue,FXJSVALUETYPE t);
	CJS_Value(v8::Isolate* isolate, const int &iValue);
	CJS_Value(v8::Isolate* isolate, const double &dValue);
	CJS_Value(v8::Isolate* isolate, const float &fValue);
	CJS_Value(v8::Isolate* isolate, const bool &bValue);
	CJS_Value(v8::Isolate* isolate, JSFXObject);
	CJS_Value(v8::Isolate* isolate, CJS_Object*);
   	CJS_Value(v8::Isolate* isolate, CJS_Document*);
	CJS_Value(v8::Isolate* isolate, FX_LPCSTR pStr);
	CJS_Value(v8::Isolate* isolate, FX_LPCWSTR pWstr);
	CJS_Value(v8::Isolate* isolate, CJS_Array& array);

	~CJS_Value();

	void SetNull();
    void Attach(v8::Handle<v8::Value> pValue,FXJSVALUETYPE t);
	void Attach(CJS_Value *pValue);
	void Detach();


	int ToInt() const;
	bool ToBool() const;
	double ToDouble() const;
	float  ToFloat() const;
	CJS_Object* ToCJSObject() const;
	CFX_WideString ToCFXWideString() const;
	CFX_ByteString ToCFXByteString() const;
	v8::Handle<v8::Object> ToV8Object() const;
	v8::Handle<v8::Array> ToV8Array() const;
	v8::Handle<v8::Value> ToV8Value() const;

	void operator = (int iValue);
	void operator = (bool bValue);
	void operator = (double);
	void operator = (float);
	void operator = (CJS_Object*);
	void operator = (CJS_Document*);
	void operator = (v8::Handle<v8::Object>);
	void operator = (CJS_Array &);
	void operator = (CJS_Date &);
	void operator = (FX_LPCWSTR pWstr);
	void operator = (FX_LPCSTR pStr);
	void operator = (CJS_Value value);

	FX_BOOL IsArrayObject() const;
	FX_BOOL	IsDateObject() const;
	FXJSVALUETYPE GetType() const;

	FX_BOOL ConvertToArray(CJS_Array &) const;
	FX_BOOL ConvertToDate(CJS_Date &) const;

	v8::Isolate* GetIsolate() {return m_isolate;}
protected:
	v8::Handle<v8::Value> m_pValue;
	FXJSVALUETYPE m_eType;
	v8::Isolate* m_isolate;
};

class CJS_Parameters : public CFX_ArrayTemplate<CJS_Value>
{
public:
	void push_back(const CJS_Value& newElement) {
		CFX_ArrayTemplate<CJS_Value>::Add(newElement);
	}
	int size() const {
		return CFX_ArrayTemplate<CJS_Value>::GetSize();
	}
};

class CJS_PropValue: public CJS_Value
{
public:
	CJS_PropValue(const CJS_Value&);
	CJS_PropValue(v8::Isolate* isolate);
	~CJS_PropValue();
public:
	FX_BOOL IsSetting();
	FX_BOOL IsGetting();
	void operator<<(int);
	void operator>>(int&) const;
	void operator<<(bool);
	void operator>>(bool&) const;
	void operator<<(double);
	void operator>>(double&) const;
	void operator<<(CJS_Object* pObj);
	void operator>>(CJS_Object*& ppObj) const;
	void operator<<(CJS_Document* pJsDoc);
	void operator>>(CJS_Document*& ppJsDoc) const;
	void operator<<(CFX_ByteString);
	void operator>>(CFX_ByteString&) const;
	void operator<<(CFX_WideString);
	void operator>>(CFX_WideString&) const;
	void operator<<(FX_LPCWSTR c_string);
	void operator<<(JSFXObject);
	void operator>>(JSFXObject&) const;
	void operator>>(CJS_Array& array) const;
	void operator<<(CJS_Array& array);
	void operator<<(CJS_Date& date);
	void operator>>(CJS_Date& date) const;
	operator v8::Handle<v8::Value>() const;
	void StartSetting();
	void StartGetting();
private:
	FX_BOOL m_bIsSetting;
};

class CJS_Array
{
public:
	CJS_Array(v8::Isolate* isolate);
	virtual ~CJS_Array();

	void Attach(v8::Handle<v8::Array> pArray);
	void GetElement(unsigned index,CJS_Value &value);
	void SetElement(unsigned index,CJS_Value value);
    int GetLength();
	FX_BOOL IsAttached();
	operator v8::Handle<v8::Array>();

	v8::Isolate* GetIsolate() {return m_isolate;}
private:
	v8::Handle<v8::Array> m_pArray;
	v8::Isolate* m_isolate;
};

class CJS_Date
{
friend class CJS_Value;
public:
	CJS_Date(v8::Isolate* isolate);
	CJS_Date(v8::Isolate* isolate,double dMsec_time);
	CJS_Date(v8::Isolate* isolate,int year, int mon, int day,int hour, int min, int sec);
	virtual ~CJS_Date();
	void Attach(v8::Handle<v8::Value> pDate);

	int     GetYear();
	void    SetYear(int iYear);

	int     GetMonth();
	void    SetMonth(int iMonth);

	int     GetDay();
	void    SetDay(int iDay);

	int     GetHours();
	void    SetHours(int iHours);

	int     GetMinutes();
	void    SetMinutes(int minutes);

	int     GetSeconds();
	void    SetSeconds(int seconds);

	operator v8::Handle<v8::Value>();
	operator double() const;

	CFX_WideString	ToString() const;

	static double	MakeDate(int year, int mon, int mday,int hour, int min, int sec,int ms);

	FX_BOOL	IsValidDate();

protected:
	v8::Handle<v8::Value> m_pDate;
	v8::Isolate* m_isolate;
};

#endif //_JS_VALUE_H_

