/*
 *	IEnumIDList
 *
 *	Copyright 1998	Juergen Schmied <juergen.schmied@metronet.de>
 *
 * 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 <stdarg.h>
#include <stdlib.h>
#include <string.h>

#define COBJMACROS

#include "wine/debug.h"
#include "wine/unicode.h"
#include "windef.h"
#include "winbase.h"
#include "winreg.h"
#include "shlwapi.h"

#include "pidl.h"
#include "shell32_main.h"

WINE_DEFAULT_DEBUG_CHANNEL(shell);

/**************************************************************************
 *  AddToEnumList()
 */
BOOL AddToEnumList(IEnumIDListImpl *list, LPITEMIDLIST pidl)
{
    struct pidl_enum_entry *pidl_entry;

    TRACE("(%p)->(pidl=%p)\n", list, pidl);

    if (!list || !pidl)
        return FALSE;

    if (!(pidl_entry = SHAlloc(sizeof(*pidl_entry))))
        return FALSE;

    pidl_entry->pidl = pidl;
    list_add_tail(&list->pidls, &pidl_entry->entry);
    if (!list->current)
        list->current = list_head(&list->pidls);

    return TRUE;
}

/**************************************************************************
 *  CreateFolderEnumList()
 */
BOOL CreateFolderEnumList(IEnumIDListImpl *list, LPCWSTR lpszPath, DWORD dwFlags)
{
    LPITEMIDLIST pidl=NULL;
    WIN32_FIND_DATAW stffile;
    HANDLE hFile;
    WCHAR  szPath[MAX_PATH];
    BOOL succeeded = TRUE;
    static const WCHAR stars[] = { '*','.','*',0 };
    static const WCHAR dot[] = { '.',0 };
    static const WCHAR dotdot[] = { '.','.',0 };

    TRACE("(%p)->(path=%s flags=0x%08x)\n", list, debugstr_w(lpszPath), dwFlags);

    if(!lpszPath || !lpszPath[0]) return FALSE;

    strcpyW(szPath, lpszPath);
    PathAddBackslashW(szPath);
    strcatW(szPath,stars);

    hFile = FindFirstFileW(szPath,&stffile);
    if ( hFile != INVALID_HANDLE_VALUE )
    {
        BOOL findFinished = FALSE;

        do
        {
            if ( !(stffile.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) 
             || (dwFlags & SHCONTF_INCLUDEHIDDEN) )
            {
                if ( (stffile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) &&
                 dwFlags & SHCONTF_FOLDERS &&
                 strcmpW(stffile.cFileName, dot) && strcmpW(stffile.cFileName, dotdot))
                {
                    pidl = _ILCreateFromFindDataW(&stffile);
                    succeeded = succeeded && AddToEnumList(list, pidl);
                }
                else if (!(stffile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
                 && dwFlags & SHCONTF_NONFOLDERS)
                {
                    pidl = _ILCreateFromFindDataW(&stffile);
                    succeeded = succeeded && AddToEnumList(list, pidl);
                }
            }
            if (succeeded)
            {
                if (!FindNextFileW(hFile, &stffile))
                {
                    if (GetLastError() == ERROR_NO_MORE_FILES)
                        findFinished = TRUE;
                    else
                        succeeded = FALSE;
                }
            }
        } while (succeeded && !findFinished);
        FindClose(hFile);
    }
    return succeeded;
}

static inline IEnumIDListImpl *impl_from_IEnumIDList(IEnumIDList *iface)
{
    return CONTAINING_RECORD(iface, IEnumIDListImpl, IEnumIDList_iface);
}

/**************************************************************************
 *  IEnumIDList::QueryInterface
 */
static HRESULT WINAPI IEnumIDList_fnQueryInterface(IEnumIDList *iface, REFIID riid, void **ppvObj)
{
    IEnumIDListImpl *This = impl_from_IEnumIDList(iface);

    TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(riid), ppvObj);

    *ppvObj = NULL;

    if (IsEqualIID(riid, &IID_IUnknown) ||
        IsEqualIID(riid, &IID_IEnumIDList))
    {
        *ppvObj = &This->IEnumIDList_iface;
    }

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

    WARN("interface %s is not supported\n", debugstr_guid(riid));
    return E_NOINTERFACE;
}

