/*
 * CLSID_FilterGraph event handling.
 *
 * 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 "control.h"
#include "evcode.h"
#include "uuids.h"
#include "vfwmsgs.h"

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

#include "quartz_private.h"
#include "fgraph.h"

#define EVENTQUEUE_BLOCKSIZE	2
#define EVENTQUEUE_MAX			1024

struct FilterGraph_MEDIAEVENT
{
	long		lEventCode;
	LONG_PTR	lParam1;
	LONG_PTR	lParam2;
};


static HRESULT FGEVENT_KeepEvent(
	BOOL bKeep,
	long lEventCode, LONG_PTR lParam1, LONG_PTR lParam2 )
{
	switch ( lEventCode )
	{
	/*case EC_COMPLETE:*/
	case EC_USERABORT:
		break;
	case EC_ERRORABORT:
		break;
	case EC_TIME:
		break;
	/*case EC_REPAINT:*/
	case EC_STREAM_ERROR_STOPPED:
		break;
	case EC_STREAM_ERROR_STILLPLAYING:
		break;
	case EC_ERROR_STILLPLAYING:
		break;
	case EC_PALETTE_CHANGED:
		break;
	case EC_VIDEO_SIZE_CHANGED:
		break;
	case EC_QUALITY_CHANGE:
		break;
	/*case EC_SHUTTING_DOWN:*/
	case EC_CLOCK_CHANGED:
		break;

	case EC_OPENING_FILE:
		break;
	case EC_BUFFERING_DATA:
		break;
	case EC_FULLSCREEN_LOST:
		if ( bKeep )
		{
			if ( ((IBaseFilter*)lParam2) != NULL )
				IBaseFilter_AddRef( (IBaseFilter*)lParam2 );
		}
		else
		{
			if ( ((IBaseFilter*)lParam2) != NULL )
				IBaseFilter_Release( (IBaseFilter*)lParam2 );
		}
		break;
	/*case EC_ACTIVATE:*/
	/*case EC_NEED_RESTART:*/
	/*case EC_WINDOW_DESTROYED:*/
	/*case EC_DISPLAY_CHANGED:*/
	/*case EC_STARVATION:*/
	/*case EC_OLE_EVENT:*/
	/*case EC_NOTIFY_WINDOW:*/
	/*case EC_STREAM_CONTROL_STOPPED:*/
	/*case EC_STREAM_CONTROL_STARTED:*/
	/*case EC_END_OF_SEGMENT:*/
	/*case EC_SEGMENT_STARTED:*/
	case EC_LENGTH_CHANGED:
		break;

	default:
		if ( lEventCode < EC_USER )
		{
			FIXME( "unknown system event %08lx\n", lEventCode );
			return E_INVALIDARG;
		}
		TRACE( "user event %08lx\n", lEventCode );
		break;
	}

	return NOERROR;
}

/***************************************************************************
 *
 *	CLSID_FilterGraph::IMediaEvent[Ex]
 *
 */

