/*
 * 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 <stdarg.h>
#include <math.h>

#define COBJMACROS
#define CONST_VTABLE

#include "windef.h"
#include "objbase.h"
#include "wincodec.h"
#include "wincodecsdk.h"
#include "wine/test.h"

static const WCHAR wszTestProperty1[] = {'P','r','o','p','e','r','t','y','1',0};
static const WCHAR wszTestProperty2[] = {'P','r','o','p','e','r','t','y','2',0};
static const WCHAR wszTestInvalidProperty[] = {'I','n','v','a','l','i','d',0};

static void test_propertybag_getpropertyinfo(IPropertyBag2 *property, ULONG expected_count)
{
    HRESULT hr;
    PROPBAG2 pb[2];
    ULONG out_count;

    /* iProperty: Out of bounce */
    hr = IPropertyBag2_GetPropertyInfo(property, expected_count, 1, pb, &out_count);
    ok(hr == WINCODEC_ERR_VALUEOUTOFRANGE,
       "GetPropertyInfo handled iProperty out of bounce wrong, hr=%x\n", hr);

    /* cProperty: Out of bounce */
    hr = IPropertyBag2_GetPropertyInfo(property, 0, expected_count+1, pb, &out_count);
    ok(hr == WINCODEC_ERR_VALUEOUTOFRANGE,
       "GetPropertyInfo handled cProperty out of bounce wrong, hr=%x\n", hr);

    /* GetPropertyInfo can be called for zero items on Windows 8 but not on Windows 7 (wine behaves like Win8) */
    if (expected_count == 0)
        return;

    hr = IPropertyBag2_GetPropertyInfo(property, 0, expected_count, pb, &out_count);
    ok(hr == S_OK, "GetPropertyInfo failed, hr=%x\n", hr);
    if (FAILED(hr))
        return;

    ok(expected_count == out_count,
       "GetPropertyInfo returned unexpected property count, %i != %i)\n",
       expected_count, out_count);

    if(expected_count != 2)
        return;

    ok(pb[0].vt == VT_UI1, "Invalid variant type, pb[0].vt=%x\n", pb[0].vt);
    ok(pb[0].dwType == PROPBAG2_TYPE_DATA, "Invalid variant type, pb[0].dwType=%x\n", pb[0].dwType);
    ok(lstrcmpW(pb[0].pstrName, wszTestProperty1) == 0, "Invalid property name, pb[0].pstrName=%s\n", wine_dbgstr_w(pb[0].pstrName));

    ok(pb[1].vt == VT_R4, "Invalid variant type, pb[1].vt=%x\n", pb[1].vt);
    ok(pb[1].dwType == PROPBAG2_TYPE_DATA, "Invalid variant type, pb[1].dwType=%x\n", pb[1].dwType);
    ok(lstrcmpW(pb[1].pstrName, wszTestProperty2) == 0, "Invalid property name, pb[1].pstrName=%s\n", wine_dbgstr_w(pb[1].pstrName));
}

static void test_propertybag_countproperties(IPropertyBag2 *property, ULONG expected_count)
{
    ULONG count = (ULONG)-1;
    HRESULT hr;

    hr = IPropertyBag2_CountProperties(property, NULL);
    ok(hr == E_INVALIDARG, "CountProperties returned unexpected result, hr=%x\n", hr);

    hr = IPropertyBag2_CountProperties(property, &count);
    ok(hr == S_OK, "CountProperties failed, hr=%x\n", hr);

    if (FAILED(hr))
        return;

    ok(count == expected_count, "CountProperties returned invalid value, count=%i\n", count);
}

