/*
 * Implementation of CLSID_SystemClock.
 *
 * Copyright (C) Hidenori TAKESHIMA <hidenori@a2.ctktv.ne.jp>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include "config.h"

#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "winuser.h"
#include "winerror.h"
#include "strmif.h"
#include "uuids.h"

#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(quartz);

#include "quartz_private.h"
#include "sysclock.h"


/***************************************************************************
 *
 *	new/delete for CLSID_SystemClock
 *
 */

/* can I use offsetof safely? - FIXME? */
static QUARTZ_IFEntry IFEntries[] =
{
  { &IID_IReferenceClock, offsetof(CSystemClock,refclk)-offsetof(CSystemClock,unk) },
};


static void QUARTZ_DestroySystemClock(IUnknown* punk)
{
	CSystemClock_THIS(punk,unk);

	CSystemClock_UninitIReferenceClock( This );
}

HRESULT QUARTZ_CreateSystemClock(IUnknown* punkOuter,void** ppobj)
{
	CSystemClock*	psc;
	HRESULT	hr;

	TRACE("(%p,%p)\n",punkOuter,ppobj);

	psc = (CSystemClock*)QUARTZ_AllocObj( sizeof(CSystemClock) );
	if ( psc == NULL )
		return E_OUTOFMEMORY;

	QUARTZ_IUnkInit( &psc->unk, punkOuter );
	hr = CSystemClock_InitIReferenceClock( psc );
	if ( FAILED(hr) )
	{
		QUARTZ_FreeObj( psc );
		return hr;
	}

	psc->unk.pEntries = IFEntries;
	psc->unk.dwEntries = sizeof(IFEntries)/sizeof(IFEntries[0]);
	psc->unk.pOnFinalRelease = QUARTZ_DestroySystemClock;

	*ppobj = (void*)(&psc->unk);

	return S_OK;
}


/***************************************************************************
 *
 *	CLSID_SystemClock::IReferenceClock
 *
 */

#define	QUARTZ_MSG_ADDTIMER			(WM_APP+0)
#define	QUARTZ_MSG_REMOVETIMER		(WM_APP+1)
#define	QUARTZ_MSG_EXITTHREAD		(WM_APP+2)


/****************************************************************************/

static QUARTZ_TimerEntry* IReferenceClock_AllocTimerEntry(CSystemClock* This)
{
	QUARTZ_TimerEntry*	pEntry;
	DWORD	dw;

	pEntry = &This->m_timerEntries[0];
	for ( dw = 0; dw < WINE_QUARTZ_SYSCLOCK_TIMER_MAX; dw++ )
	{
		if ( pEntry->hEvent == (HANDLE)NULL )
			return pEntry;
		pEntry ++;
	}

	return NULL;
}

static QUARTZ_TimerEntry* IReferenceClock_SearchTimer(CSystemClock* This, DWORD dwAdvCookie)
{
	QUARTZ_TimerEntry*	pEntry;
	DWORD	dw;

	pEntry = &This->m_timerEntries[0];
	for ( dw = 0; dw < WINE_QUARTZ_SYSCLOCK_TIMER_MAX; dw++ )
	{
		if ( pEntry->hEvent != (HANDLE)NULL &&
			 pEntry->dwAdvCookie == dwAdvCookie )
			return pEntry;
		pEntry ++;
	}

	return NULL;
}

