/*
 * Implementation of CLSID_FilterMapper and CLSID_FilterMapper2.
 *
 * FIXME - some stubs
 *
 * 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 <stdlib.h>
#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "winuser.h"
#include "winreg.h"
#include "winerror.h"
#include "strmif.h"
#include "uuids.h"

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

#include "quartz_private.h"
#include "fmap.h"
#include "regsvr.h"
#include "devenum.h"
#include "complist.h"
#include "enumunk.h"

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

typedef struct QUARTZ_REGFILTERDATA
{
	DWORD	dwVersion; /* =2 */
	DWORD	dwMerit;
	DWORD	cPins; /* count of pins */
	DWORD	dwZero; /* padding??? */
} QUARTZ_REGFILTERDATA;

typedef struct QUARTZ_REGPINDATA
{
	CHAR	id[4]; /* '0pi3', '1pi3', ... */
	DWORD	dwFlags; /* flags */
	UINT	cInstances; /* FIXME - is this correct? */
	UINT	nMediaTypes; /* count of media types('0ty3') */
	UINT	nMediums; /* FIXME - is this correct? */
	UINT	nOfsClsPinCategory; /* FIXME - is this correct? */
} QUARTZ_REGPINDATA;

typedef struct QUARTZ_REGMEDIATYPE
{
	CHAR	id[4]; /* '0ty3', '1ty3', ... */
	DWORD	nZero; /* padding??? */
	UINT	nOfsMajorType;
	UINT	nOfsMinorType;
} QUARTZ_REGMEDIATYPE;



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

static
REGFILTER2* QUARTZ_RegFilterV2FromFilterData(
	const BYTE* pData, DWORD cbData )
{
	REGFILTER2*	pFilter;
	REGFILTERPINS2*	pPin;
	REGPINTYPES*	pTypes;
	BYTE* pDst;
	const QUARTZ_REGFILTERDATA*	pRegFilter;
	const QUARTZ_REGPINDATA*	pRegPin;
	const QUARTZ_REGMEDIATYPE*	pRegMediaType;
	DWORD	cPins;
	DWORD	cbBufSize;
	UINT	n;

	TRACE("(%p,%lu)\n",pData,cbData);

	if ( cbData < sizeof(QUARTZ_REGFILTERDATA) )
		return NULL;

	pRegFilter = (QUARTZ_REGFILTERDATA*)pData;

	if ( pRegFilter->dwVersion != 2 ) return NULL; /* FIXME */

	if ( cbData < (sizeof(QUARTZ_REGFILTERDATA)+sizeof(QUARTZ_REGPINDATA)*pRegFilter->cPins) )
		return NULL;

	cbBufSize = sizeof(REGFILTER2);
	cPins = pRegFilter->cPins;
	pRegPin = (const QUARTZ_REGPINDATA*)(pRegFilter+1);
	while ( cPins-- > 0 )
	{
		if ( pRegPin->nMediums != 0 ||
			 pRegPin->nOfsClsPinCategory != 0 )
			return NULL; /* FIXME */

		cbBufSize += sizeof(REGFILTERPINS2) +
			pRegPin->nMediaTypes * (sizeof(REGPINTYPES) + sizeof(GUID)*2) +
			pRegPin->nMediums * sizeof(REGPINMEDIUM) +
			sizeof(CLSID);
		pRegPin = (const QUARTZ_REGPINDATA*)( ((const BYTE*)pRegPin) +
			sizeof(QUARTZ_REGPINDATA) +
			sizeof(QUARTZ_REGMEDIATYPE) * pRegPin->nMediaTypes );
	}

	pFilter = (REGFILTER2*)QUARTZ_AllocMem( cbBufSize );
	if ( pFilter == NULL ) return NULL;
	ZeroMemory( pFilter, cbBufSize );
	pPin = (REGFILTERPINS2*)(pFilter+1);
	pDst = (BYTE*)(pPin + pRegFilter->cPins);

	pFilter->dwVersion = 2;
	pFilter->dwMerit = pRegFilter->dwMerit;
	pFilter->u.s2.cPins2 = pRegFilter->cPins;
	pFilter->u.s2.rgPins2 = pPin;

	cPins = pRegFilter->cPins;
	TRACE("cPins = %lu\n",cPins);

	pRegPin = (const QUARTZ_REGPINDATA*)(pRegFilter+1);
	while ( cPins-- > 0 )
	{
		pPin->dwFlags = pRegPin->dwFlags;
		pPin->cInstances = pRegPin->cInstances;
		pPin->nMediaTypes = pRegPin->nMediaTypes;
		pPin->lpMediaType = NULL;
		pPin->nMediums = pRegPin->nMediums;
		pPin->lpMedium = NULL;
		pPin->clsPinCategory = NULL;

		pTypes = (REGPINTYPES*)pDst;
		pPin->lpMediaType = pTypes;
		pDst += sizeof(REGPINTYPES) * pRegPin->nMediaTypes;

		pRegPin = (const QUARTZ_REGPINDATA*)( ((const BYTE*)pRegPin) +
			sizeof(QUARTZ_REGPINDATA) );

		for ( n = 0; n < pPin->nMediaTypes; n++ )
		{
			pRegMediaType = ((const QUARTZ_REGMEDIATYPE*)pRegPin);
			TRACE("ofsMajor = %u, ofsMinor = %u\n", pRegMediaType->nOfsMajorType, pRegMediaType->nOfsMinorType);
			memcpy( pDst, pData+pRegMediaType->nOfsMajorType, sizeof(GUID) );
			pTypes->clsMajorType = (const GUID*)pDst; pDst += sizeof(GUID);
			memcpy( pDst, pData+pRegMediaType->nOfsMinorType, sizeof(GUID) );
			pTypes->clsMinorType = (const GUID*)pDst; pDst += sizeof(GUID);

			pRegPin = (const QUARTZ_REGPINDATA*)( ((const BYTE*)pRegPin) +
				sizeof(QUARTZ_REGMEDIATYPE) );
			pTypes ++;
		}

		/* FIXME - pPin->lpMedium */
		/* FIXME - pPin->clsPinCategory */

		pPin ++;
	}

	return pFilter;
}

