/*
 * IUpdateInstaller 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 _update_installer
{
    const struct IUpdateInstallerVtbl *vtbl;
    LONG refs;
} update_installer;

static inline update_installer *impl_from_IUpdateInstaller( IUpdateInstaller *iface )
{
    return (update_installer *)((char *)iface - FIELD_OFFSET( update_installer, vtbl ));
}

static ULONG WINAPI update_installer_AddRef(
    IUpdateInstaller *iface )
{
    update_installer *update_installer = impl_from_IUpdateInstaller( iface );
    return InterlockedIncrement( &update_installer->refs );
}

static ULONG WINAPI update_installer_Release(
    IUpdateInstaller *iface )
{
    update_installer *update_installer = impl_from_IUpdateInstaller( iface );
    LONG refs = InterlockedDecrement( &update_installer->refs );
    if (!refs)
    {
        TRACE("destroying %p\n", update_installer);
        HeapFree( GetProcessHeap(), 0, update_installer );
    }
    return refs;
}

static HRESULT WINAPI update_installer_QueryInterface(
    IUpdateInstaller *iface,
    REFIID riid,
    void **ppvObject )
{
    update_installer *This = impl_from_IUpdateInstaller( iface );

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

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

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

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

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

static HRESULT WINAPI update_installer_Invoke(
    IUpdateInstaller *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 update_installer_get_ClientApplicationID(
    IUpdateInstaller *This,
    BSTR *retval )
{
    FIXME("\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI update_installer_put_ClientApplicationID(
    IUpdateInstaller *This,
    BSTR value )
{
    FIXME("%p, %s\n", This, debugstr_w(value));
    return E_NOTIMPL;
}

static HRESULT WINAPI update_installer_get_IsForced(
    IUpdateInstaller *This,
    VARIANT_BOOL *retval )
{
    FIXME("\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI update_installer_put_IsForced(
    IUpdateInstaller *This,
    VARIANT_BOOL value )
{
    FIXME("\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI update_installer_get_ParentHwnd(
    IUpdateInstaller *This,
    HWND *retval )
{
    FIXME("\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI update_installer_put_ParentHwnd(
    IUpdateInstaller *This,
    HWND value )
{
    FIXME("\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI update_installer_put_ParentWindow(
    IUpdateInstaller *This,
    IUnknown *value )
{
    FIXME("\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI update_installer_get_ParentWindow(
    IUpdateInstaller *This,
    IUnknown **retval )
{
    FIXME("\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI update_installer_get_Updates(
    IUpdateInstaller *This,
    IUpdateCollection **retval )
{
    FIXME("\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI update_installer_put_Updates(
    IUpdateInstaller *This,
    IUpdateCollection *value )
{
    FIXME("\n");
    return E_NOTIMPL;
}

static const struct IUpdateInstallerVtbl update_installer_vtbl =
{
    update_installer_QueryInterface,
    update_installer_AddRef,
    update_installer_Release,
    update_installer_GetTypeInfoCount,
    update_installer_GetTypeInfo,
    update_installer_GetIDsOfNames,
    update_installer_Invoke,
    update_installer_get_ClientApplicationID,
    update_installer_put_ClientApplicationID,
    update_installer_get_IsForced,
    update_installer_put_IsForced,
    update_installer_get_ParentHwnd,
    update_installer_put_ParentHwnd,
    update_installer_put_ParentWindow,
    update_installer_get_ParentWindow,
    update_installer_get_Updates,
    update_installer_put_Updates,
};

HRESULT UpdateInstaller_create( IUnknown *pUnkOuter, LPVOID *ppObj )
{
    update_installer *installer;

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

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

    installer->vtbl = &update_installer_vtbl;
    installer->refs = 1;

    *ppObj = &installer->vtbl;

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