static HRESULT WINAPI
IMediaEventEx_fnQueryInterface(IMediaEventEx* iface,REFIID riid,void** ppobj)
{
	CFilterGraph_THIS(iface,mediaevent);

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

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

static ULONG WINAPI
IMediaEventEx_fnAddRef(IMediaEventEx* iface)
{
	CFilterGraph_THIS(iface,mediaevent);

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

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

static ULONG WINAPI
IMediaEventEx_fnRelease(IMediaEventEx* iface)
{
	CFilterGraph_THIS(iface,mediaevent);

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

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

static HRESULT WINAPI
IMediaEventEx_fnGetTypeInfoCount(IMediaEventEx* iface,UINT* pcTypeInfo)
{
	CFilterGraph_THIS(iface,mediaevent);

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

	return E_NOTIMPL;
}

static HRESULT WINAPI
IMediaEventEx_fnGetTypeInfo(IMediaEventEx* iface,UINT iTypeInfo, LCID lcid, ITypeInfo** ppobj)
{
	CFilterGraph_THIS(iface,mediaevent);

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

	return E_NOTIMPL;
}

static HRESULT WINAPI
IMediaEventEx_fnGetIDsOfNames(IMediaEventEx* iface,REFIID riid, LPOLESTR* ppwszName, UINT cNames, LCID lcid, DISPID* pDispId)
{
	CFilterGraph_THIS(iface,mediaevent);

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

	return E_NOTIMPL;
}

static HRESULT WINAPI
IMediaEventEx_fnInvoke(IMediaEventEx* iface,DISPID DispId, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarRes, EXCEPINFO* pExcepInfo, UINT* puArgErr)
{
	CFilterGraph_THIS(iface,mediaevent);

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

	return E_NOTIMPL;
}


static HRESULT WINAPI
IMediaEventEx_fnGetEventHandle(IMediaEventEx* iface,OAEVENT* hEvent)
{
	CFilterGraph_THIS(iface,mediaevent);

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

	*hEvent = (OAEVENT)This->m_hMediaEvent;

	return NOERROR;
}

static HRESULT WINAPI
IMediaEventEx_fnGetEvent(IMediaEventEx* iface,long* plEventCode,LONG_PTR* plParam1,LONG_PTR* plParam2,long lTimeOut)
{
	CFilterGraph_THIS(iface,mediaevent);
	ULONG cQueued;
	DWORD dw;
	DWORD dwStart;
	HRESULT	hr;
	FilterGraph_MEDIAEVENT*	pEvent;

	TRACE("(%p)->(%p,%p,%p,%ld)\n",This,plEventCode,
		plParam1,plParam2,lTimeOut);

	if ( plEventCode == NULL || plParam1 == NULL || plParam2 == NULL )
		return E_POINTER;

	while ( 1 )
	{
		dwStart = GetTickCount();
		dw = WaitForSingleObject( This->m_hMediaEvent, lTimeOut );
		if ( dw == WAIT_TIMEOUT )
			return VFW_E_TIMEOUT;
		if ( dw != WAIT_OBJECT_0 )
			return E_FAIL;

		EnterCriticalSection( &This->m_csMediaEvents );
		hr = S_FALSE;
		if ( This->m_cbMediaEventsMax > 0 )
		{
			cQueued =
				(This->m_cbMediaEventsMax +
				 This->m_cbMediaEventsPut - This->m_cbMediaEventsGet) %
					This->m_cbMediaEventsMax;
			if ( cQueued > 0 )
			{
				pEvent = &This->m_pMediaEvents[This->m_cbMediaEventsGet];
				*plEventCode = pEvent->lEventCode;
				*plParam1 = pEvent->lParam1;
				*plParam2 = pEvent->lParam2;
				This->m_cbMediaEventsGet = (This->m_cbMediaEventsGet + 1) %
						This->m_cbMediaEventsMax;

				hr = NOERROR;
				if ( This->m_cbMediaEventsPut == This->m_cbMediaEventsGet )
					ResetEvent( This->m_hMediaEvent );
			}
		}
		LeaveCriticalSection( &This->m_csMediaEvents );

		if ( hr != S_FALSE )
			return hr;
		if ( lTimeOut != INFINITE )
		{
			lTimeOut -= GetTickCount() - dwStart;
			if ( lTimeOut < 0 )
				return VFW_E_TIMEOUT;
		}
	}
}

static HRESULT WINAPI
IMediaEventEx_fnWaitForCompletion(IMediaEventEx* iface,long lTimeOut,long* plEventCode)
{
	CFilterGraph_THIS(iface,mediaevent);
	HRESULT hr;
	long lEventCode;
	LONG_PTR lParam1;
	LONG_PTR lParam2;
	DWORD dwTimePrev;
	DWORD dwTimeCur;

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

	if ( plEventCode == NULL )
		return E_POINTER;
	*plEventCode = 0;

	dwTimePrev = GetTickCount();

	while ( 1 )
	{
		hr = IMediaEventEx_GetEvent(
				CFilterGraph_IMediaEventEx(This),
				&lEventCode,&lParam1,&lParam2,lTimeOut);
		if ( hr == VFW_E_TIMEOUT )
			hr = E_ABORT;
		if ( hr != NOERROR )
			return hr;
		IMediaEventEx_FreeEventParams(
				CFilterGraph_IMediaEventEx(This),
				lEventCode,lParam1,lParam2);

		if ( lEventCode == EC_COMPLETE ||
			 lEventCode == EC_ERRORABORT ||
			 lEventCode == EC_USERABORT )
		{
			*plEventCode = lEventCode;
			return NOERROR;
		}

		if ( lTimeOut != INFINITE )
		{
			dwTimeCur = GetTickCount();
			lTimeOut -= dwTimeCur - dwTimePrev;
			dwTimePrev = dwTimeCur;
			if ( lTimeOut < 0 )
				return E_ABORT;
		}
	}
}

static HRESULT WINAPI
IMediaEventEx_fnCancelDefaultHandling(IMediaEventEx* iface,long lEventCode)
{
	CFilterGraph_THIS(iface,mediaevent);

	FIXME("(%p)->() stub!\n",This);

	return E_NOTIMPL;
}

static HRESULT WINAPI
IMediaEventEx_fnRestoreDefaultHandling(IMediaEventEx* iface,long lEventCode)
{
	CFilterGraph_THIS(iface,mediaevent);

	FIXME("(%p)->() stub!\n",This);

	return E_NOTIMPL;
}

static HRESULT WINAPI
IMediaEventEx_fnFreeEventParams(IMediaEventEx* iface,long lEventCode,LONG_PTR lParam1,LONG_PTR lParam2)
{
	CFilterGraph_THIS(iface,mediaevent);

	TRACE("(%p)->(%08lx,%08x,%08x)\n",This,lEventCode,lParam1,lParam2);

	return FGEVENT_KeepEvent( FALSE, lEventCode, lParam1, lParam2 );
}

static HRESULT WINAPI
IMediaEventEx_fnSetNotifyWindow(IMediaEventEx* iface,OAHWND hwnd,long message,LONG_PTR lParam)
{
	CFilterGraph_THIS(iface,mediaevent);

	TRACE("(%p)->(%08x,%08lx,%08x)\n",This,hwnd,message,lParam);

	EnterCriticalSection( &This->m_csMediaEvents );
	This->m_hwndEventNotify = (HWND)hwnd;
	This->m_lEventNotifyMsg = message;
	This->m_lEventNotifyParam = lParam;
	LeaveCriticalSection( &This->m_csMediaEvents );

	return NOERROR;
}

static HRESULT WINAPI
IMediaEventEx_fnSetNotifyFlags(IMediaEventEx* iface,long lNotifyFlags)
{
	CFilterGraph_THIS(iface,mediaevent);

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

	if ( lNotifyFlags != 0 && lNotifyFlags != 1 )
		return E_INVALIDARG;

	EnterCriticalSection( &This->m_csMediaEvents );
	This->m_lEventNotifyFlags = lNotifyFlags;
	LeaveCriticalSection( &This->m_csMediaEvents );

	return NOERROR;
}

static HRESULT WINAPI
IMediaEventEx_fnGetNotifyFlags(IMediaEventEx* iface,long* plNotifyFlags)
{
	CFilterGraph_THIS(iface,mediaevent);

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

	if ( plNotifyFlags == NULL )
		return E_POINTER;

	EnterCriticalSection( &This->m_csMediaEvents );
	*plNotifyFlags = This->m_lEventNotifyFlags;
	LeaveCriticalSection( &This->m_csMediaEvents );

	return NOERROR;
}



static ICOM_VTABLE(IMediaEventEx) imediaevent =
{
	ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
	/* IUnknown fields */
	IMediaEventEx_fnQueryInterface,
	IMediaEventEx_fnAddRef,
	IMediaEventEx_fnRelease,
	/* IDispatch fields */
	IMediaEventEx_fnGetTypeInfoCount,
	IMediaEventEx_fnGetTypeInfo,
	IMediaEventEx_fnGetIDsOfNames,
	IMediaEventEx_fnInvoke,
	/* IMediaEvent fields */
	IMediaEventEx_fnGetEventHandle,
	IMediaEventEx_fnGetEvent,
	IMediaEventEx_fnWaitForCompletion,
	IMediaEventEx_fnCancelDefaultHandling,
	IMediaEventEx_fnRestoreDefaultHandling,
	IMediaEventEx_fnFreeEventParams,
	/* IMediaEventEx fields */
	IMediaEventEx_fnSetNotifyWindow,
	IMediaEventEx_fnSetNotifyFlags,
	IMediaEventEx_fnGetNotifyFlags,
};


HRESULT CFilterGraph_InitIMediaEventEx( CFilterGraph* pfg )
{
	TRACE("(%p)\n",pfg);
	ICOM_VTBL(&pfg->mediaevent) = &imediaevent;

	pfg->m_hMediaEvent = CreateEventA( NULL, TRUE, FALSE, NULL );
	if ( pfg->m_hMediaEvent == (HANDLE)NULL )
		return E_OUTOFMEMORY;

	InitializeCriticalSection( &pfg->m_csMediaEvents );
	pfg->m_pMediaEvents = NULL;
	pfg->m_cbMediaEventsPut = 0;
	pfg->m_cbMediaEventsGet = 0;
	pfg->m_cbMediaEventsMax = 0;
	pfg->m_hwndEventNotify = (HWND)NULL;
	pfg->m_lEventNotifyMsg = 0;
	pfg->m_lEventNotifyParam = 0;
	pfg->m_lEventNotifyFlags = 0;

	return NOERROR;
}

void CFilterGraph_UninitIMediaEventEx( CFilterGraph* pfg )
{
	HRESULT hr;
	long lEventCode;
	LONG_PTR lParam1;
	LONG_PTR lParam2;

	TRACE("(%p)\n",pfg);

	while ( 1 )
	{
		hr = IMediaEventEx_GetEvent(
				CFilterGraph_IMediaEventEx(pfg),
				&lEventCode,&lParam1,&lParam2,0);
		if ( hr != NOERROR )
			break;
		IMediaEventEx_FreeEventParams(
				CFilterGraph_IMediaEventEx(pfg),
				lEventCode,lParam1,lParam2);
	}

	if ( pfg->m_pMediaEvents != NULL )
	{
		QUARTZ_FreeMem( pfg->m_pMediaEvents );
		pfg->m_pMediaEvents = NULL;
	}

	DeleteCriticalSection( &pfg->m_csMediaEvents );
	CloseHandle( pfg->m_hMediaEvent );
}

/***************************************************************************
 *
 *	CLSID_FilterGraph::IMediaEventSink
 *
 */

static HRESULT WINAPI
IMediaEventSink_fnQueryInterface(IMediaEventSink* iface,REFIID riid,void** ppobj)
{
	CFilterGraph_THIS(iface,mediaeventsink);

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

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

static ULONG WINAPI
IMediaEventSink_fnAddRef(IMediaEventSink* iface)
{
	CFilterGraph_THIS(iface,mediaeventsink);

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

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

static ULONG WINAPI
IMediaEventSink_fnRelease(IMediaEventSink* iface)
{
	CFilterGraph_THIS(iface,mediaeventsink);

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

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

static HRESULT WINAPI
IMediaEventSink_fnNotify(IMediaEventSink* iface,long lEventCode,LONG_PTR lParam1,LONG_PTR lParam2)
{
	CFilterGraph_THIS(iface,mediaeventsink);
	HRESULT hr = NOERROR;
	ULONG cQueued;
	ULONG cTemp;
	FilterGraph_MEDIAEVENT*	pEvent;

	TRACE("(%p)->(%08lx,%08x,%08x) stub!\n",This,lEventCode,lParam1,lParam2);

	EnterCriticalSection( &This->m_csMediaEvents );

	/* allocate a new entry. */
	if ( This->m_cbMediaEventsMax == 0 )
		cQueued = 0;
	else
		cQueued =
			(This->m_cbMediaEventsMax +
			 This->m_cbMediaEventsPut - This->m_cbMediaEventsGet) %
				This->m_cbMediaEventsMax;

	if ( (cQueued + 1) >= This->m_cbMediaEventsMax )
	{
		if ( This->m_cbMediaEventsMax >= EVENTQUEUE_MAX )
		{
			hr = E_FAIL;
			goto end;
		}
		pEvent = (FilterGraph_MEDIAEVENT*)
			QUARTZ_AllocMem( sizeof(FilterGraph_MEDIAEVENT) *
				(This->m_cbMediaEventsMax+EVENTQUEUE_BLOCKSIZE) );
		if ( pEvent == NULL )
		{
			hr = E_OUTOFMEMORY;
			goto end;
		}
		if ( cQueued > 0 )
		{
			if ( (This->m_cbMediaEventsGet + cQueued) >=
				This->m_cbMediaEventsMax )
			{
				cTemp = This->m_cbMediaEventsMax - This->m_cbMediaEventsGet;
				memcpy(
					pEvent,
					&This->m_pMediaEvents[This->m_cbMediaEventsGet],
					sizeof(FilterGraph_MEDIAEVENT) * cTemp );
				memcpy(
					pEvent + cTemp,
					&This->m_pMediaEvents[0],
					sizeof(FilterGraph_MEDIAEVENT) * (cQueued - cTemp) );
			}
			else
			{
				memcpy(
					pEvent,
					&This->m_pMediaEvents[This->m_cbMediaEventsGet],
					sizeof(FilterGraph_MEDIAEVENT) * cQueued );
			}
			QUARTZ_FreeMem( This->m_pMediaEvents );
		}
		This->m_pMediaEvents = pEvent;
		This->m_cbMediaEventsMax += EVENTQUEUE_BLOCKSIZE;
		This->m_cbMediaEventsPut = cQueued;
		This->m_cbMediaEventsGet = 0;
	}

	/* duplicate params if necessary. */
	hr = FGEVENT_KeepEvent( TRUE, lEventCode, lParam1, lParam2 );
	if ( FAILED(hr) )
		goto end;

	/* add to the queue. */
	pEvent = &This->m_pMediaEvents[This->m_cbMediaEventsPut];
	pEvent->lEventCode = lEventCode;
	pEvent->lParam1 = lParam1;
	pEvent->lParam2 = lParam2;
	This->m_cbMediaEventsPut =
		(This->m_cbMediaEventsPut + 1) % This->m_cbMediaEventsMax;

	SetEvent( This->m_hMediaEvent );
	if ( This->m_hwndEventNotify != (HWND)NULL &&
		 This->m_lEventNotifyFlags == 0 )
	{
		PostMessageA(
			This->m_hwndEventNotify,
			This->m_lEventNotifyMsg,
			(WPARAM)0,
			(LPARAM)This->m_lEventNotifyParam );
	}

	hr = NOERROR;
end:
	LeaveCriticalSection( &This->m_csMediaEvents );

	return hr;
}


static ICOM_VTABLE(IMediaEventSink) imediaeventsink =
{
	ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
	/* IUnknown fields */
	IMediaEventSink_fnQueryInterface,
	IMediaEventSink_fnAddRef,
	IMediaEventSink_fnRelease,
	/* IMediaEventSink fields */
	IMediaEventSink_fnNotify,
};



HRESULT CFilterGraph_InitIMediaEventSink( CFilterGraph* pfg )
{
	TRACE("(%p)\n",pfg);
	ICOM_VTBL(&pfg->mediaeventsink) = &imediaeventsink;

	return NOERROR;
}

void CFilterGraph_UninitIMediaEventSink( CFilterGraph* pfg )
{
	TRACE("(%p)\n",pfg);
}

