/*
 * Copyright 2009 Vincent Povirk for CodeWeavers
 * Copyright 2013 Ludger Sprenker
 *
 * 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 "windef.h"
#include "winbase.h"
#include "objbase.h"
#include "wine/unicode.h"

#include "wincodecs_private.h"

#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(wincodecs);

typedef struct PropertyBag {
    IPropertyBag2 IPropertyBag2_iface;
    LONG ref;
    UINT prop_count;
    PROPBAG2 *properties;
    VARIANT *values;
} PropertyBag;

static inline PropertyBag *impl_from_IPropertyBag2(IPropertyBag2 *iface)
{
    return CONTAINING_RECORD(iface, PropertyBag, IPropertyBag2_iface);
}

static HRESULT WINAPI PropertyBag_QueryInterface(IPropertyBag2 *iface, REFIID iid,
    void **ppv)
{
    PropertyBag *This = impl_from_IPropertyBag2(iface);
    TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);

    if (!ppv) return E_INVALIDARG;

    if (IsEqualIID(&IID_IUnknown, iid) ||
        IsEqualIID(&IID_IPropertyBag2, iid))
    {
        *ppv = &This->IPropertyBag2_iface;
    }
    else
    {
        *ppv = NULL;
        return E_NOINTERFACE;
    }

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

static ULONG WINAPI PropertyBag_AddRef(IPropertyBag2 *iface)
{
    PropertyBag *This = impl_from_IPropertyBag2(iface);
    ULONG ref = InterlockedIncrement(&This->ref);

    TRACE("(%p) refcount=%u\n", iface, ref);

    return ref;
}

static ULONG WINAPI PropertyBag_Release(IPropertyBag2 *iface)
{
    PropertyBag *This = impl_from_IPropertyBag2(iface);
    ULONG ref = InterlockedDecrement(&This->ref);

    TRACE("(%p) refcount=%u\n", iface, ref);

    if (ref == 0)
    {
        ULONG i;
        if (This->properties && This->values)
        {
            for (i=0; i < This->prop_count; i++)
            {
                HeapFree(GetProcessHeap(), 0, This->properties[i].pstrName);
                VariantClear( This->values+i );
            }
        }

        HeapFree(GetProcessHeap(), 0, This->properties);
        HeapFree(GetProcessHeap(), 0, This->values);
        HeapFree(GetProcessHeap(), 0, This);
    }

    return ref;
}

static LONG find_item(PropertyBag *This, LPCOLESTR name)
{
    LONG i;
    if (!This->properties)
        return -1;
    if (!name)
        return -1;

    for (i=0; i < This->prop_count; i++)
    {
        if (strcmpW(name, This->properties[i].pstrName) == 0)
            return i;
    }

    return -1;
}

static HRESULT WINAPI PropertyBag_Read(IPropertyBag2 *iface, ULONG cProperties,
    PROPBAG2 *pPropBag, IErrorLog *pErrLog, VARIANT *pvarValue, HRESULT *phrError)
{
    HRESULT res = S_OK;
    ULONG i;
    PropertyBag *This = impl_from_IPropertyBag2(iface);

    TRACE("(%p,%u,%p,%p,%p,%p)\n", iface, cProperties, pPropBag, pErrLog, pvarValue, phrError);

    for (i=0; i < cProperties; i++)
    {
        LONG idx;
        if (pPropBag[i].dwHint && pPropBag[i].dwHint <= This->prop_count)
            idx = pPropBag[i].dwHint-1;
        else
            idx = find_item(This, pPropBag[i].pstrName);

        if (idx > -1)
        {
            VariantInit(pvarValue+i);
            res = VariantCopy(pvarValue+i, This->values+idx);
            if (FAILED(res))
                break;
            phrError[i] = res;
        }
        else
        {
            res = E_FAIL;
            break;
        }
    }

    return res;
}

static HRESULT WINAPI PropertyBag_Write(IPropertyBag2 *iface, ULONG cProperties,
    PROPBAG2 *pPropBag, VARIANT *pvarValue)
{
    HRESULT res = S_OK;
    ULONG i;
    PropertyBag *This = impl_from_IPropertyBag2(iface);

    TRACE("(%p,%u,%p,%p)\n", iface, cProperties, pPropBag, pvarValue);

    for (i=0; i < cProperties; i++)
    {
        LONG idx;
        if (pPropBag[i].dwHint && pPropBag[i].dwHint <= This->prop_count)
            idx = pPropBag[i].dwHint-1;
        else
            idx = find_item(This, pPropBag[i].pstrName);

        if (idx > -1)
        {
            if (This->properties[idx].vt != V_VT(pvarValue+i))
                return WINCODEC_ERR_PROPERTYUNEXPECTEDTYPE;
            res = VariantCopy(This->values+idx, pvarValue+i);
            if (FAILED(res))
                return E_FAIL;
        }
        else
        {
            if (pPropBag[i].pstrName)
                FIXME("Application tried to set the unknown option %s.\n",
                      debugstr_w(pPropBag[i].pstrName));

            /* FIXME: Function is not atomar on error, but MSDN does not say anything about it
             *        (no reset of items between 0 and i-1) */
            return E_FAIL;
        }
    }

    return res;
}

