// 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_SRC_JAVASCRIPT_JS_OBJECT_H_
#define FPDFSDK_SRC_JAVASCRIPT_JS_OBJECT_H_

#include <map>

#include "JS_Runtime.h"
#include "fpdfsdk/include/fsdk_define.h"  // For FX_UINT
#include "fpdfsdk/include/jsapi/fxjs_v8.h"
#include "third_party/base/nonstd_unique_ptr.h"

class CJS_Context;
class CJS_Object;
class CJS_Timer;
class CPDFDoc_Environment;
class CJS_EmbedObj {
 public:
  explicit CJS_EmbedObj(CJS_Object* pJSObject);
  virtual ~CJS_EmbedObj();

  virtual void TimerProc(CJS_Timer* pTimer) {}

  CJS_Object* GetJSObject() const { return m_pJSObject; }

  int MsgBox(CPDFDoc_Environment* pApp,
             const FX_WCHAR* swMsg,
             const FX_WCHAR* swTitle,
             FX_UINT nType,
             FX_UINT nIcon);
  void Alert(CJS_Context* pContext, const FX_WCHAR* swMsg);

 protected:
  CJS_Object* m_pJSObject;
};

class CJS_Object {
 public:
  explicit CJS_Object(v8::Local<v8::Object> pObject);
  virtual ~CJS_Object();

  void MakeWeak();
  void Dispose();

  virtual FX_BOOL IsType(const FX_CHAR* sClassName) { return TRUE; }
  virtual CFX_ByteString GetClassName() { return ""; }

  virtual void InitInstance(IJS_Runtime* pIRuntime) {}
  virtual void ExitInstance() {}

  v8::Local<v8::Object> ToV8Object() { return m_pV8Object.Get(m_pIsolate); }

  // Takes ownership of |pObj|.
  void SetEmbedObject(CJS_EmbedObj* pObj) { m_pEmbedObj.reset(pObj); }
  CJS_EmbedObj* GetEmbedObject() const { return m_pEmbedObj.get(); }

  static int MsgBox(CPDFDoc_Environment* pApp,
                    const FX_WCHAR* swMsg,
                    const FX_WCHAR* swTitle,
                    FX_UINT nType,
                    FX_UINT nIcon);
  static void Alert(CJS_Context* pContext, const FX_WCHAR* swMsg);

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

 protected:
  nonstd::unique_ptr<CJS_EmbedObj> m_pEmbedObj;
  v8::Global<v8::Object> m_pV8Object;
  v8::Isolate* m_pIsolate;
};

class CJS_Timer : public CJS_Runtime::Observer {
 public:
  CJS_Timer(CJS_EmbedObj* pObj,
            CPDFDoc_Environment* pApp,
            CJS_Runtime* pRuntime,
            int nType,
            const CFX_WideString& script,
            FX_DWORD dwElapse,
            FX_DWORD dwTimeOut);
  ~CJS_Timer() override;

  void KillJSTimer();

  int GetType() const { return m_nType; }
  FX_DWORD GetTimeOut() const { return m_dwTimeOut; }
  CJS_Runtime* GetRuntime() const { return m_bValid ? m_pRuntime : nullptr; }
  CFX_WideString GetJScript() const { return m_swJScript; }

  static void TimerProc(int idEvent);

 private:
  using TimerMap = std::map<FX_UINT, CJS_Timer*>;
  static TimerMap* GetGlobalTimerMap();

  // CJS_Runtime::Observer
  void OnDestroyed() override;

  FX_DWORD m_nTimerID;
  CJS_EmbedObj* const m_pEmbedObj;
  bool m_bProcessing;
  bool m_bValid;

  // data
  const int m_nType;  // 0:Interval; 1:TimeOut
  const FX_DWORD m_dwTimeOut;
  const CFX_WideString m_swJScript;
  CJS_Runtime* const m_pRuntime;
  CPDFDoc_Environment* const m_pApp;
};

#endif  // FPDFSDK_SRC_JAVASCRIPT_JS_OBJECT_H_