static
BYTE* QUARTZ_RegFilterV2ToFilterData(
	const REGFILTER2* pFilter, DWORD* pcbData )
{
	DWORD	cbData;
	DWORD	cbPinData;
	DWORD	cPins;
	const REGFILTERPINS2*	pPin;
	const REGPINTYPES*	pTypes;
	BYTE*	pRet = NULL;
	BYTE*	pDst;
	QUARTZ_REGFILTERDATA*	pRegFilter;
	QUARTZ_REGPINDATA*	pRegPin;
	QUARTZ_REGMEDIATYPE*	pRegMediaType;
	UINT	n;

	if ( pFilter->dwVersion != 2 ) return NULL; /* FIXME */

	cbData = sizeof(QUARTZ_REGFILTERDATA);
	cPins = pFilter->u.s2.cPins2;
	pPin = pFilter->u.s2.rgPins2;
	if ( cPins > 10 ) return NULL; /* FIXME */

	cbPinData = 0;
	while ( cPins-- > 0 )
	{
		if ( pPin->cInstances != 0 ||
			 pPin->nMediaTypes > 10 ||
			 pPin->nMediums != 0 ||
			 pPin->clsPinCategory != 0 )
		{
			FIXME( "not implemented.\n" );
			return NULL; /* FIXME */
		}

		cbPinData += sizeof(QUARTZ_REGPINDATA) +
			pPin->nMediaTypes * sizeof(QUARTZ_REGMEDIATYPE);
		cbData += pPin->nMediaTypes * (sizeof(GUID)*2);
		pPin ++;
	}
	cbData += cbPinData;
	TRACE("cbData %lu, cbPinData %lu\n",cbData,cbPinData);

	pRet = (BYTE*)QUARTZ_AllocMem( cbData );
	if ( pRet == NULL ) return NULL;
	ZeroMemory( pRet, cbData );
	pDst = pRet;

	pRegFilter = (QUARTZ_REGFILTERDATA*)pDst;
	pDst += sizeof(QUARTZ_REGFILTERDATA);

	pRegFilter->dwVersion = 2;
	pRegFilter->dwMerit = pFilter->dwMerit;
	pRegFilter->cPins = pFilter->u.s2.cPins2;

	pRegPin = (QUARTZ_REGPINDATA*)pDst;
	pDst += cbPinData;

	pPin = pFilter->u.s2.rgPins2;
	for ( cPins = 0; cPins < pFilter->u.s2.cPins2; cPins++ )
	{
		pRegPin->id[0] = '0'+cPins;
		pRegPin->id[1] = 'p';
		pRegPin->id[2] = 'i';
		pRegPin->id[3] = '3';
		pRegPin->dwFlags = pPin->dwFlags; /* flags */
		pRegPin->cInstances = pPin->cInstances;
		pRegPin->nMediaTypes = pPin->nMediaTypes;
		pRegPin->nMediums = pPin->nMediums;
		pRegPin->nOfsClsPinCategory = 0; /* FIXME */

		pTypes = pPin->lpMediaType;
		pRegPin = (QUARTZ_REGPINDATA*)( ((const BYTE*)pRegPin) +
			sizeof(QUARTZ_REGPINDATA) );
		for ( n = 0; n < pPin->nMediaTypes; n++ )
		{
			pRegMediaType = ((QUARTZ_REGMEDIATYPE*)pRegPin);

			pRegMediaType->id[0] = '0'+n;
			pRegMediaType->id[1] = 't';
			pRegMediaType->id[2] = 'y';
			pRegMediaType->id[3] = '3';

			/* FIXME - CLSID should be shared. */
			pRegMediaType->nOfsMajorType = pDst - pRet;
			memcpy( pDst, pTypes->clsMajorType, sizeof(GUID) );
			pDst += sizeof(GUID);
			pRegMediaType->nOfsMinorType = pDst - pRet;
			memcpy( pDst, pTypes->clsMinorType, sizeof(GUID) );
			pDst += sizeof(GUID);

			pRegPin = (QUARTZ_REGPINDATA*)( ((const BYTE*)pRegPin) +
				sizeof(QUARTZ_REGMEDIATYPE) );
			pTypes ++;
		}
		pPin ++;
	}

	*pcbData = pDst - pRet;
	TRACE("cbData %lu/%lu\n",*pcbData,cbData);

	return pRet;
}

