/*
 * Implementation of IEnumRegFilters 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/unicode.h"

#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(quartz);

typedef struct IEnumRegFiltersImpl
{
    const IEnumRegFiltersVtbl * lpVtbl;
    LONG refCount;
    ULONG size;
    REGFILTER* RegFilters;
    ULONG uIndex;
} IEnumRegFiltersImpl;

static const struct IEnumRegFiltersVtbl IEnumRegFiltersImpl_Vtbl;

HRESULT IEnumRegFiltersImpl_Construct(REGFILTER* pInRegFilters, const ULONG size, IEnumRegFilters ** ppEnum)
{
    IEnumRegFiltersImpl* pEnumRegFilters;
    REGFILTER* pRegFilters = NULL;
    unsigned int i;

    TRACE("(%p, %d, %p)\n", pInRegFilters, size, ppEnum);

    pEnumRegFilters = CoTaskMemAlloc(sizeof(IEnumRegFiltersImpl));
    if (!pEnumRegFilters)
    {
        *ppEnum = NULL;
        return E_OUTOFMEMORY;
    }

    /* Accept size of 0 */
    if (size)
    {
        pRegFilters = CoTaskMemAlloc(sizeof(REGFILTER)*size);
        if (!pRegFilters)
	{
            CoTaskMemFree(pEnumRegFilters);
            *ppEnum = NULL;
           return E_OUTOFMEMORY;
        }
    }

    for(i = 0; i < size; i++)
    {
        pRegFilters[i].Clsid = pInRegFilters[i].Clsid;
        pRegFilters[i].Name = (WCHAR*)CoTaskMemAlloc((strlenW(pInRegFilters[i].Name)+1)*sizeof(WCHAR));
        if (!pRegFilters[i].Name)
        {
            while(i)
                CoTaskMemFree(pRegFilters[--i].Name);
            CoTaskMemFree(pRegFilters);
            CoTaskMemFree(pEnumRegFilters);
            return E_OUTOFMEMORY;
        }
        CopyMemory(pRegFilters[i].Name, pInRegFilters[i].Name, (strlenW(pInRegFilters[i].Name)+1)*sizeof(WCHAR));
    }

    pEnumRegFilters->lpVtbl = &IEnumRegFiltersImpl_Vtbl;
    pEnumRegFilters->refCount = 1;
    pEnumRegFilters->uIndex = 0;
    pEnumRegFilters->RegFilters = pRegFilters;
    pEnumRegFilters->size = size;

    *ppEnum = (IEnumRegFilters *)(&pEnumRegFilters->lpVtbl);

    return S_OK;
}

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

    *ppv = NULL;

    if (IsEqualIID(riid, &IID_IUnknown))
        *ppv = (LPVOID)iface;
    else if (IsEqualIID(riid, &IID_IEnumRegFilters))
        *ppv = (LPVOID)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 IEnumRegFiltersImpl_AddRef(IEnumRegFilters * iface)
{
    IEnumRegFiltersImpl *This = (IEnumRegFiltersImpl *)iface;
    ULONG refCount = InterlockedIncrement(&This->refCount);

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

    return refCount;
}

static ULONG WINAPI IEnumRegFiltersImpl_Release(IEnumRegFilters * iface)
{
    IEnumRegFiltersImpl *This = (IEnumRegFiltersImpl *)iface;
    ULONG refCount = InterlockedDecrement(&This->refCount);

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

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

static HRESULT WINAPI IEnumRegFiltersImpl_Next(IEnumRegFilters * iface, ULONG cFilters, REGFILTER ** ppRegFilter, ULONG * pcFetched)
{
    ULONG cFetched; 
    IEnumRegFiltersImpl *This = (IEnumRegFiltersImpl *)iface;
    unsigned int i;

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

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

    if (cFetched > 0)
    {
        for(i = 0; i < cFetched; i++)
        {
            /* The string in the REGFILTER structure must be allocated in the same block as the REGFILTER structure itself */
            ppRegFilter[i] = (REGFILTER*)CoTaskMemAlloc(sizeof(REGFILTER)+(strlenW(This->RegFilters[i].Name)+1)*sizeof(WCHAR));
            if (!ppRegFilter[i])
            {
                while(i)
                {
                    CoTaskMemFree(ppRegFilter[--i]);
                    ppRegFilter[i] = NULL;
                }
                return E_OUTOFMEMORY;
        }
            ppRegFilter[i]->Clsid = This->RegFilters[i].Clsid;
            ppRegFilter[i]->Name = (WCHAR*)((char*)ppRegFilter[i]+sizeof(REGFILTER));
            CopyMemory(ppRegFilter[i]->Name, This->RegFilters[i].Name, (strlenW(This->RegFilters[i].Name)+1)*sizeof(WCHAR));
        }

        This->uIndex += cFetched;
        if (pcFetched)
            *pcFetched = cFetched;
        return S_OK;
    }

    return S_FALSE;
}

static HRESULT WINAPI IEnumRegFiltersImpl_Skip(IEnumRegFilters * iface, ULONG n)
{
    TRACE("(%p)->(%u)\n", iface, n);

    return E_NOTIMPL;
}

static HRESULT WINAPI IEnumRegFiltersImpl_Reset(IEnumRegFilters * iface)
{
    IEnumRegFiltersImpl *This = (IEnumRegFiltersImpl *)iface;

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

    This->uIndex = 0;
    return S_OK;
}

static HRESULT WINAPI IEnumRegFiltersImpl_Clone(IEnumRegFilters * iface, IEnumRegFilters ** ppEnum)
{
    TRACE("(%p)->(%p)\n", iface, ppEnum);

    return E_NOTIMPL;
}

static const IEnumRegFiltersVtbl IEnumRegFiltersImpl_Vtbl =
{
    IEnumRegFiltersImpl_QueryInterface,
    IEnumRegFiltersImpl_AddRef,
    IEnumRegFiltersImpl_Release,
    IEnumRegFiltersImpl_Next,
    IEnumRegFiltersImpl_Skip,
    IEnumRegFiltersImpl_Reset,
    IEnumRegFiltersImpl_Clone
};
