/*
 * Implementation of IReferenceClock
 *
 * Copyright 2004 Raphael Junqueira
 *
 * 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
 */

#define COM_NO_WINDOWS_H
#include "quartz_private.h"

#include "wine/debug.h"
#include "wine/unicode.h"
#include "uuids.h"
#include <assert.h>

WINE_DEFAULT_DEBUG_CHANNEL(quartz);

typedef struct SystemClockAdviseEntry SystemClockAdviseEntry;
struct SystemClockAdviseEntry {
  SystemClockAdviseEntry* next;
  SystemClockAdviseEntry* prev;

  HANDLE           hEvent;
  REFERENCE_TIME   rtBaseTime;
  REFERENCE_TIME   rtIntervalTime;
};

typedef struct SystemClockImpl {
  IReferenceClockVtbl *lpVtbl;
  ULONG ref;

  /** IReferenceClock */
  HANDLE         adviseThread;
  DWORD          adviseThreadId;
  BOOL           adviseThreadActive;
  REFERENCE_TIME lastRefTime;
  DWORD	         lastTimeTickCount;
  CRITICAL_SECTION safe;

  SystemClockAdviseEntry* pSingleShotAdvise;
  SystemClockAdviseEntry* pPeriodicAdvise;
} SystemClockImpl;


static void QUARTZ_RemoveAviseEntryFromQueue(SystemClockImpl* This, SystemClockAdviseEntry* pEntry) {
  if (pEntry->prev) pEntry->prev->next = pEntry->next;
  if (pEntry->next) pEntry->next->prev = pEntry->prev;
  if (This->pSingleShotAdvise == pEntry) This->pSingleShotAdvise = pEntry->next;
  if (This->pPeriodicAdvise == pEntry)    This->pPeriodicAdvise = pEntry->next;
}

static void QUARTZ_InsertAviseEntryFromQueue(SystemClockImpl* This, SystemClockAdviseEntry* pEntry, SystemClockAdviseEntry** pQueue) {
  SystemClockAdviseEntry* prev_it = NULL;
  SystemClockAdviseEntry* it = NULL;
  REFERENCE_TIME bornTime =  pEntry->rtBaseTime + pEntry->rtIntervalTime;

  for (it = *pQueue; NULL != it && (it->rtBaseTime + it->rtIntervalTime) < bornTime; it = it->next) {
    prev_it = it;
  }
  if (NULL == prev_it) {
    pEntry->prev = NULL;
    if (NULL != (*pQueue)) pEntry->next = (*pQueue)->next;
    /*assert( NULL == pEntry->next->prev );*/
    if (NULL != pEntry->next) pEntry->next->prev = pEntry;
    (*pQueue) = pEntry;
  } else {
    pEntry->prev = prev_it;
    pEntry->next = prev_it->next;
    prev_it->next = pEntry;
    if (NULL != pEntry->next) pEntry->next->prev = pEntry;
  }
}

#define MAX_REFTIME            (REFERENCE_TIME)(0x7FFFFFFFFFFFFFFF)
#define ADVISE_EXIT            (WM_APP + 0)
#define ADVISE_REMOVE          (WM_APP + 2)
#define ADVISE_ADD_SINGLESHOT  (WM_APP + 4)
#define ADVISE_ADD_PERIODIC    (WM_APP + 8)

static DWORD WINAPI SystemClockAdviseThread(LPVOID lpParam) {
  SystemClockImpl* This = (SystemClockImpl*) lpParam;
  DWORD timeOut = INFINITE;
  DWORD tmpTimeOut;
  MSG msg;
  HRESULT hr;
  REFERENCE_TIME curTime;
  SystemClockAdviseEntry* it = NULL;

  TRACE("(%p): Main Loop\n", This);

  while (TRUE) {
    if (timeOut > 0) MsgWaitForMultipleObjects(0, NULL, FALSE, timeOut, QS_POSTMESSAGE|QS_SENDMESSAGE|QS_TIMER);
    
    EnterCriticalSection(&This->safe);
    /*timeOut = IReferenceClock_OnTimerUpdated(This); */
    hr = IReferenceClock_GetTime((IReferenceClock*) This, &curTime);
    if (FAILED(hr)) {
      timeOut = INFINITE;
      goto outrefresh;
    }
    
    /** First SingleShots Advice: sorted list */
    for (it = This->pSingleShotAdvise; NULL != it && it->rtBaseTime <= curTime; it = it->next) {
      /** send event ... */
      SetEvent((HANDLE) it->hEvent);
      /** ... and Release it */
      QUARTZ_RemoveAviseEntryFromQueue(This, it);
      HeapFree(GetProcessHeap(), 0, it);
    }
    if (NULL != it) timeOut = (DWORD) (curTime - (it->rtBaseTime + it->rtIntervalTime));

    /** Now Periodics Advice: semi sorted list (sort cannot be used) */
    for (it = This->pPeriodicAdvise; NULL != it; it = it->next) {
      if (it->rtBaseTime <= curTime) {
	DWORD nPeriods = (DWORD) ((curTime - it->rtBaseTime) / it->rtIntervalTime);
	/** Release the semaphore ... */
	ReleaseSemaphore((HANDLE) it->hEvent, nPeriods, NULL);
	/** ... and refresh time */
	it->rtBaseTime += it->rtIntervalTime;
	/*assert( it->rtBaseTime + it->rtIntervalTime < curTime );*/
      }
      tmpTimeOut = (DWORD) (curTime - (it->rtBaseTime + it->rtIntervalTime));
      if (timeOut > tmpTimeOut) timeOut = tmpTimeOut; 
    }

outrefresh:
    LeaveCriticalSection(&This->safe);
    
    while (TRUE == PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE)) {
      /** if hwnd we suppose that is a windows event ... */
      if  (NULL != msg.hwnd) {
	TranslateMessage(&msg);
	DispatchMessageA(&msg);
      } else {
	switch (msg.message) {	    
	case WM_QUIT:
	case ADVISE_EXIT:
	  goto outofthread;
	  break;
	case ADVISE_ADD_SINGLESHOT:
	case ADVISE_ADD_PERIODIC:
	  /** set timeout to 0 to do a rescan now */
	  timeOut = 0;
	  break;
	case ADVISE_REMOVE:
	  /** hmmmm what we can do here ... */
	  timeOut = INFINITE;
	  break;
	default:
	  ERR("Unhandled message %u. Critical Path\n", msg.message);
	  break;
	}
      }
    }
  }