static
REGFILTER2* QUARTZ_RegFilterV1ToV2( const REGFILTER2* prfV1 )
{
	REGFILTER2*	prfV2;
	const REGFILTERPINS*	pPinV1;
	REGFILTERPINS2*	pPinV2;
	DWORD	cPins;

	if ( prfV1->dwVersion != 1 ) return NULL;

	prfV2 = (REGFILTER2*)QUARTZ_AllocMem(
		sizeof(REGFILTER2) + sizeof(REGFILTERPINS2) * prfV1->u.s1.cPins );
	if ( prfV2 == NULL ) return NULL;
	ZeroMemory( prfV2, sizeof(REGFILTER2) + sizeof(REGFILTERPINS2) * prfV1->u.s1.cPins );
	pPinV1 = prfV1->u.s1.rgPins;
	pPinV2 = (REGFILTERPINS2*)(prfV2+1);
	prfV2->dwVersion = 2;
	prfV2->dwMerit = prfV1->dwMerit;
	prfV2->u.s2.cPins2 = prfV1->u.s1.cPins;
	prfV2->u.s2.rgPins2 = pPinV2;

	cPins = prfV1->u.s1.cPins;
	while ( cPins-- > 0 )
	{
		pPinV2->dwFlags = 0;
		pPinV2->cInstances = 0;
		pPinV2->nMediaTypes = pPinV1->nMediaTypes;
		pPinV2->lpMediaType = pPinV1->lpMediaType;
		pPinV2->nMediums = 0;
		pPinV2->lpMedium = NULL;
		pPinV2->clsPinCategory = NULL;

		if ( pPinV1->bRendered )
			pPinV2->dwFlags |= REG_PINFLAG_B_RENDERER;
		if ( pPinV1->bOutput )
			pPinV2->dwFlags |= REG_PINFLAG_B_OUTPUT;
		if ( pPinV1->bZero )
			pPinV2->dwFlags |= REG_PINFLAG_B_ZERO;
		if ( pPinV1->bMany )
			pPinV2->dwFlags |= REG_PINFLAG_B_MANY;

		pPinV1 ++;
		pPinV2 ++;
	}

	return prfV2;
}

static
BYTE* QUARTZ_RegFilterToFilterData(
	const REGFILTER2* pFilter, DWORD* pcbData )
{
	REGFILTER2*	prfV2;
	BYTE*	pRet = NULL;

	*pcbData = 0;
	switch ( pFilter->dwVersion )
	{
	case 1:
		prfV2 = QUARTZ_RegFilterV1ToV2( pFilter );
		if ( prfV2 != NULL )
		{
			pRet = QUARTZ_RegFilterV2ToFilterData( prfV2, pcbData );
			QUARTZ_FreeMem( prfV2 );
		}
		break;
	case 2:
		pRet = QUARTZ_RegFilterV2ToFilterData( pFilter, pcbData );
		break;
	default:
		FIXME( "unknown REGFILTER2 version - %08lu\n", pFilter->dwVersion );
		break;
	}

	return pRet;
}

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