static void test_propertybag_read(IPropertyBag2 *property)
{
    HRESULT hr;
    PROPBAG2 options[3] = {{0}};
    VARIANT values[3];
    HRESULT itm_hr[3] = {S_OK, S_OK, S_OK};

    /* 1. One unknown property */
    options[0].pstrName = (LPOLESTR)wszTestInvalidProperty;
    hr = IPropertyBag2_Read(property, 1, options, NULL, values, itm_hr);
    ok(hr == E_FAIL,
       "Read for an unknown property did not fail with expected code, hr=%x\n", hr);

    /* 2. One known property */
    options[0].pstrName = (LPOLESTR)wszTestProperty1;
    itm_hr[0] = E_FAIL;
    hr = IPropertyBag2_Read(property, 1, options, NULL, values, itm_hr);
    ok(hr == S_OK, "Read failed, hr=%x\n", hr);
    if (SUCCEEDED(hr))
    {
        ok(itm_hr[0] == S_OK,
           "Read failed, itm_hr[0]=%x\n", itm_hr[0]);
        ok(V_VT(&values[0]) == VT_UI1,
           "Read failed, V_VT(&values[0])=%x\n", V_VT(&values[0]));
        ok(V_UNION(&values[0], bVal) == 12,
           "Read failed, &values[0]=%i\n", V_UNION(&values[0], bVal));

        VariantClear(&values[0]);
    }

    /* 3. Two known properties */
    options[0].pstrName = (LPOLESTR)wszTestProperty1;
    options[1].pstrName = (LPOLESTR)wszTestProperty2;
    itm_hr[0] = E_FAIL;
    itm_hr[1] = E_FAIL;
    hr = IPropertyBag2_Read(property, 2, options, NULL, values, itm_hr);
    ok(hr == S_OK, "Read failed, hr=%x\n", hr);
    if (SUCCEEDED(hr))
    {
        ok(itm_hr[0] == S_OK, "Read failed, itm_hr[0]=%x\n", itm_hr[0]);
        ok(V_VT(&values[0]) == VT_UI1, "Read failed, V_VT(&values[0])=%x\n", V_VT(&values[0]));
        ok(V_UNION(&values[0], bVal) == 12, "Read failed, &values[0]=%i\n", V_UNION(&values[0], bVal));

        ok(itm_hr[1] == S_OK, "Read failed, itm_hr[1]=%x\n", itm_hr[1]);
        ok(V_VT(&values[1]) == VT_R4, "Read failed, V_VT(&values[1])=%x\n", V_VT(&values[1]));
        ok(V_UNION(&values[1], fltVal) == (float)3.14, "Read failed, &values[1]=%f\n", V_UNION(&values[1], fltVal));

        VariantClear(&values[0]);
        VariantClear(&values[1]);
    }


    /* 4. One unknown property between two valid */

    /* Exotic initializations so we can detect what is unchanged */
    itm_hr[0] = -1; itm_hr[1] = -1; itm_hr[2] = -1;
    V_VT(&values[0]) = VT_NULL;
    V_VT(&values[1]) = VT_NULL;
    V_VT(&values[2]) = VT_NULL;
    V_UNION(&values[0], bVal) = 254;
    V_UNION(&values[1], bVal) = 254;
    V_UNION(&values[2], bVal) = 254;

    options[0].pstrName = (LPOLESTR)wszTestProperty1;
    options[1].pstrName = (LPOLESTR)wszTestInvalidProperty;
    options[2].pstrName = (LPOLESTR)wszTestProperty2;

    hr = IPropertyBag2_Read(property, 3, options, NULL, values, itm_hr);
    ok(hr == E_FAIL, "Read failed, hr=%x\n", hr);
    if (hr == E_FAIL)
    {
        ok(itm_hr[0] == S_OK, "Read error code has unexpected value, itm_hr[0]=%x\n", itm_hr[0]);
        ok(itm_hr[1] == -1,   "Read error code has unexpected value, itm_hr[1]=%x\n", itm_hr[1]);
        ok(itm_hr[2] == -1,   "Read error code has unexpected value, itm_hr[2]=%x\n", itm_hr[2]);

        ok(V_VT(&values[0]) == VT_UI1,  "Read variant has unexpected type, V_VT(&values[0])=%x\n", V_VT(&values[0]));
        ok(V_VT(&values[1]) == VT_NULL, "Read variant has unexpected type, V_VT(&values[1])=%x\n", V_VT(&values[1]));
        ok(V_VT(&values[2]) == VT_NULL, "Read variant has unexpected type, V_VT(&values[2])=%x\n", V_VT(&values[2]));

        ok(V_UNION(&values[0], bVal) == 12,  "Read variant has unexpected value, V_UNION(&values[0])=%i\n", V_UNION(&values[0], bVal));
        ok(V_UNION(&values[1], bVal) == 254, "Read variant has unexpected value, V_UNION(&values[1])=%i\n", V_UNION(&values[1], bVal));
        ok(V_UNION(&values[2], bVal) == 254, "Read variant has unexpected value, V_UNION(&values[2])=%i\n", V_UNION(&values[2], bVal));
    }
}

