// 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_OBJECT_H_
#define _JS_OBJECT_H_

#include "../fsdk_define.h"  // For FX_UINT
#include "../fsdk_mgr.h"  // For CPDFDoc_Environment
#include "../fx_systemhandler.h"  // For IFX_SystemHandler
#include "../jsapi/fxjs_v8.h"

class CPDFSDK_PageView;
class CJS_Object;
class CJS_Timer;
class CJS_Context;

class CJS_EmbedObj 
{
public:
	CJS_EmbedObj(CJS_Object* pJSObject);
	virtual ~CJS_EmbedObj();

	virtual void				TimerProc(CJS_Timer* pTimer){};

	CJS_Timer*					BeginTimer(CPDFDoc_Environment * pApp, FX_UINT nElapse);
	void						EndTimer(CJS_Timer* pTimer);

	CJS_Object*					GetJSObject(){return m_pJSObject;};
	operator					CJS_Object* (){return m_pJSObject;};

	CPDFSDK_PageView *			JSGetPageView(IFXJS_Context* cc);
	int							MsgBox(CPDFDoc_Environment * pApp, CPDFSDK_PageView* pPageView, FX_LPCWSTR swMsg, FX_LPCWSTR swTitle = NULL, FX_UINT nType = 0, FX_UINT nIcon = 0);
	void						Alert(CJS_Context* pContext, FX_LPCWSTR swMsg);

protected:
	CJS_Object*					m_pJSObject;
};

class CJS_Object 
{
public:
	CJS_Object(JSFXObject pObject);
	virtual ~CJS_Object(void);

	void						MakeWeak();

	virtual FX_BOOL				IsType(FX_LPCSTR sClassName){return TRUE;};
	virtual CFX_ByteString		GetClassName(){return "";};

	virtual FX_BOOL				InitInstance(IFXJS_Context* cc){return TRUE;};
	virtual FX_BOOL				ExitInstance(){return TRUE;};

	operator					JSFXObject () {return v8::Local<v8::Object>::New(m_pIsolate, m_pObject);}
	operator					CJS_EmbedObj* (){return m_pEmbedObj;};

	void						SetEmbedObject(CJS_EmbedObj* pObj){m_pEmbedObj = pObj;};
	CJS_EmbedObj *				GetEmbedObject(){return m_pEmbedObj;};

	static CPDFSDK_PageView *	JSGetPageView(IFXJS_Context* cc);
	static int					MsgBox(CPDFDoc_Environment * pApp, CPDFSDK_PageView* pPageView, FX_LPCWSTR swMsg, FX_LPCWSTR swTitle = NULL, FX_UINT nType = 0,FX_UINT nIcon = 0);
	static void					Alert(CJS_Context* pContext, FX_LPCWSTR swMsg);

	v8::Isolate*					GetIsolate() {return m_pIsolate;}
protected:
	CJS_EmbedObj *				m_pEmbedObj;
	v8::Persistent<v8::Object>			m_pObject;
	v8::Isolate*					m_pIsolate;
};

struct JS_TIMER_MAP
{
	FX_UINT nID;
	CJS_Timer * pTimer;
};

typedef CFX_ArrayTemplate<JS_TIMER_MAP*>	CTimerMapArray;

struct JS_TIMER_MAPARRAY
{
public:
	JS_TIMER_MAPARRAY()
	{
	}

	~JS_TIMER_MAPARRAY()
	{
		Reset();
	}

	void Reset()
	{
		for (int i=0,sz=m_Array.GetSize(); i<sz; i++)
			delete m_Array.GetAt(i);

		m_Array.RemoveAll();
	}

	void SetAt(FX_UINT nIndex,CJS_Timer * pTimer)
	{
		int i = Find(nIndex);

		if (i>=0)
		{
			if (JS_TIMER_MAP * pMap = m_Array.GetAt(i))
				pMap->pTimer = pTimer;
		}
		else
		{
			if (JS_TIMER_MAP * pMap = new JS_TIMER_MAP)
			{
				pMap->nID = nIndex;
				pMap->pTimer = pTimer;
				m_Array.Add(pMap);
			}
		}
	}

	CJS_Timer * GetAt(FX_UINT nIndex)
	{
		int i = Find(nIndex);

		if (i>=0)
		{
			if (JS_TIMER_MAP * pMap = m_Array.GetAt(i))
				return pMap->pTimer;
		}
		return NULL;
	}

