/*
 * 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 "wincodec.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 = max(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;
}