static void test_propertybag_write(IPropertyBag2 *property)
{
    HRESULT hr;
    PROPBAG2 options[2] = {{0}};
    VARIANT values[2];

    VariantInit(&values[0]);
    VariantInit(&values[1]);

    /* 1. One unknown property */
    options[0].pstrName = (LPOLESTR)wszTestInvalidProperty;
    hr = IPropertyBag2_Write(property, 1, options, values);
    ok(hr == E_FAIL, "Write for an unknown property did not fail with expected code, hr=%x\n", hr);

    /* 2. One property without correct type */
    options[0].pstrName = (LPOLESTR)wszTestProperty1;
    V_VT(&values[0]) = VT_UI1;
    V_UNION(&values[0], bVal) = 1;
    hr = IPropertyBag2_Write(property, 1, options, values);
    ok(hr == S_OK, "Write for one property failed, hr=%x\n", hr);

    /* 3. One property with mismatching type */
    options[0].pstrName = (LPOLESTR)wszTestProperty1;
    V_VT(&values[0]) = VT_I1;
    V_UNION(&values[0], bVal) = 2;
    hr = IPropertyBag2_Write(property, 1, options, values);
    ok(hr == WINCODEC_ERR_PROPERTYUNEXPECTEDTYPE,
       "Write with mismatching type did not fail with expected code hr=%x\n", hr);

    /* 4. Reset one property to empty */
    options[0].pstrName = (LPOLESTR)wszTestProperty1;
    VariantClear(&values[0]);
    hr = IPropertyBag2_Write(property, 1, options, values);
    ok(hr == WINCODEC_ERR_PROPERTYUNEXPECTEDTYPE,
       "Write to reset to empty value does not fail with expected code, hr=%x\n", hr);

    /* 5. Set two properties */
    options[0].pstrName = (LPOLESTR)wszTestProperty1;
    V_VT(&values[0]) = VT_UI1;
    V_UNION(&values[0], bVal) = 12;
    options[1].pstrName = (LPOLESTR)wszTestProperty2;
    V_VT(&values[1]) = VT_R4;
    V_UNION(&values[1], fltVal) = (float)3.14;
    hr = IPropertyBag2_Write(property, 2, options, values);
    ok(hr == S_OK, "Write for two properties failed, hr=%x\n", hr);
}

static void test_empty_propertybag(void)
{
    HRESULT hr;
    IWICComponentFactory *factory;
    IPropertyBag2 *property;

    hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER,
                          &IID_IWICComponentFactory, (void**)&factory);
    ok(hr == S_OK, "CoCreateInstance failed, hr=%x\n", hr);

    hr = IWICComponentFactory_CreateEncoderPropertyBag(factory, NULL, 0, &property);

    ok(hr == S_OK, "Creating EncoderPropertyBag failed, hr=%x\n", hr);
    if (FAILED(hr)) return;

    test_propertybag_countproperties(property, 0);

    test_propertybag_getpropertyinfo(property, 0);

    IPropertyBag2_Release(property);

    IWICComponentFactory_Release(factory);
}

static void test_filled_propertybag(void)
{
    HRESULT hr;
    IWICComponentFactory *factory;
    IPropertyBag2 *property;
    PROPBAG2 opts[2]= {
        {.pstrName = (LPOLESTR)wszTestProperty1, .vt=VT_UI1, .dwType=PROPBAG2_TYPE_DATA},
        {.pstrName = (LPOLESTR)wszTestProperty2, .vt=VT_R4,  .dwType=PROPBAG2_TYPE_DATA}
    };

    hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER,
                          &IID_IWICComponentFactory, (void**)&factory);
    ok(hr == S_OK, "CoCreateInstance failed, hr=%x\n", hr);

    hr = IWICComponentFactory_CreateEncoderPropertyBag(factory, opts, 2, &property);

    ok(hr == S_OK, "Creating EncoderPropertyBag failed, hr=%x\n", hr);
    if (FAILED(hr)) return;

    test_propertybag_countproperties(property, 2);

    test_propertybag_getpropertyinfo(property, 2);

    test_propertybag_write(property);

    test_propertybag_read(property);

    IPropertyBag2_Release(property);

    IWICComponentFactory_Release(factory);
}

START_TEST(propertybag)
{
    CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);

    test_empty_propertybag();

    test_filled_propertybag();

    CoUninitialize();
}