static
BOOL QUARTZ_CheckPinType( BOOL bExactMatch, const REGFILTERPINS2* pPin, DWORD cTypes, const GUID* pTypes, const REGPINMEDIUM* pMedium, const CLSID* pCategory, BOOL bRender )
{
	DWORD	n1, n2;
	BOOL	bMatch;

	if ( cTypes > 0 && pTypes != NULL )
	{
		bMatch = FALSE;
		for ( n1 = 0; n1 < pPin->nMediaTypes; n1++ )
		{
			for ( n2 = 0; n2 < cTypes; n2++ )
			{
				if ( IsEqualGUID(pPin->lpMediaType[n1].clsMajorType,&GUID_NULL) || IsEqualGUID(pPin->lpMediaType[n1].clsMajorType, &pTypes[n2*2+0]) || (!bExactMatch && IsEqualGUID(pPin->lpMediaType[n1].clsMajorType,&GUID_NULL)) )
				{
					if ( IsEqualGUID(pPin->lpMediaType[n1].clsMinorType,&GUID_NULL) || IsEqualGUID(pPin->lpMediaType[n1].clsMinorType, &pTypes[n2*2+1]) || (!bExactMatch && IsEqualGUID(pPin->lpMediaType[n1].clsMinorType,&GUID_NULL)) )
					{
						bMatch = TRUE;
						break;
					}
				}
			}
		}
		TRACE("Check media type %d\n",(int)bMatch);
		if ( !bMatch )
			return FALSE;
	}

	if ( pMedium != NULL )
	{
		bMatch = FALSE;
		for ( n1 = 0; n1 < pPin->nMediums; n1++ )
		{
			if ( IsEqualGUID( &pPin->lpMedium[n1].clsMedium, &pMedium->clsMedium ) && pPin->lpMedium[n1].dw1 == pMedium->dw1 && pPin->lpMedium[n1].dw2 == pMedium->dw2 )
			{
				bMatch = TRUE;
				break;
			}
		}
		TRACE("Check medium %d\n",(int)bMatch);
		if ( !bMatch )
			return FALSE;
	}

	if ( pCategory != NULL )
	{
		if ( pPin->clsPinCategory == NULL )
			return FALSE;
		if ( (!bExactMatch && IsEqualGUID(pCategory,&GUID_NULL)) || IsEqualGUID(pCategory,pPin->clsPinCategory) )
			return TRUE;
		return FALSE;
	}

	if ( bRender && (!(pPin->dwFlags & REG_PINFLAG_B_RENDERER)) )
	{
		TRACE("not a renderer\n");
		return FALSE;
	}

	return TRUE;
}




/***************************************************************************
 *
 *	new/delete for CLSID_FilterMapper
 *
 */

/* can I use offsetof safely? - FIXME? */
static QUARTZ_IFEntry FMapIFEntries[] =
{
  { &IID_IFilterMapper, offsetof(CFilterMapper,fmap)-offsetof(CFilterMapper,unk) },
};


static void QUARTZ_DestroyFilterMapper(IUnknown* punk)
{
	CFilterMapper_THIS(punk,unk);

	CFilterMapper_UninitIFilterMapper( This );
}

HRESULT QUARTZ_CreateFilterMapper(IUnknown* punkOuter,void** ppobj)
{
	CFilterMapper*	pfm;
	HRESULT	hr;

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

	pfm = (CFilterMapper*)QUARTZ_AllocObj( sizeof(CFilterMapper) );
	if ( pfm == NULL )
		return E_OUTOFMEMORY;

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

	pfm->unk.pEntries = FMapIFEntries;
	pfm->unk.dwEntries = sizeof(FMapIFEntries)/sizeof(FMapIFEntries[0]);
	pfm->unk.pOnFinalRelease = QUARTZ_DestroyFilterMapper;

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

	return S_OK;
}

/***************************************************************************
 *
 *	CLSID_FilterMapper::IFilterMapper
 *
 */