static HRESULT WINAPI PropertyBag_CountProperties(IPropertyBag2 *iface, ULONG *pcProperties)
{
    PropertyBag *This = impl_from_IPropertyBag2(iface);

    TRACE("(%p,%p)\n", iface, pcProperties);

    if (!pcProperties)
        return E_INVALIDARG;

    *pcProperties = This->prop_count;

    return S_OK;
}

static HRESULT copy_propbag2(PROPBAG2 *dest, PROPBAG2 *src, BOOL useCoAlloc)
{
    dest->cfType = src->cfType;
    dest->clsid = src->clsid;
    dest->dwHint = src->dwHint;
    dest->dwType = src->dwType;
    dest->vt = src->vt;
    if(useCoAlloc)
        dest->pstrName = CoTaskMemAlloc((strlenW(src->pstrName)+1) * sizeof(WCHAR));
    else
        dest->pstrName = HeapAlloc(GetProcessHeap(), 0, (strlenW(src->pstrName)+1) * sizeof(WCHAR));

    if(!dest->pstrName)
        return E_OUTOFMEMORY;

    strcpyW(dest->pstrName, src->pstrName);

    return S_OK;
}

static HRESULT WINAPI PropertyBag_GetPropertyInfo(IPropertyBag2 *iface, ULONG iProperty,
    ULONG cProperties, PROPBAG2 *pPropBag, ULONG *pcProperties)
{
    HRESULT res = S_OK;
    ULONG i;
    PropertyBag *This = impl_from_IPropertyBag2(iface);

    TRACE("(%p,%u,%u,%p,%p)\n", iface, iProperty, cProperties, pPropBag, pcProperties);

    if (iProperty >= This->prop_count && iProperty > 0)
        return WINCODEC_ERR_VALUEOUTOFRANGE;
    if (iProperty+cProperties > This->prop_count )
        return WINCODEC_ERR_VALUEOUTOFRANGE;

    *pcProperties = min(cProperties, This->prop_count-iProperty);

    for (i=0; i < *pcProperties; i++)
    {
        res = copy_propbag2(pPropBag+i, This->properties+iProperty+i, TRUE);
        if (FAILED(res))
        {
            do {
                CoTaskMemFree( pPropBag[--i].pstrName );
            } while (i);
            break;
        }
    }

    return res;
}

static HRESULT WINAPI PropertyBag_LoadObject(IPropertyBag2 *iface, LPCOLESTR pstrName,
    DWORD dwHint, IUnknown *pUnkObject, IErrorLog *pErrLog)
{
    FIXME("(%p,%s,%u,%p,%p): stub\n", iface, debugstr_w(pstrName), dwHint, pUnkObject, pErrLog);
    return E_NOTIMPL;
}

static const IPropertyBag2Vtbl PropertyBag_Vtbl = {
    PropertyBag_QueryInterface,
    PropertyBag_AddRef,
    PropertyBag_Release,
    PropertyBag_Read,
    PropertyBag_Write,
    PropertyBag_CountProperties,
    PropertyBag_GetPropertyInfo,
    PropertyBag_LoadObject
};

HRESULT CreatePropertyBag2(PROPBAG2 *options, UINT count,
                           IPropertyBag2 **ppPropertyBag2)
{
    UINT i;
    HRESULT res = S_OK;
    PropertyBag *This;

    This = HeapAlloc(GetProcessHeap(), 0, sizeof(PropertyBag));
    if (!This) return E_OUTOFMEMORY;

    This->IPropertyBag2_iface.lpVtbl = &PropertyBag_Vtbl;
    This->ref = 1;
    This->prop_count = count;

    if (count == 0)
    {
        This->properties = NULL;
        This->values = NULL;
    }
    else
    {
        This->properties = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(PROPBAG2)*count);
        This->values = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(VARIANT)*count);

        if (!This->properties || !This->values)
            res = E_OUTOFMEMORY;
        else
            for (i=0; i < count; i++)
            {
                res = copy_propbag2(This->properties+i, options+i, FALSE);
                if (FAILED(res))
                    break;
                This->properties[i].dwHint = i+1; /* 0 means unset, so we start with 1 */
            }
    }

    if (FAILED(res))
    {
        PropertyBag_Release(&This->IPropertyBag2_iface);
        *ppPropertyBag2 = NULL;
    }
    else
        *ppPropertyBag2 = &This->IPropertyBag2_iface;

    return res;
}
