/*
 * IUpdateSearcher 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_searcher
{
    const struct IUpdateSearcherVtbl *vtbl;
    LONG refs;
} update_searcher;

static inline update_searcher *impl_from_IUpdateSearcher( IUpdateSearcher *iface )
{
    return (update_searcher *)((char *)iface - FIELD_OFFSET( update_searcher, vtbl ));
}

static ULONG WINAPI update_searcher_AddRef(
    IUpdateSearcher *iface )
{
    update_searcher *update_searcher = impl_from_IUpdateSearcher( iface );
    return InterlockedIncrement( &update_searcher->refs );
}

static ULONG WINAPI update_searcher_Release(
    IUpdateSearcher *iface )
{
    update_searcher *update_searcher = impl_from_IUpdateSearcher( iface );
    LONG refs = InterlockedDecrement( &update_searcher->refs );
    if (!refs)
    {
        TRACE("destroying %p\n", update_searcher);
        HeapFree( GetProcessHeap(), 0, update_searcher );
    }
    return refs;
}

static HRESULT WINAPI update_searcher_QueryInterface(
    IUpdateSearcher *iface,
    REFIID riid,
    void **ppvObject )
{
    update_searcher *This = impl_from_IUpdateSearcher( iface );

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

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

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

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

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

static HRESULT WINAPI update_searcher_Invoke(
    IUpdateSearcher *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_searcher_get_CanAutomaticallyUpgradeService(
    IUpdateSearcher *This,
    VARIANT_BOOL *retval )
{
    FIXME("\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI update_searcher_put_CanAutomaticallyUpgradeService(
    IUpdateSearcher *This,
    VARIANT_BOOL value )
{
    FIXME("%p, %d\n", This, value);
    return S_OK;
}

static HRESULT WINAPI update_searcher_get_ClientApplicationID(
    IUpdateSearcher *This,
    BSTR *retval )
{
    FIXME("\n");
    return E_NOTIMPL;
}

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

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

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

static HRESULT WINAPI update_searcher_get_ServerSelection(
    IUpdateSearcher *This,
    ServerSelection *retval )
{
    FIXME("\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI update_searcher_put_ServerSelection(
    IUpdateSearcher *This,
    ServerSelection value )
{
    FIXME("\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI update_searcher_BeginSearch(
    IUpdateSearcher *This,
    BSTR criteria,
    IUnknown *onCompleted,
    VARIANT state,
    ISearchJob **retval )
{
    FIXME("\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI update_searcher_EndSearch(
    IUpdateSearcher *This,
    ISearchJob *searchJob,
    ISearchResult **retval )
{
    FIXME("\n");
    return E_NOTIMPL;
}

static const struct IUpdateSearcherVtbl update_searcher_vtbl =
{
    update_searcher_QueryInterface,
    update_searcher_AddRef,
    update_searcher_Release,
    update_searcher_GetTypeInfoCount,
    update_searcher_GetTypeInfo,
    update_searcher_GetIDsOfNames,
    update_searcher_Invoke,
    update_searcher_get_CanAutomaticallyUpgradeService,
    update_searcher_put_CanAutomaticallyUpgradeService,
    update_searcher_get_ClientApplicationID,
    update_searcher_put_ClientApplicationID,
    update_searcher_get_IncludePotentiallySupersededUpdates,
    update_searcher_put_IncludePotentiallySupersededUpdates,
    update_searcher_get_ServerSelection,
    update_searcher_put_ServerSelection,
    update_searcher_BeginSearch,
    update_searcher_EndSearch
};

HRESULT UpdateSearcher_create( IUnknown *pUnkOuter, LPVOID *ppObj )
{
    update_searcher *searcher;

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

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

    searcher->vtbl = &update_searcher_vtbl;
    searcher->refs = 1;

    *ppObj = &searcher->vtbl;

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