/*
 * Copyright 2009 Henri Verbeet for CodeWeavers
 * Copyright 2011 André Hentschel
 *
 * 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 "ieframe.h"

#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(ieframe);

struct taskbar_list
{
    ITaskbarList4 ITaskbarList4_iface;
    LONG refcount;
};

static inline struct taskbar_list *impl_from_ITaskbarList4(ITaskbarList4 *iface)
{
    return CONTAINING_RECORD(iface, struct taskbar_list, ITaskbarList4_iface);
}

/* IUnknown methods */

static HRESULT STDMETHODCALLTYPE taskbar_list_QueryInterface(ITaskbarList4 *iface, REFIID riid, void **object)
{
    TRACE("iface %p, riid %s, object %p\n", iface, debugstr_guid(riid), object);

    if (IsEqualGUID(riid, &IID_ITaskbarList) ||
        IsEqualGUID(riid, &IID_ITaskbarList2) ||
        IsEqualGUID(riid, &IID_ITaskbarList3) ||
        IsEqualGUID(riid, &IID_ITaskbarList4) ||
        IsEqualGUID(riid, &IID_IUnknown))
    {
        IUnknown_AddRef(iface);
        *object = iface;
        return S_OK;
    }

    WARN("%s not implemented, returning E_NOINTERFACE\n", debugstr_guid(riid));

    *object = NULL;
    return E_NOINTERFACE;
}

static ULONG STDMETHODCALLTYPE taskbar_list_AddRef(ITaskbarList4 *iface)
{
    struct taskbar_list *This = impl_from_ITaskbarList4(iface);
    ULONG refcount = InterlockedIncrement(&This->refcount);

    TRACE("%p increasing refcount to %u\n", This, refcount);

    return refcount;
}

static ULONG STDMETHODCALLTYPE taskbar_list_Release(ITaskbarList4 *iface)
{
    struct taskbar_list *This = impl_from_ITaskbarList4(iface);
    ULONG refcount = InterlockedDecrement(&This->refcount);

    TRACE("%p decreasing refcount to %u\n", This, refcount);

    if (!refcount)
    {
        heap_free(This);
        unlock_module();
    }

    return refcount;
}

/* ITaskbarList methods */

static HRESULT STDMETHODCALLTYPE taskbar_list_HrInit(ITaskbarList4 *iface)
{
    TRACE("iface %p\n", iface);

    return S_OK;
}

static HRESULT STDMETHODCALLTYPE taskbar_list_AddTab(ITaskbarList4 *iface, HWND hwnd)
{
    FIXME("iface %p, hwnd %p stub!\n", iface, hwnd);

    return E_NOTIMPL;
}

static HRESULT STDMETHODCALLTYPE taskbar_list_DeleteTab(ITaskbarList4 *iface, HWND hwnd)
{
    FIXME("iface %p, hwnd %p stub!\n", iface, hwnd);

    return E_NOTIMPL;
}

static HRESULT STDMETHODCALLTYPE taskbar_list_ActivateTab(ITaskbarList4 *iface, HWND hwnd)
{
    FIXME("iface %p, hwnd %p stub!\n", iface, hwnd);

    return E_NOTIMPL;
}

static HRESULT STDMETHODCALLTYPE taskbar_list_SetActiveAlt(ITaskbarList4 *iface, HWND hwnd)
{
    FIXME("iface %p, hwnd %p stub!\n", iface, hwnd);

    return E_NOTIMPL;
}

/* ITaskbarList2 method */

static HRESULT STDMETHODCALLTYPE taskbar_list_MarkFullscreenWindow(ITaskbarList4 *iface,
                                                                   HWND hwnd,
                                                                   BOOL fullscreen)
{
    FIXME("iface %p, hwnd %p, fullscreen %s stub!\n", iface, hwnd, (fullscreen)?"true":"false");

    return E_NOTIMPL;
}

/* ITaskbarList3 methods */

static HRESULT STDMETHODCALLTYPE taskbar_list_SetProgressValue(ITaskbarList4 *iface,
                                                               HWND hwnd,
                                                               ULONGLONG ullCompleted,
                                                               ULONGLONG ullTotal)
{
    static BOOL fixme_once;
    if(!fixme_once++) FIXME("iface %p, hwnd %p, ullCompleted %s, ullTotal %s stub!\n", iface, hwnd,
                            wine_dbgstr_longlong(ullCompleted), wine_dbgstr_longlong(ullTotal));

    return S_OK;
}

static HRESULT STDMETHODCALLTYPE taskbar_list_SetProgressState(ITaskbarList4 *iface,
                                                               HWND hwnd,
                                                               TBPFLAG tbpFlags)
{
    static BOOL fixme_once;
    if(!fixme_once++) FIXME("iface %p, hwnd %p, flags %x stub!\n", iface, hwnd, tbpFlags);

    return S_OK;
}

static HRESULT STDMETHODCALLTYPE taskbar_list_RegisterTab(ITaskbarList4 *iface, HWND hwndTab, HWND hwndMDI)
{
    FIXME("iface %p, hwndTab %p, hwndMDI %p stub!\n", iface, hwndTab, hwndMDI);

    return E_NOTIMPL;
}

static HRESULT STDMETHODCALLTYPE taskbar_list_UnregisterTab(ITaskbarList4 *iface, HWND hwndTab)
{
    FIXME("iface %p, hwndTab %p stub!\n", iface, hwndTab);

    return E_NOTIMPL;
}

static HRESULT STDMETHODCALLTYPE taskbar_list_SetTabOrder(ITaskbarList4 *iface,
                                                          HWND hwndTab,
                                                          HWND hwndInsertBefore)
{
    FIXME("iface %p, hwndTab %p, hwndInsertBefore %p stub!\n", iface, hwndTab, hwndInsertBefore);

    return E_NOTIMPL;
}

