/*
 * Copyright (C) 2002 Aric Stewart for CodeWeavers
 * Copyright (C) 2009 Damjan Jovanovic
 *
 * 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 <stdarg.h>

#define COBJMACROS

#include "windef.h"
#include "winbase.h"
#include "winreg.h"
#include "winerror.h"
#include "objbase.h"
#include "sti.h"

#include "sti_private.h"

#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(sti);

static inline stillimage *impl_from_StillImageW(IStillImageW *iface)
{
    return (stillimage *)((char*)iface - FIELD_OFFSET(stillimage, lpVtbl));
}

static HRESULT WINAPI stillimagew_QueryInterface(IStillImageW *iface, REFIID riid, void **ppvObject)
{
    stillimage *This = impl_from_StillImageW(iface);
    TRACE("(%p %s %p)\n", This, debugstr_guid(riid), ppvObject);
    return IUnknown_QueryInterface(This->pUnkOuter, riid, ppvObject);
}

static ULONG WINAPI stillimagew_AddRef(IStillImageW *iface)
{
    stillimage *This = impl_from_StillImageW(iface);
    return IUnknown_AddRef(This->pUnkOuter);
}

static ULONG WINAPI stillimagew_Release(IStillImageW *iface)
{
    stillimage *This = impl_from_StillImageW(iface);
    return IUnknown_Release(This->pUnkOuter);
}

static HRESULT WINAPI stillimagew_Initialize(IStillImageW *iface, HINSTANCE hinst, DWORD dwVersion)
{
    stillimage *This = impl_from_StillImageW(iface);
    TRACE("(%p, %p, 0x%X)\n", This, hinst, dwVersion);
    return S_OK;
}

static HRESULT WINAPI stillimagew_GetDeviceList(IStillImageW *iface, DWORD dwType, DWORD dwFlags,
                                                DWORD *pdwItemsReturned, LPVOID *ppBuffer)
{
    stillimage *This = impl_from_StillImageW(iface);
    FIXME("(%p, %u, 0x%X, %p, %p): stub\n", This, dwType, dwFlags, pdwItemsReturned, ppBuffer);
    return E_NOTIMPL;
}

static HRESULT WINAPI stillimagew_GetDeviceInfo(IStillImageW *iface, LPWSTR pwszDeviceName,
                                                LPVOID *ppBuffer)
{
    stillimage *This = impl_from_StillImageW(iface);
    FIXME("(%p, %s, %p): stub\n", This, debugstr_w(pwszDeviceName), ppBuffer);
    return E_NOTIMPL;
}

static HRESULT WINAPI stillimagew_CreateDevice(IStillImageW *iface, LPWSTR pwszDeviceName, DWORD dwMode,
                                               PSTIDEVICEW *pDevice, LPUNKNOWN pUnkOuter)
{
    stillimage *This = impl_from_StillImageW(iface);
    FIXME("(%p, %s, %u, %p, %p): stub\n", This, debugstr_w(pwszDeviceName), dwMode, pDevice, pUnkOuter);
    return E_NOTIMPL;
}

static HRESULT WINAPI stillimagew_GetDeviceValue(IStillImageW *iface, LPWSTR pwszDeviceName, LPWSTR pValueName,
                                                 LPDWORD pType, LPBYTE pData, LPDWORD cbData)
{
    stillimage *This = impl_from_StillImageW(iface);
    FIXME("(%p, %s, %s, %p, %p, %p): stub\n", This, debugstr_w(pwszDeviceName), debugstr_w(pValueName),
        pType, pData, cbData);
    return E_NOTIMPL;
}

static HRESULT WINAPI stillimagew_SetDeviceValue(IStillImageW *iface, LPWSTR pwszDeviceName, LPWSTR pValueName,
                                                 DWORD type, LPBYTE pData, DWORD cbData)
{
    stillimage *This = impl_from_StillImageW(iface);
    FIXME("(%p, %s, %s, %u, %p, %u): stub\n", This, debugstr_w(pwszDeviceName), debugstr_w(pValueName),
        type, pData, cbData);
    return E_NOTIMPL;
}

static HRESULT WINAPI stillimagew_GetSTILaunchInformation(IStillImageW *iface, LPWSTR pwszDeviceName,
                                                          DWORD *pdwEventCode, LPWSTR pwszEventName)
{
    stillimage *This = impl_from_StillImageW(iface);
    FIXME("(%p, %p, %p, %p): stub\n", This, pwszDeviceName,
        pdwEventCode, pwszEventName);
    return E_NOTIMPL;
}

static HRESULT WINAPI stillimagew_RegisterLaunchApplication(IStillImageW *iface, LPWSTR pwszAppName,
                                                            LPWSTR pwszCommandLine)
{
    stillimage *This = impl_from_StillImageW(iface);
    FIXME("(%p, %s, %s): stub\n", This, debugstr_w(pwszAppName), debugstr_w(pwszCommandLine));
    return E_NOTIMPL;
}

static HRESULT WINAPI stillimagew_UnregisterLaunchApplication(IStillImageW *iface, LPWSTR pwszAppName)
{
    stillimage *This = impl_from_StillImageW(iface);
    FIXME("(%p, %s): stub\n", This, debugstr_w(pwszAppName));
    return E_NOTIMPL;
}

static HRESULT WINAPI stillimagew_EnableHwNotifications(IStillImageW *iface, LPCWSTR pwszDeviceName,
                                                        BOOL bNewState)
{
    stillimage *This = impl_from_StillImageW(iface);
    FIXME("(%p, %s, %u): stub\n", This, debugstr_w(pwszDeviceName), bNewState);
    return E_NOTIMPL;
}

static HRESULT WINAPI stillimagew_GetHwNotificationState(IStillImageW *iface, LPCWSTR pwszDeviceName,
                                                         BOOL *pbCurrentState)
{
    stillimage *This = impl_from_StillImageW(iface);
    FIXME("(%p, %s, %p): stub\n", This, debugstr_w(pwszDeviceName), pbCurrentState);
    return E_NOTIMPL;
}

static HRESULT WINAPI stillimagew_RefreshDeviceBus(IStillImageW *iface, LPCWSTR pwszDeviceName)
{
    stillimage *This = impl_from_StillImageW(iface);
    FIXME("(%p, %s): stub\n", This, debugstr_w(pwszDeviceName));
    return E_NOTIMPL;
}

static HRESULT WINAPI stillimagew_LaunchApplicationForDevice(IStillImageW *iface, LPWSTR pwszDeviceName,
                                                             LPWSTR pwszAppName, LPSTINOTIFY pStiNotify)
{
    stillimage *This = impl_from_StillImageW(iface);
    FIXME("(%p, %s, %s, %p): stub\n", This, debugstr_w(pwszDeviceName), debugstr_w(pwszAppName),
        pStiNotify);
    return E_NOTIMPL;
}

static HRESULT WINAPI stillimagew_SetupDeviceParameters(IStillImageW *iface, PSTI_DEVICE_INFORMATIONW pDevInfo)
{
    stillimage *This = impl_from_StillImageW(iface);
    FIXME("(%p, %p): stub\n", This, pDevInfo);
    return E_NOTIMPL;
}

static HRESULT WINAPI stillimagew_WriteToErrorLog(IStillImageW *iface, DWORD dwMessageType, LPCWSTR pszMessage)
{
    stillimage *This = impl_from_StillImageW(iface);
    FIXME("(%p, %u, %s): stub\n", This, dwMessageType, debugstr_w(pszMessage));
    return E_NOTIMPL;
}

static const struct IStillImageWVtbl stillimagew_vtbl =
{
    stillimagew_QueryInterface,
    stillimagew_AddRef,
    stillimagew_Release,
    stillimagew_Initialize,
    stillimagew_GetDeviceList,
    stillimagew_GetDeviceInfo,
    stillimagew_CreateDevice,
    stillimagew_GetDeviceValue,
    stillimagew_SetDeviceValue,
    stillimagew_GetSTILaunchInformation,
    stillimagew_RegisterLaunchApplication,
    stillimagew_UnregisterLaunchApplication,
    stillimagew_EnableHwNotifications,
    stillimagew_GetHwNotificationState,
    stillimagew_RefreshDeviceBus,
    stillimagew_LaunchApplicationForDevice,
    stillimagew_SetupDeviceParameters,
    stillimagew_WriteToErrorLog
};

static inline stillimage *impl_from_InternalUnknown(IUnknown *iface)
{
    return (stillimage *)((char*)iface - FIELD_OFFSET(stillimage, lpInternalUnkVtbl));
}

static HRESULT WINAPI Internal_QueryInterface(IUnknown *iface, REFIID riid, void **ppvObject)
{
    stillimage *This = impl_from_InternalUnknown(iface);

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

    if (IsEqualGUID(riid, &IID_IUnknown))
        *ppvObject = iface;
    else if (IsEqualGUID(riid, &IID_IStillImageW))
        *ppvObject = &This->lpVtbl;
    else
    {
        if (IsEqualGUID(riid, &IID_IStillImageA))
            FIXME("interface IStillImageA is unsupported on Windows Vista too, please report if it's needed\n");
        else
            FIXME("interface %s not implemented\n", debugstr_guid(riid));
        *ppvObject = NULL;
        return E_NOINTERFACE;
    }

    IUnknown_AddRef((IUnknown*) *ppvObject);
    return S_OK;
}

static ULONG WINAPI Internal_AddRef(IUnknown *iface)
{
    stillimage *This = impl_from_InternalUnknown(iface);
    return InterlockedIncrement(&This->ref);
}

static ULONG WINAPI Internal_Release(IUnknown *iface)
{
    ULONG ref;
    stillimage *This = impl_from_InternalUnknown(iface);

    ref = InterlockedDecrement(&This->ref);
    if (ref == 0)
        HeapFree(GetProcessHeap(), 0, This);
    return ref;
}

static const struct IUnknownVtbl internal_unk_vtbl =
{
    Internal_QueryInterface,
    Internal_AddRef,
    Internal_Release
};

/******************************************************************************
 *           StiCreateInstanceA   (STI.@)
 */