	void RemoveAt(FX_UINT nIndex)
	{
		int i = Find(nIndex);

		if (i>=0)
		{
			delete m_Array.GetAt(i);
			m_Array.RemoveAt(i);
		}
		//To prevent potential fake memory leak reported by vc6.
		if(m_Array.GetSize() == 0)
			m_Array.RemoveAll();
	}

	int Find(FX_UINT nIndex)
	{
		for (int i=0,sz=m_Array.GetSize(); i<sz; i++)
		{
			if (JS_TIMER_MAP * pMap = m_Array.GetAt(i))
			{
				if (pMap->nID == nIndex)
					return i;
			}
		}

		return -1;
	}

	CTimerMapArray		m_Array;
};

JS_TIMER_MAPARRAY& GetTimeMap();

class CJS_Runtime;

class CJS_Timer
{
public:
	CJS_Timer(CJS_EmbedObj * pObj, CPDFDoc_Environment* pApp):
		m_nTimerID(0),
		m_pEmbedObj(pObj),
		m_bProcessing(FALSE),
		m_dwStartTime(0),
		m_dwTimeOut(0),
		m_dwElapse(0),
		m_pRuntime(NULL),
		m_nType(0),
		m_pApp(pApp)
	{
	}

	virtual ~CJS_Timer()
	{
		KillJSTimer();
	}

public:
	FX_UINT SetJSTimer(FX_UINT nElapse)
	{
		if (m_nTimerID)KillJSTimer();
		IFX_SystemHandler* pHandler = m_pApp->GetSysHandler();
		m_nTimerID = pHandler->SetTimer(nElapse,TimerProc);
		GetTimeMap().SetAt(m_nTimerID,this);
		m_dwElapse = nElapse;
		return m_nTimerID;
	};

	void KillJSTimer()
	{
		if (m_nTimerID)
		{
			if (m_pApp == NULL) {
				GetTimeMap().RemoveAt(m_nTimerID);
				m_nTimerID = 0;
				return;
			}
			IFX_SystemHandler* pHandler = m_pApp->GetSysHandler();
			pHandler->KillTimer(m_nTimerID);
			GetTimeMap().RemoveAt(m_nTimerID);
			m_nTimerID = 0;
		}
	};

	void SetType(int nType)
	{
		m_nType = nType;
	}

	int GetType() const
	{
		return m_nType;
	}

	void SetStartTime(FX_DWORD dwStartTime)
	{
		m_dwStartTime = dwStartTime;
	}

	FX_DWORD GetStartTime() const
	{
		return m_dwStartTime;
	}

	void SetTimeOut(FX_DWORD dwTimeOut)
	{
		m_dwTimeOut = dwTimeOut;
	}

	FX_DWORD GetTimeOut() const
	{
		return m_dwTimeOut;
	}

	void SetRuntime(CJS_Runtime* pRuntime)
	{
		m_pRuntime = pRuntime;
	}

	CJS_Runtime* GetRuntime() const
	{
		return m_pRuntime;
	}

	void SetJScript(const CFX_WideString& script)
	{
		m_swJScript = script;
	}

	CFX_WideString GetJScript() const
	{
		return m_swJScript;
	}

	static void TimerProc(int idEvent)
	{
		if (CJS_Timer * pTimer = GetTimeMap().GetAt(idEvent))
		{
			if (!pTimer->m_bProcessing)
			{
				pTimer->m_bProcessing = TRUE;
				if (pTimer->m_pEmbedObj) pTimer->m_pEmbedObj->TimerProc(pTimer);
				pTimer->m_bProcessing = FALSE;
			}
			else
			{
			//	TRACE(L"BUSY!\n");
			}
		}
	};

private:
	FX_UINT							m_nTimerID;
	CJS_EmbedObj*					m_pEmbedObj;
	FX_BOOL							m_bProcessing;

	//data
	FX_DWORD						m_dwStartTime;
	FX_DWORD						m_dwTimeOut;
	FX_DWORD						m_dwElapse;
	CJS_Runtime*					m_pRuntime;
	CFX_WideString					m_swJScript;
	int								m_nType; //0:Interval; 1:TimeOut

	CPDFDoc_Environment*			m_pApp;
};
#endif //_JS_OBJECT_H_
