/*
 *    Virtual Printers folder
 *
 *    Copyright 2010 Nikolay Sivov for CodeWeavers
 *
 * 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 <stdio.h>

#define COBJMACROS
#define NONAMELESSUNION
#define NONAMELESSSTRUCT

#include "winerror.h"
#include "windef.h"
#include "winbase.h"

#include "shell32_main.h"
#include "wine/debug.h"
#include "debughlp.h"

#include "shresdef.h"
#include "shfldr.h"

WINE_DEFAULT_DEBUG_CHANNEL (shell);

typedef struct {
    IShellFolder2 IShellFolder2_iface;
    IPersistFolder2 IPersistFolder2_iface;
    LONG ref;

    LPITEMIDLIST pidl;
} IPrintersFolderImpl;

static inline IPrintersFolderImpl *impl_from_IShellFolder2(IShellFolder2 *iface)
{
    return CONTAINING_RECORD(iface, IPrintersFolderImpl, IShellFolder2_iface);
}

static inline IPrintersFolderImpl *impl_from_IPersistFolder2(IPersistFolder2 *iface)
{
    return CONTAINING_RECORD(iface, IPrintersFolderImpl, IPersistFolder2_iface);
}

static const shvheader printers_header[] = {
    { IDS_SHV_COLUMN8,      SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_LEFT, 20 },
    { IDS_SHV_COL_DOCS,     SHCOLSTATE_TYPE_INT | SHCOLSTATE_ONBYDEFAULT, LVCFMT_LEFT, 12 },
    { IDS_SHV_COL_STATUS,   SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_LEFT, 12 },
    { IDS_SHV_COLUMN9,      SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_LEFT, 30 },
    { IDS_SHV_COL_LOCATION, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_LEFT, 20 },
    { IDS_SHV_COL_MODEL,    SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_LEFT, 20 }
};

#define PRINTERS_FOLDER_COL_NUM sizeof(printers_header)/sizeof(shvheader)

static HRESULT WINAPI IShellFolder_Printers_fnQueryInterface(IShellFolder2 *iface,
               REFIID riid, LPVOID *ppvObj)
{
    IPrintersFolderImpl *This = impl_from_IShellFolder2(iface);

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

    *ppvObj = NULL;

    if (IsEqualIID (riid, &IID_IUnknown) ||
        IsEqualIID (riid, &IID_IShellFolder) ||
        IsEqualIID (riid, &IID_IShellFolder2))
    {
        *ppvObj = This;
    }
    else if (IsEqualIID (riid, &IID_IPersist) ||
             IsEqualIID (riid, &IID_IPersistFolder) ||
             IsEqualIID (riid, &IID_IPersistFolder2))
    {
        *ppvObj = &This->IPersistFolder2_iface;
    }

    if (*ppvObj)
    {
        IUnknown_AddRef ((IUnknown *) (*ppvObj));
        TRACE ("-- Interface: (%p)->(%p)\n", ppvObj, *ppvObj);
        return S_OK;
    }

    ERR ("-- interface %s not supported\n", shdebugstr_guid (riid));
    return E_NOINTERFACE;
}

static ULONG WINAPI IShellFolder_Printers_fnAddRef (IShellFolder2 * iface)
{
    IPrintersFolderImpl *This = impl_from_IShellFolder2(iface);
    ULONG refCount = InterlockedIncrement(&This->ref);
    TRACE ("(%p)->(count=%u)\n", This, refCount - 1);
    return refCount;
}

static ULONG WINAPI IShellFolder_Printers_fnRelease (IShellFolder2 * iface)
{
    IPrintersFolderImpl *This = impl_from_IShellFolder2(iface);
    ULONG refCount = InterlockedDecrement(&This->ref);

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

    if (!refCount)
    {
        TRACE ("-- destroying IShellFolder(%p)\n", This);
        SHFree(This->pidl);
        LocalFree (This);
    }
    return refCount;
}

static HRESULT WINAPI IShellFolder_Printers_fnParseDisplayName (IShellFolder2 *iface,
               HWND hwndOwner, LPBC pbc, LPOLESTR lpszDisplayName,
               DWORD * pchEaten, LPITEMIDLIST * ppidl, DWORD * pdwAttributes)
{
    IPrintersFolderImpl *This = impl_from_IShellFolder2(iface);

    FIXME("(%p)->(HWND=%p,%p,%p=%s,%p,pidl=%p,%p) stub\n", This,
          hwndOwner, pbc, lpszDisplayName, debugstr_w (lpszDisplayName),
          pchEaten, ppidl, pdwAttributes);

    return E_NOTIMPL;
}

static HRESULT WINAPI IShellFolder_Printers_fnEnumObjects (IShellFolder2 *iface,
               HWND hwndOwner, DWORD dwFlags, LPENUMIDLIST *ppEnumIDList)
{
    IPrintersFolderImpl *This = impl_from_IShellFolder2(iface);
    FIXME("(%p)->(HWND=%p flags=0x%08x pplist=%p) stub\n", This,
          hwndOwner, dwFlags, ppEnumIDList);
    return E_NOTIMPL;
}

static HRESULT WINAPI IShellFolder_Printers_fnBindToObject (IShellFolder2 *iface,
               LPCITEMIDLIST pidl, LPBC pbcReserved, REFIID riid, LPVOID *ppvOut)
{
    IPrintersFolderImpl *This = impl_from_IShellFolder2(iface);
    FIXME("(%p)->(pidl=%p,%p,%s,%p) stub\n", This,
          pidl, pbcReserved, shdebugstr_guid (riid), ppvOut);
    return E_NOTIMPL;
}

static HRESULT WINAPI IShellFolder_Printers_fnBindToStorage (IShellFolder2 * iface,
               LPCITEMIDLIST pidl, LPBC pbcReserved, REFIID riid, LPVOID *ppvOut)
{
    IPrintersFolderImpl *This = impl_from_IShellFolder2(iface);

    FIXME("(%p)->(pidl=%p,%p,%s,%p) stub\n", This,
          pidl, pbcReserved, shdebugstr_guid (riid), ppvOut);

    *ppvOut = NULL;
    return E_NOTIMPL;
}

static HRESULT WINAPI IShellFolder_Printers_fnCompareIDs(IShellFolder2 *iface,
               LPARAM lParam, LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2)
{
    IPrintersFolderImpl *This = impl_from_IShellFolder2(iface);
    FIXME("(%p)->(0x%08lx,pidl1=%p,pidl2=%p) stub\n", This, lParam, pidl1, pidl2);
    return E_NOTIMPL;
}

static HRESULT WINAPI IShellFolder_Printers_fnCreateViewObject(IShellFolder2 *iface,
               HWND hwndOwner, REFIID riid, LPVOID *ppvOut)
{
    IPrintersFolderImpl *This = impl_from_IShellFolder2(iface);
    HRESULT hr = E_NOTIMPL;

    TRACE("(%p)->(hwnd=%p,%s,%p)\n", This,
          hwndOwner, shdebugstr_guid (riid), ppvOut);

    if (!ppvOut)
        return E_INVALIDARG;

    *ppvOut = NULL;

    if (IsEqualIID (riid, &IID_IShellView))
    {
        IShellView *pShellView = IShellView_Constructor ((IShellFolder *) iface);
        if (pShellView)
        {
            hr = IShellView_QueryInterface (pShellView, riid, ppvOut);
            IShellView_Release (pShellView);
        }
    }
    else
        WARN("unsupported interface %s\n", shdebugstr_guid (riid));

    return hr;
}

static HRESULT WINAPI IShellFolder_Printers_fnGetAttributesOf (IShellFolder2 * iface,
                UINT cidl, LPCITEMIDLIST * apidl, DWORD * rgfInOut)
{
    IPrintersFolderImpl *This = impl_from_IShellFolder2(iface);
    FIXME("(%p)->(cidl=%d apidl=%p mask=%p (0x%08x)) stub\n",
           This, cidl, apidl, rgfInOut, rgfInOut ? *rgfInOut : 0);
    return E_NOTIMPL;
}

static HRESULT WINAPI IShellFolder_Printers_fnGetUIObjectOf (IShellFolder2 * iface,
                HWND hwndOwner, UINT cidl, LPCITEMIDLIST * apidl, REFIID riid,
                UINT * prgfInOut, LPVOID * ppvOut)
{
    IPrintersFolderImpl *This = impl_from_IShellFolder2(iface);

    FIXME("(%p)->(%p,%u,apidl=%p,%s,%p,%p) stub\n", This,
          hwndOwner, cidl, apidl, shdebugstr_guid (riid), prgfInOut, ppvOut);

    if (!ppvOut)
        return E_INVALIDARG;

    *ppvOut = NULL;

    return E_NOTIMPL;
}

static HRESULT WINAPI IShellFolder_Printers_fnGetDisplayNameOf (IShellFolder2 *iface,
               LPCITEMIDLIST pidl, DWORD dwFlags, LPSTRRET strRet)
{
    IPrintersFolderImpl *This = impl_from_IShellFolder2(iface);

    FIXME("(%p)->(pidl=%p,0x%08x,%p) stub\n", This, pidl, dwFlags, strRet);

    if (!strRet)
        return E_INVALIDARG;

    return E_NOTIMPL;
}

static HRESULT WINAPI IShellFolder_Printers_fnSetNameOf (
               IShellFolder2 * iface, HWND hwndOwner, LPCITEMIDLIST pidl,
               LPCOLESTR lpName, DWORD dwFlags, LPITEMIDLIST * pPidlOut)
{
    IPrintersFolderImpl *This = impl_from_IShellFolder2(iface);
    FIXME ("(%p)->(%p,pidl=%p,%s,%u,%p) stub\n", This,
           hwndOwner, pidl, debugstr_w (lpName), dwFlags, pPidlOut);
    return E_FAIL;
}

static HRESULT WINAPI IShellFolder_Printers_fnGetDefaultSearchGUID (
               IShellFolder2 * iface, GUID * pguid)
{
    IPrintersFolderImpl *This = impl_from_IShellFolder2(iface);
    FIXME ("(%p) stub\n", This);
    return E_NOTIMPL;
}

static HRESULT WINAPI IShellFolder_Printers_fnEnumSearches (
               IShellFolder2 * iface, IEnumExtraSearch ** ppenum)
{
    IPrintersFolderImpl *This = impl_from_IShellFolder2(iface);
    FIXME ("(%p) stub\n", This);
    return E_NOTIMPL;
}

static HRESULT WINAPI IShellFolder_Printers_fnGetDefaultColumn (
               IShellFolder2 *iface, DWORD dwRes, ULONG *pSort, ULONG *pDisplay)
{
    IPrintersFolderImpl *This = impl_from_IShellFolder2(iface);
    FIXME("(%p) stub\n", This);
    return E_NOTIMPL;
}

static HRESULT WINAPI IShellFolder_Printers_fnGetDefaultColumnState (
               IShellFolder2 *iface, UINT iColumn, DWORD *pcsFlags)
{
    IPrintersFolderImpl *This = impl_from_IShellFolder2(iface);

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

    if (iColumn >= PRINTERS_FOLDER_COL_NUM)
        return E_INVALIDARG;

    *pcsFlags = printers_header[iColumn].pcsFlags;

    return S_OK;
}

static HRESULT WINAPI IShellFolder_Printers_fnGetDetailsEx (IShellFolder2 * iface,
               LPCITEMIDLIST pidl, const SHCOLUMNID * pscid, VARIANT * pv)
{
    IPrintersFolderImpl *This = impl_from_IShellFolder2(iface);
    FIXME ("(%p) stub\n", This);
    return E_NOTIMPL;
}

static HRESULT WINAPI IShellFolder_Printers_fnGetDetailsOf (IShellFolder2 *iface,
               LPCITEMIDLIST pidl, UINT iColumn, SHELLDETAILS *psd)
{
    IPrintersFolderImpl *This = impl_from_IShellFolder2(iface);

    TRACE("(%p)->(%p %i %p)\n", This, pidl, iColumn, psd);

    if (iColumn >= PRINTERS_FOLDER_COL_NUM)
        return E_NOTIMPL;

    if (!pidl)
        return SHELL32_GetColumnDetails(printers_header, iColumn, psd);

    FIXME("unimplemented for supplied pidl\n");

    return E_NOTIMPL;
}

static HRESULT WINAPI IShellFolder_Printers_fnMapColumnToSCID (
               IShellFolder2 * iface, UINT column, SHCOLUMNID * pscid)
{
    IPrintersFolderImpl *This = impl_from_IShellFolder2(iface);
    FIXME ("(%p)->(%u %p) stub\n", This, column, pscid);
    return E_NOTIMPL;
}

static const IShellFolder2Vtbl vtbl_ShellFolder2 =
{
    /* IUnknown */
    IShellFolder_Printers_fnQueryInterface,
    IShellFolder_Printers_fnAddRef,
    IShellFolder_Printers_fnRelease,
    /* IShellFolder */
    IShellFolder_Printers_fnParseDisplayName,
    IShellFolder_Printers_fnEnumObjects,
    IShellFolder_Printers_fnBindToObject,
    IShellFolder_Printers_fnBindToStorage,
    IShellFolder_Printers_fnCompareIDs,
    IShellFolder_Printers_fnCreateViewObject,
    IShellFolder_Printers_fnGetAttributesOf,
    IShellFolder_Printers_fnGetUIObjectOf,
    IShellFolder_Printers_fnGetDisplayNameOf,
    IShellFolder_Printers_fnSetNameOf,
    /* IShellFolder2 */
    IShellFolder_Printers_fnGetDefaultSearchGUID,
    IShellFolder_Printers_fnEnumSearches,
    IShellFolder_Printers_fnGetDefaultColumn,
    IShellFolder_Printers_fnGetDefaultColumnState,
    IShellFolder_Printers_fnGetDetailsEx,
    IShellFolder_Printers_fnGetDetailsOf,
    IShellFolder_Printers_fnMapColumnToSCID
};

