// Copyright (c) 2015 Pieter van Ginkel. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

//#define PDF_ENABLE_V8 1

#include "public/fpdfview.h"
#if PDF_ENABLE_V8
#include "v8/include/v8.h"
#include "v8/include/libplatform/libplatform.h"
#endif // PDF_ENABLE_V8

//#define FPDF_EXPORT1 __declspec(dllexport)
//#define FPDF_CALLCONV1 __stdcall

extern "C"
{
	FPDF_EXPORT void FPDF_CALLCONV FPDF_AddRef();
	FPDF_EXPORT void FPDF_CALLCONV FPDF_Release();
}

class RefCounter
{
private:
	CRITICAL_SECTION cs;
	int refCount;
#if PDF_ENABLE_V8
	v8::Platform* platform;
#endif // PDF_ENABLE_V8
	static RefCounter* _instance;
	
public:
	RefCounter()
	{
		::InitializeCriticalSection(&cs);
		refCount = 0;
#if PDF_ENABLE_V8
		platform = NULL;
#endif // PDF_ENABLE_V8
	}

	~RefCounter()
	{
		::DeleteCriticalSection(&cs);
	}

	// Singletonオブジェクトの取得
	static RefCounter* sGetInstance( void )
	{
		if(!_instance) {
        	_instance = new RefCounter;
        }
        return _instance ;
	}

	void Enter()
	{
		::EnterCriticalSection(&cs);
	}

	void Leave()
	{
		::LeaveCriticalSection(&cs);
	}

	void AddRef()
	{
		::EnterCriticalSection(&cs);

		if (refCount == 0)
		{
#if PDF_ENABLE_V8
#if V8_INTL_SUPPORT
#error V8_INTL_SUPPORT cannot be enabled
#endif
			//platform = v8::platform::CreateDefaultPlatform();
			v8::V8::InitializePlatform(platform);
			v8::V8::Initialize();
#endif // PDF_ENABLE_V8

			FPDF_InitLibrary();
		}

		refCount++;

		::LeaveCriticalSection(&cs);
	}

	void Release()
	{
		::EnterCriticalSection(&cs);

		refCount--;

		if (refCount == 0)
		{
			FPDF_DestroyLibrary();
#if PDF_ENABLE_V8
			//v8::V8::ShutdownPlatform();
			delete platform;
#endif // PDF_ENABLE_V8
		}

		::LeaveCriticalSection(&cs);
	}
};


//static RefCounter refCounter;
// Singletonの実装
RefCounter* RefCounter::_instance = 0;


FPDF_EXPORT void FPDF_CALLCONV FPDF_AddRef()
{
	RefCounter *ref = RefCounter::sGetInstance() ;
	ref->AddRef();
	//refCounter.AddRef();
}

FPDF_EXPORT void FPDF_CALLCONV FPDF_Release()
{
	RefCounter *ref = RefCounter::sGetInstance() ;
	ref->Release();
	//refCounter.Release();
}