HRESULT WINAPI StiCreateInstanceA(HINSTANCE hinst, DWORD dwVer, PSTIA *ppSti, LPUNKNOWN pUnkOuter)
{
    FIXME("(%p, %u, %p, %p): stub, unimplemented on Windows Vista too, please report if it's needed\n", hinst, dwVer, ppSti, pUnkOuter);
    return STG_E_UNIMPLEMENTEDFUNCTION;
}

/******************************************************************************
 *           StiCreateInstanceW   (STI.@)
 */
HRESULT WINAPI StiCreateInstanceW(HINSTANCE hinst, DWORD dwVer, PSTIW *ppSti, LPUNKNOWN pUnkOuter)
{
    stillimage *This;
    HRESULT hr;

    TRACE("(%p, %u, %p, %p)\n", hinst, dwVer, ppSti, pUnkOuter);

    This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(stillimage));
    if (This)
    {
        This->lpVtbl = &stillimagew_vtbl;
        This->lpInternalUnkVtbl = &internal_unk_vtbl;
        if (pUnkOuter)
            This->pUnkOuter = pUnkOuter;
        else
            This->pUnkOuter = (IUnknown*) &This->lpInternalUnkVtbl;
        This->ref = 1;

        hr = IStillImage_Initialize((IStillImageW*) &This->lpVtbl, hinst, dwVer);
        if (SUCCEEDED(hr))
        {
            if (pUnkOuter)
                *ppSti = (IStillImageW*) &This->lpInternalUnkVtbl;
            else
                *ppSti = (IStillImageW*) &This->lpVtbl;
        }
    }
    else
        hr = E_OUTOFMEMORY;

    return hr;
}