/*** IPersistFolder2 ***/
static HRESULT WINAPI IPersistFolder2_Printers_fnQueryInterface(IPersistFolder2 * iface,
               REFIID iid, LPVOID * ppvObj)
{
    IPrintersFolderImpl *This = impl_from_IPersistFolder2(iface);
    return IShellFolder2_QueryInterface(&This->IShellFolder2_iface, iid, ppvObj);
}

static ULONG WINAPI IPersistFolder2_Printers_fnAddRef(IPersistFolder2 *iface)
{
    IPrintersFolderImpl *This = impl_from_IPersistFolder2(iface);
    return IShellFolder2_AddRef(&This->IShellFolder2_iface);
}

static ULONG WINAPI IPersistFolder2_Printers_fnRelease(IPersistFolder2 *iface)
{
    IPrintersFolderImpl *This = impl_from_IPersistFolder2(iface);
    return IShellFolder2_Release(&This->IShellFolder2_iface);
}

static HRESULT WINAPI IPersistFolder2_Printers_fnGetClassID(IPersistFolder2 *iface, CLSID *classId)
{
    IPrintersFolderImpl *This = impl_from_IPersistFolder2(iface);

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

    if (!classId)
        return E_POINTER;

    return E_NOTIMPL;
}

static HRESULT WINAPI IPersistFolder2_Printers_fnInitialize(IPersistFolder2 *iface, LPCITEMIDLIST pidl)
{
    IPrintersFolderImpl *This = impl_from_IPersistFolder2(iface);

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

    SHFree(This->pidl);
    This->pidl = ILClone(pidl);

    return S_OK;
}