outofthread:
  TRACE("(%p): Exiting\n", This);
  return 0;
}
/*static DWORD WINAPI SystemClockAdviseThread(LPVOID lpParam) { */

static BOOL SystemClockPostMessageToAdviseThread(SystemClockImpl* This, UINT iMsg) {
  if (FALSE == This->adviseThreadActive) {
    This->adviseThread = CreateThread(NULL, 0, SystemClockAdviseThread, This, 0, &This->adviseThreadId);
    if (NULL == This->adviseThread) return FALSE;
    SetThreadPriority(This->adviseThread, THREAD_PRIORITY_TIME_CRITICAL);
    This->adviseThreadActive = TRUE;
  }
  return PostThreadMessageA(This->adviseThreadId, iMsg, 0, 0);
}

IReferenceClockVtbl SystemClock_Vtbl;

static ULONG WINAPI SystemClockImpl_AddRef(IReferenceClock* iface) {
  SystemClockImpl *This = (SystemClockImpl *)iface;
  TRACE("(%p): AddRef from %ld\n", This, This->ref);
  return ++(This->ref);
}

static HRESULT WINAPI SystemClockImpl_QueryInterface(IReferenceClock* iface, REFIID riid, void** ppobj) {
  SystemClockImpl *This = (SystemClockImpl *)iface;
  TRACE("(%p, %s,%p)\n", This, debugstr_guid(riid), ppobj);
  
  if (IsEqualIID (riid, &IID_IUnknown) || 
      IsEqualIID (riid, &IID_IReferenceClock)) {
    SystemClockImpl_AddRef(iface);
    *ppobj = This;
    return S_OK;
  }
  
  WARN("(%p, %s,%p): not found\n", This, debugstr_guid(riid), ppobj);
  return E_NOINTERFACE;
}

static ULONG WINAPI SystemClockImpl_Release(IReferenceClock* iface) {
  SystemClockImpl *This = (SystemClockImpl *)iface;
  ULONG ref = --This->ref;
  TRACE("(%p): ReleaseRef to %ld\n", This, This->ref);
  if (ref == 0) {
    if (SystemClockPostMessageToAdviseThread(This, ADVISE_EXIT)) {
      WaitForSingleObject(This->adviseThread, INFINITE);
      CloseHandle(This->adviseThread);
    }
    DeleteCriticalSection(&This->safe);
    HeapFree(GetProcessHeap(), 0, This);
  }
  return ref;
}

static HRESULT WINAPI SystemClockImpl_GetTime(IReferenceClock* iface, REFERENCE_TIME* pTime) {
  SystemClockImpl *This = (SystemClockImpl *)iface;
  DWORD curTimeTickCount;
  HRESULT hr = S_OK;

  TRACE("(%p, %p)\n", This, pTime);

  if (NULL == pTime) {
    return E_POINTER;
  }

  curTimeTickCount = GetTickCount();

  EnterCriticalSection(&This->safe);
  /** TODO: safe this not using * 10000 */
  This->lastRefTime += (REFERENCE_TIME) (DWORD) (curTimeTickCount - This->lastTimeTickCount) * (REFERENCE_TIME) 10000;
  This->lastTimeTickCount = curTimeTickCount;
  LeaveCriticalSection(&This->safe);

  *pTime = This->lastRefTime;
  if (This->lastTimeTickCount == curTimeTickCount) hr = S_FALSE;
  This->lastTimeTickCount = curTimeTickCount;
  return hr;
}