static DWORD IReferenceClock_OnTimerUpdated(CSystemClock* This)
{
	QUARTZ_TimerEntry*	pEntry;
	REFERENCE_TIME	rtCur;
	REFERENCE_TIME	rtSignal;
	REFERENCE_TIME	rtCount;
	HRESULT	hr;
	LONG	lCount;
	DWORD	dw;
	DWORD	dwTimeout = INFINITE;
	DWORD	dwTimeoutCur;

	hr = IReferenceClock_GetTime((IReferenceClock*)(&This->refclk),&rtCur);
	if ( hr != NOERROR )
		return INFINITE;

	pEntry = &This->m_timerEntries[0];
	for ( dw = 0; dw < WINE_QUARTZ_SYSCLOCK_TIMER_MAX; dw++ )
	{
		if ( pEntry->hEvent != (HANDLE)NULL )
		{
			rtSignal = pEntry->rtStart + pEntry->rtInterval;
			if ( rtCur >= rtSignal )
			{
				if ( pEntry->fPeriodic )
				{
					rtCount = ((rtCur - pEntry->rtStart) / pEntry->rtInterval);
					lCount = ( rtCount > (REFERENCE_TIME)0x7fffffff ) ?
						(LONG)0x7fffffff : (LONG)rtCount;
					if ( !ReleaseSemaphore( pEntry->hEvent, lCount, NULL ) )
					{
						while ( lCount > 0 )
						{
							if ( !ReleaseSemaphore( pEntry->hEvent, 1, NULL ) )
								break;
						}
					}
					dwTimeout = 0;
				}
				else
				{
					TRACE( "signal an event\n" );
					SetEvent( pEntry->hEvent );
					pEntry->hEvent = (HANDLE)NULL;
				}
			}
			else
			{
				rtCount = rtSignal - rtCur;
				/* [100ns] -> [ms] */
				rtCount = (rtCount+(REFERENCE_TIME)9999)/(REFERENCE_TIME)10000;
				dwTimeoutCur = (rtCount >= 0xfffffffe) ? (DWORD)0xfffffffe : (DWORD)rtCount;
				if ( dwTimeout > dwTimeoutCur )
					dwTimeout = dwTimeoutCur;
			}
		}
		pEntry ++;
	}

	return dwTimeout;
}

static
DWORD WINAPI IReferenceClock_TimerEntry( LPVOID lpvParam )
{
	CSystemClock*	This = (CSystemClock*)lpvParam;
	MSG	msg;
	DWORD	dwRes;
	DWORD	dwTimeout;

	/* initialize the message queue. */
	PeekMessageA( &msg, (HWND)NULL, 0, 0, PM_NOREMOVE );
	/* resume the owner thread. */
	SetEvent( This->m_hEventInit );

	TRACE( "Enter message loop.\n" );

	/* message loop. */
	dwTimeout = INFINITE;
	while ( 1 )
	{
		if ( dwTimeout > 0 )
		{
			dwRes = MsgWaitForMultipleObjects(
				0, NULL, FALSE,
				dwTimeout,
				QS_ALLEVENTS );
		}

		EnterCriticalSection( &This->m_csClock );
		dwTimeout = IReferenceClock_OnTimerUpdated(This);
		LeaveCriticalSection( &This->m_csClock );
		TRACE( "catch an event / timeout %lu\n", dwTimeout );

		while ( PeekMessageA( &msg, (HWND)NULL, 0, 0, PM_REMOVE ) )
		{
			if ( msg.message == WM_QUIT )
				goto quitthread;

			if ( msg.hwnd != (HWND)NULL )
			{
				TranslateMessage( &msg );
				DispatchMessageA( &msg );
			}
			else
			{
				switch ( msg.message )
				{
				case QUARTZ_MSG_ADDTIMER:
				case QUARTZ_MSG_REMOVETIMER:
					dwTimeout = 0;
					break;
				case QUARTZ_MSG_EXITTHREAD:
					PostQuitMessage(0);
					break;
				default:
					FIXME( "invalid message %04u\n", (unsigned)msg.message );
					break;
				}
			}
		}
	}

quitthread:
	TRACE( "quit thread\n" );
	return 0;
}

/****************************************************************************/

static HRESULT WINAPI
IReferenceClock_fnQueryInterface(IReferenceClock* iface,REFIID riid,void** ppobj)
{
	CSystemClock_THIS(iface,refclk);

	TRACE("(%p)->()\n",This);

	return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj);
}

static ULONG WINAPI
IReferenceClock_fnAddRef(IReferenceClock* iface)
{
	CSystemClock_THIS(iface,refclk);

	TRACE("(%p)->()\n",This);

	return IUnknown_AddRef(This->unk.punkControl);
}

