/*
 * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#include "quartz_private.h"

#include "wine/debug.h"
#include "wine/unicode.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 {
  IReferenceClock IReferenceClock_iface;
  LONG ref;

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

  SystemClockAdviseEntry* pSingleShotAdvise;
  SystemClockAdviseEntry* pPeriodicAdvise;
} SystemClockImpl;

static inline SystemClockImpl *impl_from_IReferenceClock(IReferenceClock *iface)
{
    return CONTAINING_RECORD(iface, SystemClockImpl, IReferenceClock_iface);
}


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 = 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(&This->IReferenceClock_iface, &curTime);
    if (FAILED(hr)) {
      timeOut = INFINITE;
      goto outrefresh;
    }

    /** First SingleShots Advice: sorted list */
    it = This->pSingleShotAdvise;
    while ((NULL != it) && (it->rtBaseTime + it->rtIntervalTime) <= curTime) {
      SystemClockAdviseEntry* nextit = it->next;
      /** send event ... */
      SetEvent(it->hEvent);
      /** ... and Release it */
      QUARTZ_RemoveAviseEntryFromQueue(This, it);
      CoTaskMemFree(it);
      it = nextit;
    }
    if (NULL != it) timeOut = (DWORD) ((it->rtBaseTime + it->rtIntervalTime) - curTime) / (REFERENCE_TIME)10000;

    /** 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(it->hEvent, nPeriods, NULL);
	/** ... and refresh time */
	it->rtBaseTime += nPeriods * it->rtIntervalTime;
	/*assert( it->rtBaseTime + it->rtIntervalTime < curTime );*/
      }
      tmpTimeOut = (DWORD) ((it->rtBaseTime + it->rtIntervalTime) - curTime) / (REFERENCE_TIME)10000;
      if (timeOut > tmpTimeOut) timeOut = tmpTimeOut; 
    }

outrefresh:
    LeaveCriticalSection(&This->safe);
    
    while (PeekMessageW(&msg, NULL, 0, 0, PM_REMOVE)) {
      /** if hwnd we suppose that is a windows event ... */
      if  (NULL != msg.hwnd) {
	TranslateMessage(&msg);
	DispatchMessageW(&msg);
      } else {
	switch (msg.message) {	    
	case WM_QUIT:
	case ADVISE_EXIT:
	  goto outofthread;
	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) {
    BOOL res;
    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;
    while(1) {
      res = PostThreadMessageW(This->adviseThreadId, iMsg, 0, 0);
      /* Let the thread creates its message queue (with MsgWaitForMultipleObjects call) by yielding and retrying */
      if (!res && (GetLastError() == ERROR_INVALID_THREAD_ID))
	Sleep(0);
      else
	break;
    }
    return res;
  }
  return PostThreadMessageW(This->adviseThreadId, iMsg, 0, 0);
}

static ULONG WINAPI SystemClockImpl_AddRef(IReferenceClock* iface) {
  SystemClockImpl *This = impl_from_IReferenceClock(iface);
  ULONG ref = InterlockedIncrement(&This->ref);

  TRACE("(%p): AddRef from %d\n", This, ref - 1);

  return ref;
}

static HRESULT WINAPI SystemClockImpl_QueryInterface(IReferenceClock* iface, REFIID riid, void** ppobj) {
  SystemClockImpl *This = impl_from_IReferenceClock(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;
  }
  
  *ppobj = NULL;
  WARN("(%p, %s,%p): not found\n", This, debugstr_guid(riid), ppobj);
  return E_NOINTERFACE;
}

static ULONG WINAPI SystemClockImpl_Release(IReferenceClock* iface) {
  SystemClockImpl *This = impl_from_IReferenceClock(iface);
  ULONG ref = InterlockedDecrement(&This->ref);
  TRACE("(%p): ReleaseRef to %d\n", This, ref);
  if (ref == 0) {
    if (SystemClockPostMessageToAdviseThread(This, ADVISE_EXIT)) {
      WaitForSingleObject(This->adviseThread, INFINITE);
      CloseHandle(This->adviseThread);
    }
    This->safe.DebugInfo->Spare[0] = 0;
    DeleteCriticalSection(&This->safe);
    CoTaskMemFree(This);
  }
  return ref;
}

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

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

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

  curTimeTickCount = GetTickCount();

  EnterCriticalSection(&This->safe);
  if (This->lastTimeTickCount == curTimeTickCount) hr = S_FALSE;
  This->lastRefTime += (REFERENCE_TIME) (DWORD) (curTimeTickCount - This->lastTimeTickCount) * (REFERENCE_TIME) 10000;
  This->lastTimeTickCount = curTimeTickCount;
  *pTime = This->lastRefTime;
  LeaveCriticalSection(&This->safe);
  return hr;
}

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

  TRACE("(%p, 0x%s, 0x%s, %ld, %p)\n", This, wine_dbgstr_longlong(rtBaseTime),
      wine_dbgstr_longlong(rtStreamTime), hEvent, pdwAdviseCookie);

  if (!hEvent) {
    return E_INVALIDARG;
  }
  if (0 >= rtBaseTime + rtStreamTime) {
    return E_INVALIDARG;
  }
  if (NULL == pdwAdviseCookie) {
    return E_POINTER;
  }
  pEntry = CoTaskMemAlloc(sizeof(SystemClockAdviseEntry));
  if (NULL == pEntry) {
    return E_OUTOFMEMORY;
  }
  ZeroMemory(pEntry, sizeof(SystemClockAdviseEntry));

  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 = impl_from_IReferenceClock(iface);
  SystemClockAdviseEntry* pEntry = NULL;

  TRACE("(%p, 0x%s, 0x%s, %ld, %p)\n", This, wine_dbgstr_longlong(rtStartTime),
      wine_dbgstr_longlong(rtPeriodTime), hSemaphore, pdwAdviseCookie);

  if (!hSemaphore) {
    return E_INVALIDARG;
  }
  if (0 >= rtStartTime || 0 >= rtPeriodTime) {
    return E_INVALIDARG;
  }
  if (NULL == pdwAdviseCookie) {
    return E_POINTER;
  }
  pEntry = CoTaskMemAlloc(sizeof(SystemClockAdviseEntry));
  if (NULL == pEntry) {
    return E_OUTOFMEMORY;
  }
  ZeroMemory(pEntry, sizeof(SystemClockAdviseEntry));

  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 = impl_from_IReferenceClock(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);
  CoTaskMemFree(pEntry);

  SystemClockPostMessageToAdviseThread(This, ADVISE_REMOVE);

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

static const 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 = CoTaskMemAlloc(sizeof(SystemClockImpl));
  if (NULL == obj) 	{
    *ppv = NULL;
    return E_OUTOFMEMORY;
  }
  ZeroMemory(obj, sizeof(SystemClockImpl));

  obj->IReferenceClock_iface.lpVtbl = &SystemClock_Vtbl;
  obj->ref = 0;  /* will be inited by QueryInterface */

  obj->lastTimeTickCount = GetTickCount();
  InitializeCriticalSection(&obj->safe);
  obj->safe.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": SystemClockImpl.safe");

  return SystemClockImpl_QueryInterface(&obj->IReferenceClock_iface, &IID_IReferenceClock, ppv);
}
