/*
 * IEnum* implementation
 *
 * Copyright 2006 Mike McCormack
 *
 * 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
 */

#define COBJMACROS

#include <stdarg.h>

#include "windef.h"
#include "winbase.h"
#include "objbase.h"

#include "enumx.h"

#include "wine/list.h"
#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(ole);

struct tagEnumSTATPROPSETSTG_impl
{
    const void *vtbl;
    LONG ref;
    struct list elements;
    struct list *current;
    ULONG elem_size;
    GUID riid;
};

/************************************************************************
 * enumx_QueryInterface
 */
HRESULT WINAPI enumx_QueryInterface(
    enumx_impl *This,
    REFIID riid,
    void** ppvObject)
{
    if ( ppvObject==0 )
        return E_INVALIDARG;

    *ppvObject = 0;

    if (IsEqualGUID(&IID_IUnknown, riid) ||
        IsEqualGUID(&This->riid, riid))
    {
        IUnknown_AddRef(((IUnknown*)This));
        *ppvObject = This;
        return S_OK;
    }

    return E_NOINTERFACE;
}

/************************************************************************
 * enumx_AddRef
 */
ULONG WINAPI enumx_AddRef(enumx_impl *This)
{
    return InterlockedIncrement(&This->ref);
}

/************************************************************************
 * enumx_Release
 */
ULONG WINAPI enumx_Release(enumx_impl *This)
{
    ULONG ref;

    ref = InterlockedDecrement(&This->ref);
    if (ref == 0)
    {
        while (!list_empty(&This->elements))
        {
             struct list *x = list_head(&This->elements);
             list_remove(x);
             HeapFree(GetProcessHeap(), 0, x);
        }
        HeapFree(GetProcessHeap(), 0, This);
    }
    return ref;
}

/************************************************************************
 * enumx_Next
 */
HRESULT WINAPI enumx_Next(enumx_impl *This, ULONG celt,
                                 void *rgelt, ULONG *pceltFetched)
{
    unsigned char *p;
    ULONG count = 0;

    TRACE("%p %u %p\n", This, celt, pceltFetched);

    if (This->current == NULL)
        This->current = list_head(&This->elements);
    p = rgelt;
    while (count < celt && This->current && This->current != &This->elements)
    {
        memcpy(p, &This->current[1], This->elem_size);
        p += This->elem_size;
        This->current = This->current->next;
        count++;
    }
    if (pceltFetched)
        *pceltFetched = count;
    if (count < celt)
        return S_FALSE;
    return S_OK;
}

/************************************************************************
 * enumx_Skip
 */
HRESULT WINAPI enumx_Skip(enumx_impl *This, ULONG celt)
{
    ULONG count = 0;

    TRACE("%p %u\n", This, celt);

    if (This->current == NULL)
        This->current = list_head(&This->elements);

    while (count < celt && This->current && This->current != &This->elements)
        count++;

    return S_OK;
}

/************************************************************************
 * enumx_Reset
 */
HRESULT WINAPI enumx_Reset(enumx_impl *This)
{
    TRACE("\n");

    This->current = NULL;
    return S_OK;
}

/************************************************************************
 * enumx_fnClone
 */
HRESULT WINAPI enumx_Clone(
    enumx_impl *iface,
    enumx_impl **ppenum)
{
    FIXME("\n");
    return E_NOTIMPL;
}

/************************************************************************
 * enumx_allocate
 *
 * Allocate a generic enumerator
 */
enumx_impl *enumx_allocate(REFIID riid, const void *vtbl, ULONG elem_size)
{
    enumx_impl *enumx;

    enumx = HeapAlloc(GetProcessHeap(), 0, sizeof *enumx);
    if (enumx)
    {
        enumx->vtbl = vtbl;
        enumx->ref = 1;
        enumx->current = NULL;
        enumx->elem_size = elem_size;
        enumx->riid = *riid;
        list_init(&enumx->elements);
    }

    return enumx;
}

/************************************************************************
 * enumx_add_element
 *
 * Add an element to the enumeration.
 */
void *enumx_add_element(enumx_impl *enumx, const void *data)
{
    struct list *element;

    element = HeapAlloc(GetProcessHeap(), 0, sizeof *element + enumx->elem_size);
    if (!element)
        return NULL;
    memcpy(&element[1], data, enumx->elem_size);
    list_add_tail(&enumx->elements, element);
    return &element[1];
}