static ULONG WINAPI
IReferenceClock_fnRelease(IReferenceClock* iface)
{
	CSystemClock_THIS(iface,refclk);

	TRACE("(%p)->()\n",This);

	return IUnknown_Release(This->unk.punkControl);
}

static HRESULT WINAPI
IReferenceClock_fnGetTime(IReferenceClock* iface,REFERENCE_TIME* prtTime)
{
	CSystemClock_THIS(iface,refclk);
	DWORD	dwTimeCur;

	TRACE( "(%p)->(%p)\n", This, prtTime );

	if ( prtTime == NULL )
		return E_POINTER;

	EnterCriticalSection( &This->m_csClock );

	dwTimeCur = GetTickCount();
	This->m_rtLast += (REFERENCE_TIME)(DWORD)(dwTimeCur - This->m_dwTimeLast) * (REFERENCE_TIME)10000;

	This->m_dwTimeLast = dwTimeCur;

	*prtTime = This->m_rtLast;

	LeaveCriticalSection( &This->m_csClock );

	return NOERROR;
}

static HRESULT WINAPI
IReferenceClock_fnAdviseTime(IReferenceClock* iface,REFERENCE_TIME rtBase,REFERENCE_TIME rtStream,HEVENT hEvent,DWORD_PTR* pdwAdvCookie)
{
	CSystemClock_THIS(iface,refclk);
	QUARTZ_TimerEntry*	pEntry;
	HRESULT	hr;
	REFERENCE_TIME	rtCur;

	TRACE( "(%p)->()\n", This );

	if ( pdwAdvCookie == NULL )
		return E_POINTER;
	if ( hEvent == (HANDLE)NULL )
		return E_INVALIDARG;

	EnterCriticalSection( &This->m_csClock );

	*pdwAdvCookie = (DWORD_PTR)(This->m_dwAdvCookieNext ++);

	hr = IReferenceClock_GetTime(iface,&rtCur);
	if ( hr != NOERROR )
		goto err;
	if ( rtCur >= (rtBase+rtStream) )
	{
		SetEvent(hEvent);
		hr = NOERROR;
		goto err;
	}

	pEntry = IReferenceClock_AllocTimerEntry(This);
	if ( pEntry == NULL )
	{
		hr = E_FAIL;
		goto err;
	}

        pEntry->dwAdvCookie = *pdwAdvCookie;
        pEntry->fPeriodic = FALSE;
        pEntry->hEvent = hEvent;
        pEntry->rtStart = rtBase;
        pEntry->rtInterval = rtStream;

	if ( !PostThreadMessageA(
			This->m_idThreadTimer,
			QUARTZ_MSG_ADDTIMER,
			0, 0 ) )
	{
		pEntry->hEvent = (HANDLE)NULL;
		hr = E_FAIL;
		goto err;
	}

	hr = NOERROR;
err:
	LeaveCriticalSection( &This->m_csClock );

	return hr;
}

static HRESULT WINAPI
IReferenceClock_fnAdvisePeriodic(IReferenceClock* iface,REFERENCE_TIME rtStart,REFERENCE_TIME rtPeriod,HSEMAPHORE hSemaphore,DWORD_PTR* pdwAdvCookie)
{
	CSystemClock_THIS(iface,refclk);
	QUARTZ_TimerEntry*	pEntry;
	HRESULT	hr;

	TRACE( "(%p)->()\n", This );

	if ( pdwAdvCookie == NULL )
		return E_POINTER;
	if ( hSemaphore == (HSEMAPHORE)NULL )
		return E_INVALIDARG;

	EnterCriticalSection( &This->m_csClock );

	*pdwAdvCookie = (DWORD_PTR)(This->m_dwAdvCookieNext ++);

	pEntry = IReferenceClock_AllocTimerEntry(This);
	if ( pEntry == NULL )
	{
		hr = E_FAIL;
		goto err;
	}

        pEntry->dwAdvCookie = *pdwAdvCookie;
        pEntry->fPeriodic = TRUE;
        pEntry->hEvent = (HANDLE)hSemaphore;
        pEntry->rtStart = rtStart;
        pEntry->rtInterval = rtPeriod;

	if ( !PostThreadMessageA(
			This->m_idThreadTimer,
			QUARTZ_MSG_ADDTIMER,
			0, 0 ) )
	{
		pEntry->hEvent = (HANDLE)NULL;
		hr = E_FAIL;
		goto err;
	}

	hr = NOERROR;
err:
	LeaveCriticalSection( &This->m_csClock );

	return hr;
}

