/*
 * IAutomaticUpdates implementation
 *
 * Copyright 2008 Hans Leidekker
 *
 * 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 "config.h"
#include <stdarg.h>

#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "ole2.h"
#include "wuapi.h"

#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(wuapi);

typedef struct _automatic_updates
{
    const struct IAutomaticUpdatesVtbl *vtbl;
    LONG refs;
} automatic_updates;

static inline automatic_updates *impl_from_IAutomaticUpdates( IAutomaticUpdates *iface )
{
    return (automatic_updates *)((char*)iface - FIELD_OFFSET( automatic_updates, vtbl ));
}

static ULONG WINAPI automatic_updates_AddRef(
    IAutomaticUpdates *iface )
{
    automatic_updates *automatic_updates = impl_from_IAutomaticUpdates( iface );
    return InterlockedIncrement( &automatic_updates->refs );
}

static ULONG WINAPI automatic_updates_Release(
    IAutomaticUpdates *iface )
{
    automatic_updates *automatic_updates = impl_from_IAutomaticUpdates( iface );
    LONG refs = InterlockedDecrement( &automatic_updates->refs );
    if (!refs)
    {
        TRACE("destroying %p\n", automatic_updates);
        HeapFree( GetProcessHeap(), 0, automatic_updates );
    }
    return refs;
}

static HRESULT WINAPI automatic_updates_QueryInterface(
    IAutomaticUpdates *iface,
    REFIID riid,
    void **ppvObject )
{
    automatic_updates *This = impl_from_IAutomaticUpdates( iface );

    TRACE("%p %s %p\n", This, debugstr_guid( riid ), ppvObject );

    if ( IsEqualGUID( riid, &IID_IAutomaticUpdates ) ||
         IsEqualGUID( riid, &IID_IDispatch ) ||
         IsEqualGUID( riid, &IID_IUnknown ) )
    {
        *ppvObject = iface;
    }
    else
    {
        FIXME("interface %s not implemented\n", debugstr_guid(riid));
        return E_NOINTERFACE;
    }
    IAutomaticUpdates_AddRef( iface );
    return S_OK;
}

static HRESULT WINAPI automatic_updates_GetTypeInfoCount(
    IAutomaticUpdates *iface,
    UINT *pctinfo )
{
    FIXME("\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI automatic_updates_GetTypeInfo(
    IAutomaticUpdates *iface,
    UINT iTInfo,
    LCID lcid,
    ITypeInfo **ppTInfo )
{
    FIXME("\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI automatic_updates_GetIDsOfNames(
    IAutomaticUpdates *iface,
    REFIID riid,
    LPOLESTR *rgszNames,
    UINT cNames,
    LCID lcid,
    DISPID *rgDispId )
{
    FIXME("\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI automatic_updates_Invoke(
    IAutomaticUpdates *iface,
    DISPID dispIdMember,
    REFIID riid,
    LCID lcid,
    WORD wFlags,
    DISPPARAMS *pDispParams,
    VARIANT *pVarResult,
    EXCEPINFO *pExcepInfo,
    UINT *puArgErr )
{
    FIXME("\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI automatic_updates_DetectNow(
    IAutomaticUpdates *This )
{
    FIXME("\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI automatic_updates_Pause(
    IAutomaticUpdates *This )
{
    FIXME("\n");
    return S_OK;
}

static HRESULT WINAPI automatic_updates_Resume(
    IAutomaticUpdates *This )
{
    FIXME("\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI automatic_updates_ShowSettingsDialog(
    IAutomaticUpdates *This )
{
    FIXME("\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI automatic_updates_EnableService(
    IAutomaticUpdates *This )
{
    FIXME("\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI automatic_updates_get_ServiceEnabled(
    IAutomaticUpdates *This,
    VARIANT_BOOL *retval )
{
    FIXME("%p\n", retval);
    return E_NOTIMPL;
}

static HRESULT WINAPI automatic_updates_get_Settings(
    IAutomaticUpdates *This,
    IAutomaticUpdatesSettings **retval )
{
    FIXME("%p\n", retval);
    return E_NOTIMPL;
}

static const struct IAutomaticUpdatesVtbl automatic_updates_vtbl =
{
    automatic_updates_QueryInterface,
    automatic_updates_AddRef,
    automatic_updates_Release,
    automatic_updates_GetTypeInfoCount,
    automatic_updates_GetTypeInfo,
    automatic_updates_GetIDsOfNames,
    automatic_updates_Invoke,
    automatic_updates_DetectNow,
    automatic_updates_Pause,
    automatic_updates_Resume,
    automatic_updates_ShowSettingsDialog,
    automatic_updates_get_Settings,
    automatic_updates_get_ServiceEnabled,
    automatic_updates_EnableService
};

HRESULT AutomaticUpdates_create( IUnknown *pUnkOuter, LPVOID *ppObj )
{
    automatic_updates *updates;

    TRACE("(%p,%p)\n", pUnkOuter, ppObj);

    updates = HeapAlloc( GetProcessHeap(), 0, sizeof(*updates) );
    if (!updates) return E_OUTOFMEMORY;

    updates->vtbl = &automatic_updates_vtbl;
    updates->refs = 1;

    *ppObj = &updates->vtbl;

    TRACE("returning iface %p\n", *ppObj);
    return S_OK;
}