static HRESULT STDMETHODCALLTYPE taskbar_list_SetTabActive(ITaskbarList4 *iface,
                                                          HWND hwndTab,
                                                          HWND hwndMDI,
                                                          DWORD dwReserved)
{
    FIXME("iface %p, hwndTab %p, hwndMDI %p, dwReserved %x stub!\n", iface, hwndTab, hwndMDI, dwReserved);

    return E_NOTIMPL;
}

static HRESULT STDMETHODCALLTYPE taskbar_list_ThumbBarAddButtons(ITaskbarList4 *iface,
                                                                 HWND hwnd,
                                                                 UINT cButtons,
                                                                 LPTHUMBBUTTON pButton)
{
    FIXME("iface %p, hwnd %p, cButtons %u, pButton %p stub!\n", iface, hwnd, cButtons, pButton);

    return E_NOTIMPL;
}

static HRESULT STDMETHODCALLTYPE taskbar_list_ThumbBarUpdateButtons(ITaskbarList4 *iface,
                                                                   HWND hwnd,
                                                                   UINT cButtons,
                                                                   LPTHUMBBUTTON pButton)
{
    FIXME("iface %p, hwnd %p, cButtons %u, pButton %p stub!\n", iface, hwnd, cButtons, pButton);

    return E_NOTIMPL;
}

static HRESULT STDMETHODCALLTYPE taskbar_list_ThumbBarSetImageList(ITaskbarList4 *iface,
                                                                   HWND hwnd,
                                                                   HIMAGELIST himl)
{
    FIXME("iface %p, hwnd %p, himl %p stub!\n", iface, hwnd, himl);

    return E_NOTIMPL;
}

static HRESULT STDMETHODCALLTYPE taskbar_list_SetOverlayIcon(ITaskbarList4 *iface,
                                                             HWND hwnd,
                                                             HICON hIcon,
                                                             LPCWSTR pszDescription)
{
    FIXME("iface %p, hwnd %p, hIcon %p, pszDescription %s stub!\n", iface, hwnd, hIcon,
          debugstr_w(pszDescription));

    return E_NOTIMPL;
}

static HRESULT STDMETHODCALLTYPE taskbar_list_SetThumbnailTooltip(ITaskbarList4 *iface,
                                                                  HWND hwnd,
                                                                  LPCWSTR pszTip)
{
    FIXME("iface %p, hwnd %p, pszTip %s stub!\n", iface, hwnd, debugstr_w(pszTip));

    return E_NOTIMPL;
}

static HRESULT STDMETHODCALLTYPE taskbar_list_SetThumbnailClip(ITaskbarList4 *iface,
                                                               HWND hwnd,
                                                               RECT *prcClip)
{
    FIXME("iface %p, hwnd %p, prcClip %s stub!\n", iface, hwnd, wine_dbgstr_rect(prcClip));

    return E_NOTIMPL;
}

/* ITaskbarList4 method */

static HRESULT STDMETHODCALLTYPE taskbar_list_SetTabProperties(ITaskbarList4 *iface,
                                                               HWND hwndTab,
                                                               STPFLAG stpFlags)
{
    FIXME("iface %p, hwndTab %p, stpFlags %u stub!\n", iface, hwndTab, stpFlags);

    return E_NOTIMPL;
}

static const struct ITaskbarList4Vtbl taskbar_list_vtbl =
{
    /* IUnknown methods */
    taskbar_list_QueryInterface,
    taskbar_list_AddRef,
    taskbar_list_Release,
    /* ITaskbarList methods */
    taskbar_list_HrInit,
    taskbar_list_AddTab,
    taskbar_list_DeleteTab,
    taskbar_list_ActivateTab,
    taskbar_list_SetActiveAlt,
    /* ITaskbarList2 method */
    taskbar_list_MarkFullscreenWindow,
    /* ITaskbarList3 methods */
    taskbar_list_SetProgressValue,
    taskbar_list_SetProgressState,
    taskbar_list_RegisterTab,
    taskbar_list_UnregisterTab,
    taskbar_list_SetTabOrder,
    taskbar_list_SetTabActive,
    taskbar_list_ThumbBarAddButtons,
    taskbar_list_ThumbBarUpdateButtons,
    taskbar_list_ThumbBarSetImageList,
    taskbar_list_SetOverlayIcon,
    taskbar_list_SetThumbnailTooltip,
    taskbar_list_SetThumbnailClip,
    /* ITaskbarList4 method */
    taskbar_list_SetTabProperties,
};

HRESULT WINAPI TaskbarList_Create(IClassFactory *iface, IUnknown *outer, REFIID riid, void **taskbar_list)
{
    struct taskbar_list *object;
    HRESULT hres;

    TRACE("outer %p, riid %s, taskbar_list %p\n", outer, debugstr_guid(riid), taskbar_list);

    if (outer)
    {
        WARN("Aggregation not supported\n");
        *taskbar_list = NULL;
        return CLASS_E_NOAGGREGATION;
    }

    object = heap_alloc_zero(sizeof(*object));
    if (!object)
    {
        ERR("Failed to allocate taskbar list object memory\n");
        *taskbar_list = NULL;
        return E_OUTOFMEMORY;
    }

    object->ITaskbarList4_iface.lpVtbl = &taskbar_list_vtbl;
    object->refcount = 1;
    lock_module();

    TRACE("Created ITaskbarList4 %p\n", object);

    hres = ITaskbarList4_QueryInterface(&object->ITaskbarList4_iface, riid, taskbar_list);
    ITaskbarList4_Release(&object->ITaskbarList4_iface);
    return hres;
}