/******************************************************************************
 * IEnumIDList::AddRef
 */
static ULONG WINAPI IEnumIDList_fnAddRef(IEnumIDList *iface)
{
    IEnumIDListImpl *This = impl_from_IEnumIDList(iface);
    ULONG refCount = InterlockedIncrement(&This->ref);

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

    return refCount;
}

/******************************************************************************
 * IEnumIDList::Release
 */
static ULONG WINAPI IEnumIDList_fnRelease(IEnumIDList *iface)
{
    IEnumIDListImpl *This = impl_from_IEnumIDList(iface);
    ULONG refCount = InterlockedDecrement(&This->ref);

    TRACE("(%p)->(%u)\n", This, refCount + 1);

    if (!refCount)
    {
        struct pidl_enum_entry *cur, *cur2;

        LIST_FOR_EACH_ENTRY_SAFE(cur, cur2, &This->pidls, struct pidl_enum_entry, entry)
        {
            list_remove(&cur->entry);
            SHFree(cur->pidl);
            SHFree(cur);
        }
        HeapFree(GetProcessHeap(), 0, This);
    }

    return refCount;
}

/**************************************************************************
 *  IEnumIDList::Next
 */

static HRESULT WINAPI IEnumIDList_fnNext(IEnumIDList *iface, ULONG celt, LPITEMIDLIST *rgelt,
        ULONG *fetched)
{
    IEnumIDListImpl *This = impl_from_IEnumIDList(iface);
    HRESULT hr = S_OK;
    ULONG i;

    TRACE("(%p)->(%d, %p, %p)\n", This, celt, rgelt, fetched);

    /* It is valid to leave pceltFetched NULL when celt is 1. Some of explorer's
     * subsystems actually use it (and so may a third party browser)
     */
    if (fetched)
        *fetched = 0;

    *rgelt = NULL;

    if (celt > 1 && !fetched)
        return E_INVALIDARG;

    if (celt > 0 && !This->current)
        return S_FALSE;

    for (i = 0; i < celt; i++)
    {
        if (!This->current)
            break;

        rgelt[i] = ILClone(LIST_ENTRY(This->current, struct pidl_enum_entry, entry)->pidl);
        This->current = list_next(&This->pidls, This->current);
    }

    if (fetched)
        *fetched = i;

    return hr;
}

/**************************************************************************
*  IEnumIDList::Skip
*/
static HRESULT WINAPI IEnumIDList_fnSkip(IEnumIDList *iface, ULONG celt)
{
    IEnumIDListImpl *This = impl_from_IEnumIDList(iface);
    HRESULT hr = S_OK;
    ULONG i;

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

    for (i = 0; i < celt; i++)
    {
        if (!This->current)
        {
            hr = S_FALSE;
            break;
        }
        This->current = list_next(&This->pidls, This->current);
    }

    return hr;
}

/**************************************************************************
*  IEnumIDList::Reset
*/
static HRESULT WINAPI IEnumIDList_fnReset(IEnumIDList *iface)
{
    IEnumIDListImpl *This = impl_from_IEnumIDList(iface);

    TRACE("(%p)\n",This);
    This->current = list_head(&This->pidls);
    return S_OK;
}

/**************************************************************************
*  IEnumIDList::Clone
*/
static HRESULT WINAPI IEnumIDList_fnClone(IEnumIDList *iface, IEnumIDList **ppenum)
{
    IEnumIDListImpl *This = impl_from_IEnumIDList(iface);

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

    return E_NOTIMPL;
}

static const IEnumIDListVtbl eidlvt =
{
    IEnumIDList_fnQueryInterface,
    IEnumIDList_fnAddRef,
    IEnumIDList_fnRelease,
    IEnumIDList_fnNext,
    IEnumIDList_fnSkip,
    IEnumIDList_fnReset,
    IEnumIDList_fnClone,
};

IEnumIDListImpl *IEnumIDList_Constructor(void)
{
    IEnumIDListImpl *lpeidl = HeapAlloc(GetProcessHeap(), 0, sizeof(*lpeidl));

    if (lpeidl)
    {
        lpeidl->IEnumIDList_iface.lpVtbl = &eidlvt;
        lpeidl->ref = 1;
        list_init(&lpeidl->pidls);
        lpeidl->current = NULL;
    }

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

    return lpeidl;
}
