// Copyright 2014 The PDFium Authors
// 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 FXJS_CJS_OBJECT_H_
#define FXJS_CJS_OBJECT_H_

#include "core/fxcrt/span.h"
#include "core/fxcrt/unowned_ptr.h"
#include "fxjs/cfxjs_engine.h"
#include "fxjs/cjs_runtime.h"

struct JSConstSpec {
  enum Type { Number = 0, String = 1 };

  const char* pName;
  Type eType;
  double number;
  const char* pStr;
};

struct JSPropertySpec {
  const char* pName;
  v8::AccessorNameGetterCallback pPropGet;
  v8::AccessorNameSetterCallback pPropPut;
};

struct JSMethodSpec {
  const char* pName;
  v8::FunctionCallback pMethodCall;
};

class CJS_Object : public CFXJS_PerObjectData::Binding {
 public:
  static void DefineConsts(CFXJS_Engine* pEngine,
                           uint32_t nObjDefnID,
                           pdfium::span<const JSConstSpec> consts);
  static void DefineProps(CFXJS_Engine* pEngine,
                          uint32_t nObjDefnID,
                          pdfium::span<const JSPropertySpec> consts);
  static void DefineMethods(CFXJS_Engine* pEngine,
                            uint32_t nObjDefnID,
                            pdfium::span<const JSMethodSpec> consts);

  CJS_Object(v8::Local<v8::Object> pObject, CJS_Runtime* pRuntime);
  ~CJS_Object() override;

  v8::Local<v8::Object> ToV8Object() {
    return m_pV8Object.Get(GetRuntime()->GetIsolate());
  }
  CJS_Runtime* GetRuntime() const { return m_pRuntime.Get(); }

 private:
  v8::Global<v8::Object> m_pV8Object;
  ObservedPtr<CJS_Runtime> m_pRuntime;
};

#endif  // FXJS_CJS_OBJECT_H_
