// 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 FPDFSDK_INCLUDE_JAVASCRIPT_JS_VALUE_H_
#define FPDFSDK_INCLUDE_JAVASCRIPT_JS_VALUE_H_

#include "../../../core/include/fxcrt/fx_basic.h"
#include "../jsapi/fxjs_v8.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::Local<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, v8::Local<v8::Object>);
  CJS_Value(v8::Isolate* isolate, CJS_Object*);
  CJS_Value(v8::Isolate* isolate, CJS_Document*);
  CJS_Value(v8::Isolate* isolate, const FX_CHAR* pStr);
  CJS_Value(v8::Isolate* isolate, const FX_WCHAR* pWstr);
  CJS_Value(v8::Isolate* isolate, CJS_Array& array);

  ~CJS_Value();

  void SetNull();
  void Attach(v8::Local<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::Local<v8::Object> ToV8Object() const;
  v8::Local<v8::Array> ToV8Array() const;
  v8::Local<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::Local<v8::Object>);
  void operator=(CJS_Array&);
  void operator=(CJS_Date&);
  void operator=(const FX_WCHAR* pWstr);
  void operator=(const FX_CHAR* 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::Local<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<<(const FX_WCHAR* c_string);
  void operator<<(v8::Local<v8::Object>);
  void operator>>(v8::Local<v8::Object>&) 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::Local<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::Local<v8::Array> pArray);
  void GetElement(unsigned index, CJS_Value& value);
  void SetElement(unsigned index, CJS_Value value);
  int GetLength();
  FX_BOOL IsAttached();
  operator v8::Local<v8::Array>();

  v8::Isolate* GetIsolate() { return m_isolate; }

 private:
  v8::Local<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::Local<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::Local<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::Local<v8::Value> m_pDate;
  v8::Isolate* m_isolate;
};

#endif  // FPDFSDK_INCLUDE_JAVASCRIPT_JS_VALUE_H_