static HRESULT WINAPI SystemClockImpl_AdviseTime(IReferenceClock* iface, REFERENCE_TIME rtBaseTime, REFERENCE_TIME rtStreamTime, HEVENT hEvent, DWORD_PTR* pdwAdviseCookie) {
  SystemClockImpl *This = (SystemClockImpl *)iface;
  SystemClockAdviseEntry* pEntry = NULL;

  TRACE("(%p, %lld, %lld, %ld, %p)\n", This, rtBaseTime, rtStreamTime, hEvent, pdwAdviseCookie);

  if ((HEVENT) 0 == hEvent) {
    return E_INVALIDARG;
  }
  if (0 >= rtBaseTime + rtStreamTime) {
    return E_INVALIDARG;
  }
  if (NULL == pdwAdviseCookie) {
    return E_POINTER;
  }
  pEntry = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(SystemClockAdviseEntry));
  if (NULL == pEntry) {
    return E_OUTOFMEMORY;
  }

  pEntry->hEvent = (HANDLE) hEvent;
  pEntry->rtBaseTime = rtBaseTime + rtStreamTime;
  pEntry->rtIntervalTime = 0;

  EnterCriticalSection(&This->safe);
  QUARTZ_InsertAviseEntryFromQueue(This, pEntry, &This->pSingleShotAdvise);
  LeaveCriticalSection(&This->safe);

  SystemClockPostMessageToAdviseThread(This, ADVISE_ADD_SINGLESHOT);

  *pdwAdviseCookie = (DWORD_PTR) (pEntry);
  return S_OK;
}

static HRESULT WINAPI SystemClockImpl_AdvisePeriodic(IReferenceClock* iface, REFERENCE_TIME rtStartTime, REFERENCE_TIME rtPeriodTime, HSEMAPHORE hSemaphore, DWORD_PTR* pdwAdviseCookie) {
  SystemClockImpl *This = (SystemClockImpl *)iface;
  SystemClockAdviseEntry* pEntry = NULL;

  TRACE("(%p, %lld, %lld, %ld, %p)\n", This, rtStartTime, rtPeriodTime, hSemaphore, pdwAdviseCookie);

  if ((HSEMAPHORE) 0 == hSemaphore) {
    return E_INVALIDARG;
  }
  if (0 >= rtStartTime || 0 >= rtPeriodTime) {
    return E_INVALIDARG;
  }
  if (NULL == pdwAdviseCookie) {
    return E_POINTER;
  }
  pEntry = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(SystemClockAdviseEntry));
  if (NULL == pEntry) {
    return E_OUTOFMEMORY;
  }

  pEntry->hEvent = (HANDLE) hSemaphore;
  pEntry->rtBaseTime = rtStartTime;
  pEntry->rtIntervalTime = rtPeriodTime;

  EnterCriticalSection(&This->safe);
  QUARTZ_InsertAviseEntryFromQueue(This, pEntry, &This->pPeriodicAdvise);
  LeaveCriticalSection(&This->safe);

  SystemClockPostMessageToAdviseThread(This, ADVISE_ADD_PERIODIC);

  *pdwAdviseCookie = (DWORD_PTR) (pEntry);
  return S_OK;
}

static HRESULT WINAPI SystemClockImpl_Unadvise(IReferenceClock* iface, DWORD_PTR dwAdviseCookie) {
  SystemClockImpl *This = (SystemClockImpl *)iface;
  SystemClockAdviseEntry* pEntry = NULL;
  SystemClockAdviseEntry* it = NULL;
  HRESULT ret = S_OK;
  TRACE("(%p, %lu)\n", This, dwAdviseCookie);

  pEntry = (SystemClockAdviseEntry*) dwAdviseCookie;

  EnterCriticalSection(&This->safe);
  for (it = This->pPeriodicAdvise; NULL != it && it != pEntry; it = it->next) ;
  if (it != pEntry) {
    for (it = This->pSingleShotAdvise; NULL != it && it != pEntry; it = it->next) ;
    if (it != pEntry) {
      ret = S_FALSE;
      goto out;
    }
  }

  QUARTZ_RemoveAviseEntryFromQueue(This, pEntry);
  HeapFree(GetProcessHeap(), 0, pEntry);

  SystemClockPostMessageToAdviseThread(This, ADVISE_REMOVE);

out:
  LeaveCriticalSection(&This->safe);
  return ret;
}

IReferenceClockVtbl SystemClock_Vtbl = 
{
    SystemClockImpl_QueryInterface,
    SystemClockImpl_AddRef,
    SystemClockImpl_Release,
    SystemClockImpl_GetTime,
    SystemClockImpl_AdviseTime,
    SystemClockImpl_AdvisePeriodic,
    SystemClockImpl_Unadvise
};

HRESULT QUARTZ_CreateSystemClock(IUnknown * pUnkOuter, LPVOID * ppv) {
  SystemClockImpl* obj = NULL;
  
  TRACE("(%p,%p)\n", ppv, pUnkOuter);
  
  obj = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IReferenceClock));
  if (NULL == obj) 	{
    *ppv = NULL;
    return E_OUTOFMEMORY;
  }
  obj->lpVtbl = &SystemClock_Vtbl;
  obj->ref = 0;  /* will be inited by QueryInterface */

  obj->lastTimeTickCount = GetTickCount();
  InitializeCriticalSection(&obj->safe);

  return SystemClockImpl_QueryInterface((IReferenceClock*) obj, &IID_IReferenceClock, ppv);
}