static HRESULT WINAPI
IFilterMapper_fnQueryInterface(IFilterMapper* iface,REFIID riid,void** ppobj)
{
	CFilterMapper_THIS(iface,fmap);

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

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

static ULONG WINAPI
IFilterMapper_fnAddRef(IFilterMapper* iface)
{
	CFilterMapper_THIS(iface,fmap);

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

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

static ULONG WINAPI
IFilterMapper_fnRelease(IFilterMapper* iface)
{
	CFilterMapper_THIS(iface,fmap);

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

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


static HRESULT WINAPI
IFilterMapper_fnRegisterFilter(IFilterMapper* iface,CLSID clsid,LPCWSTR lpwszName,DWORD dwMerit)
{
	CFilterMapper_THIS(iface,fmap);

	FIXME("(%p)->(%s,%s,%08lx)\n",This,
		debugstr_guid(&clsid),debugstr_w(lpwszName),dwMerit);

	/* FIXME */
	/* FIXME - handle dwMerit! */
	return QUARTZ_RegisterAMovieFilter(
		&CLSID_LegacyAmFilterCategory,
		&clsid,
		NULL, 0,
		lpwszName, NULL, TRUE );
}

static HRESULT WINAPI
IFilterMapper_fnRegisterFilterInstance(IFilterMapper* iface,CLSID clsid,LPCWSTR lpwszName,CLSID* pclsidMedia)
{
	CFilterMapper_THIS(iface,fmap);
	HRESULT	hr;

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

	if ( pclsidMedia == NULL )
		return E_POINTER;
	hr = CoCreateGuid(pclsidMedia);
	if ( FAILED(hr) )
		return hr;

	/* FIXME */
	/* this doesn't work. */
	/* return IFilterMapper_RegisterFilter(iface,
		*pclsidMedia,lpwszName,0x60000000); */

	return E_NOTIMPL;
}

static HRESULT WINAPI
IFilterMapper_fnRegisterPin(IFilterMapper* iface,CLSID clsidFilter,LPCWSTR lpwszName,BOOL bRendered,BOOL bOutput,BOOL bZero,BOOL bMany,CLSID clsidReserved,LPCWSTR lpwszReserved)
{
	CFilterMapper_THIS(iface,fmap);

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

	return E_NOTIMPL;
}

static HRESULT WINAPI
IFilterMapper_fnRegisterPinType(IFilterMapper* iface,CLSID clsidFilter,LPCWSTR lpwszName,CLSID clsidMajorType,CLSID clsidSubType)
{
	CFilterMapper_THIS(iface,fmap);

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

	return E_NOTIMPL;
}

static HRESULT WINAPI
IFilterMapper_fnUnregisterFilter(IFilterMapper* iface,CLSID clsidFilter)
{
	CFilterMapper_THIS(iface,fmap);

	FIXME("(%p)->(%s)\n",This,debugstr_guid(&clsidFilter));

	/* FIXME */
	return QUARTZ_RegisterAMovieFilter(
		&CLSID_LegacyAmFilterCategory,
		&clsidFilter,
		NULL, 0, NULL, NULL, FALSE );
}

static HRESULT WINAPI
IFilterMapper_fnUnregisterFilterInstance(IFilterMapper* iface,CLSID clsidMedia)
{
	CFilterMapper_THIS(iface,fmap);

	FIXME("(%p)->(%s)\n",This,debugstr_guid(&clsidMedia));

	/* FIXME */
	/* this doesn't work. */
	/* return IFilterMapper_UnregisterFilter(iface,clsidMedia); */

	return E_NOTIMPL;
}

static HRESULT WINAPI
IFilterMapper_fnUnregisterPin(IFilterMapper* iface,CLSID clsidPin,LPCWSTR lpwszName)
{
	CFilterMapper_THIS(iface,fmap);

	FIXME("(%p)->(%s,%s) stub!\n",This,
		debugstr_guid(&clsidPin),debugstr_w(lpwszName));

	return E_NOTIMPL;
}

static HRESULT WINAPI
IFilterMapper_fnEnumMatchingFilters(IFilterMapper* iface,IEnumRegFilters** ppobj,DWORD dwMerit,BOOL bInputNeeded,CLSID clsInMajorType,CLSID clsidSubType,BOOL bRender,BOOL bOutputNeeded,CLSID clsOutMajorType,CLSID clsOutSubType)
{
	CFilterMapper_THIS(iface,fmap);

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

	return E_NOTIMPL;
}



static ICOM_VTABLE(IFilterMapper) ifmap =
{
	ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
	/* IUnknown fields */
	IFilterMapper_fnQueryInterface,
	IFilterMapper_fnAddRef,
	IFilterMapper_fnRelease,
	/* IFilterMapper fields */
	IFilterMapper_fnRegisterFilter,
	IFilterMapper_fnRegisterFilterInstance,
	IFilterMapper_fnRegisterPin,
	IFilterMapper_fnRegisterPinType,
	IFilterMapper_fnUnregisterFilter,
	IFilterMapper_fnUnregisterFilterInstance,
	IFilterMapper_fnUnregisterPin,
	IFilterMapper_fnEnumMatchingFilters,
};


HRESULT CFilterMapper_InitIFilterMapper( CFilterMapper* pfm )
{
	TRACE("(%p)\n",pfm);
	ICOM_VTBL(&pfm->fmap) = &ifmap;

	return NOERROR;
}

void CFilterMapper_UninitIFilterMapper( CFilterMapper* pfm )
{
	TRACE("(%p)\n",pfm);
}


/***************************************************************************
 *
 *	new/delete for CLSID_FilterMapper2
 *
 */

/* can I use offsetof safely? - FIXME? */
static QUARTZ_IFEntry FMap2IFEntries[] =
{
  { &IID_IFilterMapper2, offsetof(CFilterMapper2,fmap2)-offsetof(CFilterMapper2,unk) },
};


static void QUARTZ_DestroyFilterMapper2(IUnknown* punk)
{
	CFilterMapper2_THIS(punk,unk);

	CFilterMapper2_UninitIFilterMapper2( This );
}

HRESULT QUARTZ_CreateFilterMapper2(IUnknown* punkOuter,void** ppobj)
{
	CFilterMapper2*	pfm;
	HRESULT	hr;

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

	pfm = (CFilterMapper2*)QUARTZ_AllocObj( sizeof(CFilterMapper2) );
	if ( pfm == NULL )
		return E_OUTOFMEMORY;

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

	pfm->unk.pEntries = FMap2IFEntries;
	pfm->unk.dwEntries = sizeof(FMap2IFEntries)/sizeof(FMap2IFEntries[0]);
	pfm->unk.pOnFinalRelease = QUARTZ_DestroyFilterMapper2;

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

	return S_OK;
}

/***************************************************************************
 *
 *	CLSID_FilterMapper2::IFilterMapper2
 *
 */


static HRESULT WINAPI
IFilterMapper2_fnQueryInterface(IFilterMapper2* iface,REFIID riid,void** ppobj)
{
	CFilterMapper2_THIS(iface,fmap2);

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

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

static ULONG WINAPI
IFilterMapper2_fnAddRef(IFilterMapper2* iface)
{
	CFilterMapper2_THIS(iface,fmap2);

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

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

static ULONG WINAPI
IFilterMapper2_fnRelease(IFilterMapper2* iface)
{
	CFilterMapper2_THIS(iface,fmap2);

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

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

static HRESULT WINAPI
IFilterMapper2_fnCreateCategory(IFilterMapper2* iface,REFCLSID rclsidCategory,DWORD dwMerit,LPCWSTR lpwszDesc)
{
	CFilterMapper2_THIS(iface,fmap2);

	FIXME("(%p)->(%s,%lu,%s) stub!\n",This,
		debugstr_guid(rclsidCategory),
		(unsigned long)dwMerit,debugstr_w(lpwszDesc));

	return E_NOTIMPL;
}


static HRESULT WINAPI
IFilterMapper2_fnUnregisterFilter(IFilterMapper2* iface,const CLSID* pclsidCategory,const OLECHAR* lpwszInst,REFCLSID rclsidFilter)
{
	CFilterMapper2_THIS(iface,fmap2);
	WCHAR*	pwszPath = NULL;
	HRESULT hr;

	TRACE("(%p)->(%s,%s,%s)\n",This,
		debugstr_guid(pclsidCategory),
		debugstr_w(lpwszInst),
		debugstr_guid(rclsidFilter));

	if ( pclsidCategory == NULL )
		pclsidCategory = &CLSID_LegacyAmFilterCategory;

	hr = QUARTZ_GetFilterRegPath(
		&pwszPath, pclsidCategory, rclsidFilter, lpwszInst );
	if ( FAILED(hr) )
		return hr;

	hr = QUARTZ_RegDeleteKey(HKEY_CLASSES_ROOT,pwszPath);
	QUARTZ_FreeMem(pwszPath);

	return hr;
}


static HRESULT WINAPI
IFilterMapper2_fnRegisterFilter(IFilterMapper2* iface,REFCLSID rclsidFilter,LPCWSTR lpName,IMoniker** ppMoniker,const CLSID* pclsidCategory,const OLECHAR* lpwszInst,const REGFILTER2* pRF2)
{
	CFilterMapper2_THIS(iface,fmap2);
	WCHAR*  pwszPath = NULL;
	IMoniker*	pMoniker = NULL;
	BYTE*	pFilterData = NULL;
	DWORD	cbFilterData = 0;
	HRESULT hr;

	TRACE( "(%p)->(%s,%s,%p,%s,%s,%p) stub!\n",This,
		debugstr_guid(rclsidFilter),debugstr_w(lpName),
		ppMoniker,debugstr_guid(pclsidCategory),
		debugstr_w(lpwszInst),pRF2 );

	if ( lpName == NULL || pRF2 == NULL )
		return E_POINTER;

	if ( ppMoniker != NULL && *ppMoniker != NULL )
	{
		FIXME( "ppMoniker != NULL - not implemented! *ppMoniker = %p\n",*ppMoniker );
		return E_NOTIMPL;
	}

	if ( pclsidCategory == NULL )
		pclsidCategory = &CLSID_LegacyAmFilterCategory;

	if ( pMoniker == NULL )
	{
	        hr = QUARTZ_GetFilterRegPath(
		        &pwszPath, pclsidCategory, rclsidFilter, lpwszInst );
		if ( FAILED(hr) )
			return hr;
		hr = QUARTZ_CreateDeviceMoniker(
			HKEY_CLASSES_ROOT,pwszPath,&pMoniker);
		QUARTZ_FreeMem(pwszPath);
		if ( FAILED(hr) )
			return hr;
	}

	pFilterData = QUARTZ_RegFilterToFilterData( pRF2, &cbFilterData );
	if ( pFilterData == NULL || cbFilterData == 0 )
	{
		hr = E_FAIL;
		goto err;
	}

	hr = QUARTZ_RegisterFilterToMoniker(
		pMoniker, rclsidFilter, lpName, pFilterData, cbFilterData );
	if ( FAILED(hr) )
		goto err;

	if ( ppMoniker != NULL )
	{
		*ppMoniker = pMoniker;
		pMoniker = NULL;
	}
err:
	if ( pFilterData != NULL )
		QUARTZ_FreeMem(pFilterData);
	if ( pMoniker != NULL )
		IMoniker_Release(pMoniker);

	return hr;
}

struct MATCHED_ITEM
{
	IMoniker*	pMonFilter;
	DWORD		dwMerit;
};

static int sort_comp_merit(const void* p1,const void* p2)
{
	const struct MATCHED_ITEM*	pItem1 = (const struct MATCHED_ITEM*)p1;
        const struct MATCHED_ITEM*      pItem2 = (const struct MATCHED_ITEM*)p2;

	return (int)pItem2->dwMerit - (int)pItem1->dwMerit;
}

static HRESULT WINAPI
IFilterMapper2_fnEnumMatchingFilters(IFilterMapper2* iface,
	IEnumMoniker** ppEnumMoniker,DWORD dwFlags,BOOL bExactMatch,DWORD dwMerit,
	BOOL bInputNeeded,DWORD cInputTypes,const GUID* pguidInputTypes,const REGPINMEDIUM* pPinMediumIn,const CLSID* pPinCategoryIn,BOOL bRender,
	BOOL bOutputNeeded,DWORD cOutputTypes,const GUID* pguidOutputTypes,const REGPINMEDIUM* pPinMediumOut,const CLSID* pPinCategoryOut)
{
	CFilterMapper2_THIS(iface,fmap2);
	ICreateDevEnum*	pEnum = NULL;
	IEnumMoniker*	pCategories = NULL;
	IMoniker*	pCat = NULL;
	DWORD	dwCatMerit;
	IEnumMoniker*	pCatFilters = NULL;
	IMoniker*	pFilter = NULL;
	CLSID	clsid;
	ULONG	cReturned;
	BYTE*	pbFilterData = NULL;
	DWORD	cbFilterData = 0;
	REGFILTER2*	prf2 = NULL;
	QUARTZ_CompList*	pListFilters = NULL;
	struct MATCHED_ITEM*	pItems = NULL;
	struct MATCHED_ITEM*	pItemsTmp;
	int			cItems = 0;
	const REGFILTERPINS2*	pRegFilterPin;
	DWORD	n;
	BOOL	bMatch;
	HRESULT hr;

	WARN("(%p)->(%p,%08lx,%d,%08lx,%d,%lu,%p,%p,%p,%d,%d,%lu,%p,%p,%p) some features are not implemented\n",
		This,ppEnumMoniker,dwFlags,bExactMatch,dwMerit,
		bInputNeeded,cInputTypes,pguidInputTypes,
		pPinMediumIn,pPinCategoryIn,
		bRender,
		bOutputNeeded,cOutputTypes,pguidOutputTypes,
		pPinMediumOut,pPinCategoryOut);

	if ( ppEnumMoniker == NULL )
		return E_POINTER;
	*ppEnumMoniker = NULL;
	if ( dwFlags != 0 )
		return E_INVALIDARG;

	hr = CoCreateInstance(
		&CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER,
		&IID_ICreateDevEnum, (void**)&pEnum );
	if ( FAILED(hr) )
		goto err;

	hr = ICreateDevEnum_CreateClassEnumerator(pEnum,&CLSID_ActiveMovieCategories,&pCategories,0);
	if ( hr != S_OK )
		goto err;

	while ( 1 )
	{
		if ( pCat != NULL )
		{
			IMoniker_Release(pCat);
			pCat = NULL;
		}
		hr = IEnumMoniker_Next(pCategories,1,&pCat,&cReturned);
		if ( FAILED(hr) )
			goto err;
		if ( hr != S_OK )
			break;
		hr = QUARTZ_GetMeritFromMoniker(pCat,&dwCatMerit);
		if ( hr != S_OK || dwMerit > dwCatMerit )
			continue;
		hr = QUARTZ_GetCLSIDFromMoniker(pCat,&clsid);
		if ( hr != S_OK )
			continue;

		if ( pCatFilters != NULL )
		{
			IEnumMoniker_Release(pCatFilters);
			pCatFilters = NULL;
		}
		hr = ICreateDevEnum_CreateClassEnumerator(pEnum,&clsid,&pCatFilters,0);
		if ( FAILED(hr) )
			goto err;
		if ( hr != S_OK )
			continue;

		while ( 1 )
		{
			if ( pFilter != NULL )
			{
				IMoniker_Release(pFilter);
				pFilter = NULL;
			}
			hr = IEnumMoniker_Next(pCatFilters,1,&pFilter,&cReturned);
			if ( FAILED(hr) )
				goto err;
			if ( hr != S_OK )
				break;
			if ( pbFilterData != NULL )
			{
				QUARTZ_FreeMem(pbFilterData);
				pbFilterData = NULL;
			}
			if(TRACE_ON(quartz))
			{
				CLSID clsidTrace;
				if (SUCCEEDED(QUARTZ_GetCLSIDFromMoniker(pFilter,&clsidTrace)))
				{
					TRACE("moniker clsid %s\n",debugstr_guid(&clsidTrace));
				}
			}
			hr = QUARTZ_GetFilterDataFromMoniker(pFilter,&pbFilterData,&cbFilterData);
			if ( hr != S_OK )
				continue;

			if ( prf2 != NULL )
			{
				QUARTZ_FreeMem(prf2);
				prf2 = NULL;
			}
			prf2 = QUARTZ_RegFilterV2FromFilterData(pbFilterData,cbFilterData);
			if ( prf2 == NULL )
				continue;
			TRACE("prf2 %p, Merit %08lx\n",prf2,prf2->dwMerit);
			if ( prf2->dwMerit < dwMerit || prf2->dwVersion != 2 )
				continue;

			/* check input pins. */
			if ( bInputNeeded )
			{
				bMatch = FALSE;
				for ( n = 0; n < prf2->u.s2.cPins2; n++ )
				{
					pRegFilterPin = &prf2->u.s2.rgPins2[n];
					if ( pRegFilterPin->dwFlags & REG_PINFLAG_B_OUTPUT )
						continue;
					bMatch = QUARTZ_CheckPinType( bExactMatch, pRegFilterPin, cInputTypes, pguidInputTypes, pPinMediumIn, pPinCategoryIn, bRender );
					if ( bMatch )
						break;
				}
				if ( !bMatch )
				{
					TRACE("no matching input pin\n");
					continue;
				}
			}

			/* check output pins. */
			if ( bOutputNeeded )
			{
				bMatch = FALSE;
				for ( n = 0; n < prf2->u.s2.cPins2; n++ )
				{
					pRegFilterPin = &prf2->u.s2.rgPins2[n];
					if ( !(pRegFilterPin->dwFlags & REG_PINFLAG_B_OUTPUT) )
						continue;
					bMatch = QUARTZ_CheckPinType( bExactMatch, pRegFilterPin, cOutputTypes, pguidOutputTypes, pPinMediumOut, pPinCategoryOut, FALSE );
					if ( bMatch )
						break;
				}
				if ( !bMatch )
				{
					TRACE("no matching output pin\n");
					continue;
				}
			}

			/* matched - add pFilter to the list. */
			pItemsTmp = QUARTZ_ReallocMem( pItems, sizeof(struct MATCHED_ITEM) * (cItems+1) );
			if ( pItemsTmp == NULL )
			{
				hr = E_OUTOFMEMORY;
				goto err;
			}
			pItems = pItemsTmp;
			pItemsTmp = pItems + cItems; cItems ++;
			pItemsTmp->pMonFilter = pFilter; pFilter = NULL;
			pItemsTmp->dwMerit = prf2->dwMerit;
		}
	}

	if ( pItems == NULL || cItems == 0 )
	{
		hr = S_FALSE;
		goto err;
	}

	/* FIXME - sort in Merit order */
	TRACE("sort in Merit order\n");
	qsort( pItems, cItems, sizeof(struct MATCHED_ITEM), sort_comp_merit );

	pListFilters = QUARTZ_CompList_Alloc();
	if ( pListFilters == NULL )
	{
		hr = E_OUTOFMEMORY;
		goto err;
	}
	for ( n = 0; n < cItems; n++ )
	{
		TRACE("merit %08lx\n",pItems[n].dwMerit);
		hr = QUARTZ_CompList_AddComp( pListFilters, (IUnknown*)pItems[n].pMonFilter, NULL, 0 );
		if ( FAILED(hr) )
			goto err;
	}

	hr = QUARTZ_CreateEnumUnknown( &IID_IEnumMoniker, (void**)ppEnumMoniker, pListFilters );
	if ( FAILED(hr) )
		goto err;

	hr = S_OK;
err:
	if ( pEnum != NULL )
		ICreateDevEnum_Release(pEnum);
	if ( pCategories != NULL )
		IEnumMoniker_Release(pCategories);
	if ( pCat != NULL )
		IMoniker_Release(pCat);
	if ( pCatFilters != NULL )
		IEnumMoniker_Release(pCatFilters);
	if ( pFilter != NULL )
		IMoniker_Release(pFilter);
	if ( pbFilterData != NULL )
		QUARTZ_FreeMem(pbFilterData);
	if ( prf2 != NULL )
		QUARTZ_FreeMem(prf2);
	if ( pItems != NULL && cItems > 0 )
	{
		for ( n = 0; n < cItems; n++ )
		{
			if ( pItems[n].pMonFilter != NULL )
				IMoniker_Release(pItems[n].pMonFilter);
		}
		QUARTZ_FreeMem(pItems);
	}
	if ( pListFilters != NULL )
		QUARTZ_CompList_Free( pListFilters );

	TRACE("returns %08lx\n",hr);

	return hr;
}




static ICOM_VTABLE(IFilterMapper2) ifmap2 =
{
	ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
	/* IUnknown fields */
	IFilterMapper2_fnQueryInterface,
	IFilterMapper2_fnAddRef,
	IFilterMapper2_fnRelease,
	/* IFilterMapper2 fields */
	IFilterMapper2_fnCreateCategory,
	IFilterMapper2_fnUnregisterFilter,
	IFilterMapper2_fnRegisterFilter,
	IFilterMapper2_fnEnumMatchingFilters,
};


HRESULT CFilterMapper2_InitIFilterMapper2( CFilterMapper2* pfm )
{
	TRACE("(%p)\n",pfm);
	ICOM_VTBL(&pfm->fmap2) = &ifmap2;

	return NOERROR;
}

void CFilterMapper2_UninitIFilterMapper2( CFilterMapper2* pfm )
{
	TRACE("(%p)\n",pfm);
}