static HRESULT WINAPI
IReferenceClock_fnUnadvise(IReferenceClock* iface,DWORD_PTR dwAdvCookie)
{
	CSystemClock_THIS(iface,refclk);
	QUARTZ_TimerEntry*	pEntry;

	TRACE( "(%p)->(%lu)\n", This, (DWORD)dwAdvCookie );

	EnterCriticalSection( &This->m_csClock );

	pEntry = IReferenceClock_SearchTimer(This,(DWORD)dwAdvCookie);
	if ( pEntry != NULL )
	{
		pEntry->hEvent = (HANDLE)NULL;
	}

	LeaveCriticalSection( &This->m_csClock );

	return NOERROR;
}

static ICOM_VTABLE(IReferenceClock) irefclk =
{
	ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
	/* IUnknown fields */
	IReferenceClock_fnQueryInterface,
	IReferenceClock_fnAddRef,
	IReferenceClock_fnRelease,
	/* IReferenceClock fields */
	IReferenceClock_fnGetTime,
	IReferenceClock_fnAdviseTime,
	IReferenceClock_fnAdvisePeriodic,
	IReferenceClock_fnUnadvise,
};


HRESULT CSystemClock_InitIReferenceClock( CSystemClock* psc )
{
	HANDLE	hEvents[2];

	TRACE("(%p)\n",psc);
	ICOM_VTBL(&psc->refclk) = &irefclk;

	InitializeCriticalSection( &psc->m_csClock );
	psc->m_dwTimeLast = GetTickCount();
	psc->m_rtLast = (REFERENCE_TIME)0;
	psc->m_hThreadTimer = (HANDLE)NULL;
	psc->m_hEventInit = (HANDLE)NULL;
	psc->m_idThreadTimer = 0;
	psc->m_dwAdvCookieNext = 1;
	ZeroMemory( psc->m_timerEntries, sizeof(psc->m_timerEntries) );

	psc->m_hEventInit = CreateEventA( NULL, TRUE, FALSE, NULL );
	if ( psc->m_hEventInit == (HANDLE)NULL )
		goto err;

	psc->m_hThreadTimer = CreateThread(
		NULL, 0,
		IReferenceClock_TimerEntry,
		psc, 0, &psc->m_idThreadTimer );

	if ( psc->m_hThreadTimer == (HANDLE)NULL )
	{
		CloseHandle( psc->m_hEventInit );
		psc->m_hEventInit = (HANDLE)NULL;
		goto err;
	}

	hEvents[0] = psc->m_hEventInit;
	hEvents[1] = psc->m_hThreadTimer;
	if ( WaitForMultipleObjects( 2, hEvents, FALSE, INFINITE )
			!= WAIT_OBJECT_0 )
	{
		CloseHandle( psc->m_hEventInit );
		psc->m_hEventInit = (HANDLE)NULL;
		CloseHandle( psc->m_hThreadTimer );
		psc->m_hThreadTimer = (HANDLE)NULL;
		goto err;
	}

	return NOERROR;

err:
	DeleteCriticalSection( &psc->m_csClock );
	return E_FAIL;
}

void CSystemClock_UninitIReferenceClock( CSystemClock* psc )
{
	TRACE("(%p)\n",psc);

	if ( psc->m_hThreadTimer != (HANDLE)NULL )
	{
		if ( PostThreadMessageA(
			psc->m_idThreadTimer,
			QUARTZ_MSG_EXITTHREAD,
			0, 0 ) )
		{
			WaitForSingleObject( psc->m_hThreadTimer, INFINITE );
		}
		CloseHandle( psc->m_hThreadTimer );
		psc->m_hThreadTimer = (HANDLE)NULL;
	}

	DeleteCriticalSection( &psc->m_csClock );
}
