/*
 * Implementation of IEnumFilters Interface
 *
 * Copyright 2004 Christian Costa
 *
 * 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"

WINE_DEFAULT_DEBUG_CHANNEL(quartz);

typedef struct IEnumFiltersImpl
{
    const IEnumFiltersVtbl * lpVtbl;
    LONG refCount;
    IBaseFilter ** ppFilters;
    int nFilters;
    ULONG uIndex;
} IEnumFiltersImpl;

static const struct IEnumFiltersVtbl IEnumFiltersImpl_Vtbl;

HRESULT IEnumFiltersImpl_Construct(IBaseFilter ** ppFilters, ULONG nFilters, IEnumFilters ** ppEnum)
{
    /* Note: The incoming IBaseFilter interfaces are not AddRef'd here as in Windows,
     * they should have been previously AddRef'd. */
    IEnumFiltersImpl * pEnumFilters = CoTaskMemAlloc(sizeof(IEnumFiltersImpl));

    TRACE("(%p, %d, %p)\n", ppFilters, nFilters, ppEnum);

    *ppEnum = NULL;

    if (!pEnumFilters)
    {
        return E_OUTOFMEMORY;
    }

    pEnumFilters->lpVtbl = &IEnumFiltersImpl_Vtbl;
    pEnumFilters->refCount = 1;
    pEnumFilters->uIndex = 0;
    pEnumFilters->nFilters = nFilters;
    pEnumFilters->ppFilters = CoTaskMemAlloc(sizeof(IBaseFilter*) * nFilters);
    if (!pEnumFilters->ppFilters)
    {
	CoTaskMemFree(pEnumFilters);
	return E_OUTOFMEMORY;
    }

    memcpy(pEnumFilters->ppFilters, ppFilters, nFilters * sizeof(IBaseFilter*));

    *ppEnum = (IEnumFilters *)(&pEnumFilters->lpVtbl);
    return S_OK;
}

static HRESULT WINAPI IEnumFiltersImpl_QueryInterface(IEnumFilters * iface, REFIID riid, LPVOID * ppv)
{
    TRACE("(%p)->(%s, %p)\n", iface, qzdebugstr_guid(riid), ppv);

    *ppv = NULL;

    if (IsEqualIID(riid, &IID_IUnknown))
        *ppv = iface;
    else if (IsEqualIID(riid, &IID_IEnumFilters))
        *ppv = iface;

    if (*ppv)
    {
        IUnknown_AddRef((IUnknown *)(*ppv));
        return S_OK;
    }

    FIXME("No interface for %s!\n", qzdebugstr_guid(riid));

    return E_NOINTERFACE;
}

static ULONG WINAPI IEnumFiltersImpl_AddRef(IEnumFilters * iface)
{
    IEnumFiltersImpl *This = (IEnumFiltersImpl *)iface;
    ULONG refCount = InterlockedIncrement(&This->refCount);

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

    return refCount;
}

static ULONG WINAPI IEnumFiltersImpl_Release(IEnumFilters * iface)
{
    IEnumFiltersImpl *This = (IEnumFiltersImpl *)iface;
    ULONG refCount = InterlockedDecrement(&This->refCount);

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

    if (!refCount)
    {
        CoTaskMemFree(This->ppFilters);
        CoTaskMemFree(This);
        return 0;
    }
    else
        return refCount;
}

static HRESULT WINAPI IEnumFiltersImpl_Next(IEnumFilters * iface, ULONG cFilters, IBaseFilter ** ppFilters, ULONG * pcFetched)
{
    ULONG cFetched; 
    ULONG i;
    IEnumFiltersImpl *This = (IEnumFiltersImpl *)iface;

    cFetched = min(This->nFilters, This->uIndex + cFilters) - This->uIndex;

    TRACE("(%p)->(%u, %p, %p)\n", iface, cFilters, ppFilters, pcFetched);

    if (!ppFilters)
        return E_POINTER;

    for (i = 0; i < cFetched; i++)
    {
	ppFilters[i] = This->ppFilters[This->uIndex + i];
	IBaseFilter_AddRef(ppFilters[i]);
    }

    This->uIndex += cFetched;

    if (pcFetched)
        *pcFetched = cFetched;

    if (cFetched != cFilters)
        return S_FALSE;
    return S_OK;
}

static HRESULT WINAPI IEnumFiltersImpl_Skip(IEnumFilters * iface, ULONG cFilters)
{
    IEnumFiltersImpl *This = (IEnumFiltersImpl *)iface;

    TRACE("(%p)->(%u)\n", iface, cFilters);

    if (This->uIndex + cFilters < This->nFilters)
    {
        This->uIndex += cFilters;
        return S_OK;
    }
    return S_FALSE;
}

static HRESULT WINAPI IEnumFiltersImpl_Reset(IEnumFilters * iface)
{
    IEnumFiltersImpl *This = (IEnumFiltersImpl *)iface;

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

    This->uIndex = 0;
    return S_OK;
}

static HRESULT WINAPI IEnumFiltersImpl_Clone(IEnumFilters * iface, IEnumFilters ** ppEnum)
{
    HRESULT hr;
    IEnumFiltersImpl *This = (IEnumFiltersImpl *)iface;

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

    hr = IEnumFiltersImpl_Construct(This->ppFilters, This->nFilters, ppEnum);
    if (FAILED(hr))
        return hr;
    return IEnumFilters_Skip(*ppEnum, This->uIndex);
}

static const IEnumFiltersVtbl IEnumFiltersImpl_Vtbl =
{
    IEnumFiltersImpl_QueryInterface,
    IEnumFiltersImpl_AddRef,
    IEnumFiltersImpl_Release,
    IEnumFiltersImpl_Next,
    IEnumFiltersImpl_Skip,
    IEnumFiltersImpl_Reset,
    IEnumFiltersImpl_Clone
};
