/*
 * Implementation of IMediaPosition for FilterGraph.
 *
 * FIXME - stub.
 *
 * 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 "uuids.h"

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

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


static HRESULT WINAPI
IMediaPosition_fnQueryInterface(IMediaPosition* iface,REFIID riid,void** ppobj)
{
	CFilterGraph_THIS(iface,mediaposition);

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

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

static ULONG WINAPI
IMediaPosition_fnAddRef(IMediaPosition* iface)
{
	CFilterGraph_THIS(iface,mediaposition);

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

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

static ULONG WINAPI
IMediaPosition_fnRelease(IMediaPosition* iface)
{
	CFilterGraph_THIS(iface,mediaposition);

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

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

static HRESULT WINAPI
IMediaPosition_fnGetTypeInfoCount(IMediaPosition* iface,UINT* pcTypeInfo)
{
	CFilterGraph_THIS(iface,mediaposition);

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

	return IDispatch_GetTypeInfoCount(
		CFilterGraph_IDispatch(This),pcTypeInfo);
}

static HRESULT WINAPI
IMediaPosition_fnGetTypeInfo(IMediaPosition* iface,UINT iTypeInfo, LCID lcid, ITypeInfo** ppobj)
{
	CFilterGraph_THIS(iface,mediaposition);

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

	return IDispatch_GetTypeInfo(
		CFilterGraph_IDispatch(This),iTypeInfo,lcid,ppobj);
}

static HRESULT WINAPI
IMediaPosition_fnGetIDsOfNames(IMediaPosition* iface,REFIID riid, LPOLESTR* ppwszName, UINT cNames, LCID lcid, DISPID* pDispId)
{
	CFilterGraph_THIS(iface,mediaposition);

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

	return IDispatch_GetIDsOfNames(
		CFilterGraph_IDispatch(This),riid,ppwszName,cNames,lcid,pDispId);
}

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

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

	return IDispatch_Invoke(
		CFilterGraph_IDispatch(This),
		DispId,riid,lcid,wFlags,pDispParams,pVarRes,pExcepInfo,puArgErr);
}


static HRESULT WINAPI
IMediaPosition_fnget_Duration(IMediaPosition* iface,REFTIME* prefTime)
{
	CFilterGraph_THIS(iface,mediaposition);
	HRESULT	hr = E_NOTIMPL;
	HRESULT	hrFilter;
	DWORD	n;

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

	EnterCriticalSection( &This->m_csFilters );

	for ( n = 0; n < This->m_cActiveFilters; n++ )
	{
		if ( This->m_pActiveFilters[n].pPosition != NULL )
		{
			hrFilter = IMediaPosition_get_Duration( This->m_pActiveFilters[n].pPosition, prefTime );
			if ( hr == E_NOTIMPL )
			{
				hr = hrFilter;
			}
			else
			if ( hrFilter != E_NOTIMPL )
			{
				if ( SUCCEEDED(hr) )
					hr = hrFilter;
			}
		}
	}

	LeaveCriticalSection( &This->m_csFilters );

	return hr;
}

static HRESULT WINAPI
IMediaPosition_fnput_CurrentPosition(IMediaPosition* iface,REFTIME refTime)
{
	CFilterGraph_THIS(iface,mediaposition);
	HRESULT	hr = E_NOTIMPL;
	HRESULT	hrFilter;
	DWORD	n;

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

	EnterCriticalSection( &This->m_csFilters );

	for ( n = 0; n < This->m_cActiveFilters; n++ )
	{
		if ( This->m_pActiveFilters[n].pPosition != NULL )
		{
			hrFilter = IMediaPosition_put_CurrentPosition( This->m_pActiveFilters[n].pPosition, refTime );
			if ( hr == E_NOTIMPL )
			{
				hr = hrFilter;
			}
			else
			if ( hrFilter != E_NOTIMPL )
			{
				if ( SUCCEEDED(hr) )
					hr = hrFilter;
			}
		}
	}

	LeaveCriticalSection( &This->m_csFilters );

	return hr;
}

static HRESULT WINAPI
IMediaPosition_fnget_CurrentPosition(IMediaPosition* iface,REFTIME* prefTime)
{
	CFilterGraph_THIS(iface,mediaposition);
	HRESULT	hr = E_NOTIMPL;
	HRESULT	hrFilter;
	DWORD	n;

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

	EnterCriticalSection( &This->m_csFilters );

	for ( n = 0; n < This->m_cActiveFilters; n++ )
	{
		if ( This->m_pActiveFilters[n].pPosition != NULL )
		{
			hrFilter = IMediaPosition_get_CurrentPosition( This->m_pActiveFilters[n].pPosition, prefTime );
			if ( hr == E_NOTIMPL )
			{
				hr = hrFilter;
			}
			else
			if ( hrFilter != E_NOTIMPL )
			{
				if ( SUCCEEDED(hr) )
					hr = hrFilter;
			}
		}
	}

	LeaveCriticalSection( &This->m_csFilters );

	return hr;
}

static HRESULT WINAPI
IMediaPosition_fnget_StopTime(IMediaPosition* iface,REFTIME* prefTime)
{
	CFilterGraph_THIS(iface,mediaposition);
	HRESULT	hr = E_NOTIMPL;
	HRESULT	hrFilter;
	DWORD	n;

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

	EnterCriticalSection( &This->m_csFilters );

	for ( n = 0; n < This->m_cActiveFilters; n++ )
	{
		if ( This->m_pActiveFilters[n].pPosition != NULL )
		{
			hrFilter = IMediaPosition_get_StopTime( This->m_pActiveFilters[n].pPosition, prefTime );
			if ( hr == E_NOTIMPL )
			{
				hr = hrFilter;
			}
			else
			if ( hrFilter != E_NOTIMPL )
			{
				if ( SUCCEEDED(hr) )
					hr = hrFilter;
			}
		}
	}

	LeaveCriticalSection( &This->m_csFilters );

	return hr;
}

static HRESULT WINAPI
IMediaPosition_fnput_StopTime(IMediaPosition* iface,REFTIME refTime)
{
	CFilterGraph_THIS(iface,mediaposition);
	HRESULT	hr = E_NOTIMPL;
	HRESULT	hrFilter;
	DWORD	n;

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

	EnterCriticalSection( &This->m_csFilters );

	for ( n = 0; n < This->m_cActiveFilters; n++ )
	{
		if ( This->m_pActiveFilters[n].pPosition != NULL )
		{
			hrFilter = IMediaPosition_put_StopTime( This->m_pActiveFilters[n].pPosition, refTime );
			if ( hr == E_NOTIMPL )
			{
				hr = hrFilter;
			}
			else
			if ( hrFilter != E_NOTIMPL )
			{
				if ( SUCCEEDED(hr) )
					hr = hrFilter;
			}
		}
	}

	LeaveCriticalSection( &This->m_csFilters );

	return hr;
}

static HRESULT WINAPI
IMediaPosition_fnget_PrerollTime(IMediaPosition* iface,REFTIME* prefTime)
{
	CFilterGraph_THIS(iface,mediaposition);
	HRESULT	hr = E_NOTIMPL;
	HRESULT	hrFilter;
	DWORD	n;

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

	EnterCriticalSection( &This->m_csFilters );

	for ( n = 0; n < This->m_cActiveFilters; n++ )
	{
		if ( This->m_pActiveFilters[n].pPosition != NULL )
		{
			hrFilter = IMediaPosition_get_PrerollTime( This->m_pActiveFilters[n].pPosition, prefTime );
			if ( hr == E_NOTIMPL )
			{
				hr = hrFilter;
			}
			else
			if ( hrFilter != E_NOTIMPL )
			{
				if ( SUCCEEDED(hr) )
					hr = hrFilter;
			}
		}
	}

	LeaveCriticalSection( &This->m_csFilters );

	return hr;
}

static HRESULT WINAPI
IMediaPosition_fnput_PrerollTime(IMediaPosition* iface,REFTIME refTime)
{
	CFilterGraph_THIS(iface,mediaposition);
	HRESULT	hr = E_NOTIMPL;
	HRESULT	hrFilter;
	DWORD	n;

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

	EnterCriticalSection( &This->m_csFilters );

	for ( n = 0; n < This->m_cActiveFilters; n++ )
	{
		if ( This->m_pActiveFilters[n].pPosition != NULL )
		{
			hrFilter = IMediaPosition_put_PrerollTime( This->m_pActiveFilters[n].pPosition, refTime );
			if ( hr == E_NOTIMPL )
			{
				hr = hrFilter;
			}
			else
			if ( hrFilter != E_NOTIMPL )
			{
				if ( SUCCEEDED(hr) )
					hr = hrFilter;
			}
		}
	}

	LeaveCriticalSection( &This->m_csFilters );

	return hr;
}

static HRESULT WINAPI
IMediaPosition_fnput_Rate(IMediaPosition* iface,double dblRate)
{
	CFilterGraph_THIS(iface,mediaposition);
	HRESULT	hr = E_NOTIMPL;
	HRESULT	hrFilter;
	DWORD	n;

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

	EnterCriticalSection( &This->m_csFilters );

	for ( n = 0; n < This->m_cActiveFilters; n++ )
	{
		if ( This->m_pActiveFilters[n].pPosition != NULL )
		{
			hrFilter = IMediaPosition_put_Rate( This->m_pActiveFilters[n].pPosition, dblRate );
			if ( hr == E_NOTIMPL )
			{
				hr = hrFilter;
			}
			else
			if ( hrFilter != E_NOTIMPL )
			{
				if ( SUCCEEDED(hr) )
					hr = hrFilter;
			}
		}
	}

	LeaveCriticalSection( &This->m_csFilters );

	return hr;
}

static HRESULT WINAPI
IMediaPosition_fnget_Rate(IMediaPosition* iface,double* pdblRate)
{
	CFilterGraph_THIS(iface,mediaposition);
	HRESULT	hr = E_NOTIMPL;
	HRESULT	hrFilter;
	DWORD	n;

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

	EnterCriticalSection( &This->m_csFilters );

	for ( n = 0; n < This->m_cActiveFilters; n++ )
	{
		if ( This->m_pActiveFilters[n].pPosition != NULL )
		{
			hrFilter = IMediaPosition_get_Rate( This->m_pActiveFilters[n].pPosition, pdblRate );
			if ( hr == E_NOTIMPL )
			{
				hr = hrFilter;
			}
			else
			if ( hrFilter != E_NOTIMPL )
			{
				if ( SUCCEEDED(hr) )
					hr = hrFilter;
			}
		}
	}

	LeaveCriticalSection( &This->m_csFilters );

	return hr;
}

static HRESULT WINAPI
IMediaPosition_fnCanSeekForward(IMediaPosition* iface,LONG* pCanSeek)
{
	CFilterGraph_THIS(iface,mediaposition);
	HRESULT	hr = E_NOTIMPL;
	HRESULT	hrFilter;
	DWORD	n;

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

	EnterCriticalSection( &This->m_csFilters );

	for ( n = 0; n < This->m_cActiveFilters; n++ )
	{
		if ( This->m_pActiveFilters[n].pPosition != NULL )
		{
			hrFilter = IMediaPosition_CanSeekForward( This->m_pActiveFilters[n].pPosition, pCanSeek );
			if ( hr == E_NOTIMPL )
			{
				hr = hrFilter;
			}
			else
			if ( hrFilter != E_NOTIMPL )
			{
				if ( SUCCEEDED(hr) )
					hr = hrFilter;
			}
		}
	}

	LeaveCriticalSection( &This->m_csFilters );

	return hr;
}

static HRESULT WINAPI
IMediaPosition_fnCanSeekBackward(IMediaPosition* iface,LONG* pCanSeek)
{
	CFilterGraph_THIS(iface,mediaposition);
	HRESULT	hr = E_NOTIMPL;
	HRESULT	hrFilter;
	DWORD	n;

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

	EnterCriticalSection( &This->m_csFilters );

	for ( n = 0; n < This->m_cActiveFilters; n++ )
	{
		if ( This->m_pActiveFilters[n].pPosition != NULL )
		{
			hrFilter = IMediaPosition_CanSeekBackward( This->m_pActiveFilters[n].pPosition, pCanSeek );
			if ( hr == E_NOTIMPL )
			{
				hr = hrFilter;
			}
			else
			if ( hrFilter != E_NOTIMPL )
			{
				if ( SUCCEEDED(hr) )
					hr = hrFilter;
			}
		}
	}

	LeaveCriticalSection( &This->m_csFilters );

	return hr;
}


static ICOM_VTABLE(IMediaPosition) imediaposition =
{
	ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
	/* IUnknown fields */
	IMediaPosition_fnQueryInterface,
	IMediaPosition_fnAddRef,
	IMediaPosition_fnRelease,
	/* IDispatch fields */
	IMediaPosition_fnGetTypeInfoCount,
	IMediaPosition_fnGetTypeInfo,
	IMediaPosition_fnGetIDsOfNames,
	IMediaPosition_fnInvoke,
	/* IMediaPosition fields */
	IMediaPosition_fnget_Duration,
	IMediaPosition_fnput_CurrentPosition,
	IMediaPosition_fnget_CurrentPosition,
	IMediaPosition_fnget_StopTime,
	IMediaPosition_fnput_StopTime,
	IMediaPosition_fnget_PrerollTime,
	IMediaPosition_fnput_PrerollTime,
	IMediaPosition_fnput_Rate,
	IMediaPosition_fnget_Rate,
	IMediaPosition_fnCanSeekForward,
	IMediaPosition_fnCanSeekBackward,
};


HRESULT CFilterGraph_InitIMediaPosition( CFilterGraph* pfg )
{
	TRACE("(%p)\n",pfg);
	ICOM_VTBL(&pfg->mediaposition) = &imediaposition;

	return NOERROR;
}

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