/*
 * Component Category Cache 'Daemon'
 *
 * Copyright (C) 2008 Maarten Lankhorst
 *
 * 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 "config.h"

#include <stdarg.h>

#define COBJMACROS

#include "wine/debug.h"
#include "windef.h"
#include "winbase.h"
#include "winreg.h"
#include "winuser.h"
#include "shlwapi.h"
#include "winerror.h"
#include "objbase.h"

#include "shlguid.h"
#include "shlobj.h"

#include "wine/unicode.h"

#include "browseui.h"
#include "resids.h"

WINE_DEFAULT_DEBUG_CHANNEL(browseui);

typedef struct tagCCCD {
    IRunnableTask IRunnableTask_iface;
    LONG refCount;
    CRITICAL_SECTION cs;
} CompCatCacheDaemon;

static inline CompCatCacheDaemon *impl_from_IRunnableTask(IRunnableTask *iface)
{
    return CONTAINING_RECORD(iface, CompCatCacheDaemon, IRunnableTask_iface);
}

static void CompCatCacheDaemon_Destructor(CompCatCacheDaemon *This)
{
    TRACE("destroying %p\n", This);
    This->cs.DebugInfo->Spare[0] = 0;
    DeleteCriticalSection(&This->cs);
    heap_free(This);
    BROWSEUI_refCount--;
}

static HRESULT WINAPI CompCatCacheDaemon_QueryInterface(IRunnableTask *iface, REFIID iid, LPVOID *ppvOut)
{
    CompCatCacheDaemon *This = impl_from_IRunnableTask(iface);
    *ppvOut = NULL;

    if (IsEqualIID(iid, &IID_IRunnableTask) || IsEqualIID(iid, &IID_IUnknown))
    {
        *ppvOut = This;
    }

    if (*ppvOut)
    {
        IRunnableTask_AddRef(iface);
        return S_OK;
    }

    FIXME("unsupported interface: %s\n", debugstr_guid(iid));
    return E_NOINTERFACE;
}

static ULONG WINAPI CompCatCacheDaemon_AddRef(IRunnableTask *iface)
{
    CompCatCacheDaemon *This = impl_from_IRunnableTask(iface);
    return InterlockedIncrement(&This->refCount);
}

static ULONG WINAPI CompCatCacheDaemon_Release(IRunnableTask *iface)
{
    CompCatCacheDaemon *This = impl_from_IRunnableTask(iface);
    ULONG ret;

    ret = InterlockedDecrement(&This->refCount);
    if (ret == 0)
        CompCatCacheDaemon_Destructor(This);
    return ret;
}

static HRESULT WINAPI CompCatCacheDaemon_Run(IRunnableTask *iface)
{
    FIXME("stub\n");
    return S_OK;
}

static HRESULT WINAPI CompCatCacheDaemon_Kill(IRunnableTask *iface, BOOL fWait)
{
    FIXME("stub\n");
    return S_OK;
}

static HRESULT WINAPI CompCatCacheDaemon_Suspend(IRunnableTask *iface)
{
    FIXME("stub\n");
    return S_OK;
}

static HRESULT WINAPI CompCatCacheDaemon_Resume(IRunnableTask *iface)
{
    FIXME("stub\n");
    return S_OK;
}

static ULONG WINAPI CompCatCacheDaemon_IsRunning(IRunnableTask *iface)
{
    FIXME("stub\n");
    return 0;
}

static const IRunnableTaskVtbl CompCatCacheDaemonVtbl =
{
    CompCatCacheDaemon_QueryInterface,
    CompCatCacheDaemon_AddRef,
    CompCatCacheDaemon_Release,
    CompCatCacheDaemon_Run,
    CompCatCacheDaemon_Kill,
    CompCatCacheDaemon_Suspend,
    CompCatCacheDaemon_Resume,
    CompCatCacheDaemon_IsRunning
};

HRESULT CompCatCacheDaemon_Constructor(IUnknown *pUnkOuter, IUnknown **ppOut)
{
    CompCatCacheDaemon *This;
    if (pUnkOuter)
        return CLASS_E_NOAGGREGATION;

    This = heap_alloc(sizeof(CompCatCacheDaemon));
    if (This == NULL)
        return E_OUTOFMEMORY;

    This->IRunnableTask_iface.lpVtbl = &CompCatCacheDaemonVtbl;
    This->refCount = 1;
    InitializeCriticalSection(&This->cs);
    This->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": CompCatCacheDaemon.cs");

    TRACE("returning %p\n", This);
    *ppOut = (IUnknown *)This;
    BROWSEUI_refCount++;
    return S_OK;
}