static HRESULT WINAPI IPersistFolder2_Printers_fnGetCurFolder(IPersistFolder2 *iface, LPITEMIDLIST *pidl)
{
    IPrintersFolderImpl *This = impl_from_IPersistFolder2(iface);

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

    *pidl = ILClone(This->pidl);

    return *pidl ? S_OK : S_FALSE;
}

static const IPersistFolder2Vtbl vtbl_PersistFolder2 =
{
    IPersistFolder2_Printers_fnQueryInterface,
    IPersistFolder2_Printers_fnAddRef,
    IPersistFolder2_Printers_fnRelease,
    IPersistFolder2_Printers_fnGetClassID,
    IPersistFolder2_Printers_fnInitialize,
    IPersistFolder2_Printers_fnGetCurFolder
};

HRESULT WINAPI Printers_Constructor(IUnknown * pUnkOuter, REFIID riid, LPVOID * ppv)
{
    IPrintersFolderImpl *sf;

    TRACE("unkOut=%p %s\n", pUnkOuter, shdebugstr_guid (riid));

    if (!ppv)
        return E_POINTER;
    if (pUnkOuter)
        return CLASS_E_NOAGGREGATION;

    sf = LocalAlloc(LMEM_FIXED, sizeof(IPrintersFolderImpl));
    if (!sf)
        return E_OUTOFMEMORY;

    sf->ref = 0;
    sf->pidl = NULL;
    sf->IShellFolder2_iface.lpVtbl = &vtbl_ShellFolder2;
    sf->IPersistFolder2_iface.lpVtbl = &vtbl_PersistFolder2;

    if (IShellFolder2_QueryInterface(&sf->IShellFolder2_iface, riid, ppv) != S_OK)
    {
        IShellFolder2_Release(&sf->IShellFolder2_iface);
        return E_NOINTERFACE;
    }

    TRACE("--(%p)\n", sf);
    return S_OK;
}
