/*
 * Unit tests for ddrawex specific things
 *
 * 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 <assert.h>
#include "wine/test.h"
#include "windef.h"
#include "winbase.h"
#include "ddraw.h"
#include "ddrawex.h"
#include "unknwn.h"

static IDirectDrawFactory *factory;
static HRESULT (WINAPI *pDllGetClassObject)(REFCLSID rclsid, REFIID riid, LPVOID *ppv);

static IDirectDraw *createDD(void)
{
    HRESULT hr;
    IDirectDraw *dd;

    hr = IDirectDrawFactory_CreateDirectDraw(factory, NULL, NULL, DDSCL_NORMAL, 0,
                                             0, &dd);
    ok(hr == DD_OK, "Failed to create an IDirectDraw interface, hr = 0x%08x\n", hr);
    return SUCCEEDED(hr) ? dd : NULL;
}

static ULONG get_ref(IUnknown *o)
{
    IUnknown_AddRef(o);
    return IUnknown_Release(o);
}

static void RefCountTest(void)
{
    IDirectDraw *dd1 = createDD();
    IDirectDraw2 *dd2;
    IDirectDraw3 *dd3;
    IDirectDraw4 *dd4;
    ULONG ref;

    ref = get_ref((IUnknown *) dd1);
    ok(ref == 1, "A new ddraw object's refcount is %u, expected 1\n", ref);

    IDirectDraw_AddRef(dd1);
    ref = get_ref((IUnknown *) dd1);
    if (ref == 1)
    {
        win_skip("Refcounting is broken\n");
        IDirectDraw_Release(dd1);
        return;
    }
    ok(ref == 2, "After AddRef the refcount is %u, expected 2\n", ref);
    IDirectDraw_Release(dd1);
    ref = get_ref((IUnknown *) dd1);
    ok(ref == 1, "After Release the refcount is %u, expected 1\n", ref);

    IDirectDraw_QueryInterface(dd1, &IID_IDirectDraw2, (void **) &dd2);
    ref = get_ref((IUnknown *) dd2);
    ok(ref == 2, "IDirectDraw2 refcount is %u, expected 2\n", ref);

    IDirectDraw_QueryInterface(dd1, &IID_IDirectDraw3, (void **) &dd3);
    ref = get_ref((IUnknown *) dd3);
    ok(ref == 3, "IDirectDraw3 refcount is %u, expected 3\n", ref);

    IDirectDraw_QueryInterface(dd1, &IID_IDirectDraw4, (void **) &dd4);
    ref = get_ref((IUnknown *) dd4);
    ok(ref == 4, "IDirectDraw4 refcount is %u, expected 4\n", ref);

    IDirectDraw_Release(dd1);
    IDirectDraw2_Release(dd2);
    IDirectDraw3_Release(dd3);

    ref = get_ref((IUnknown *) dd4);
    ok(ref == 1, "IDirectDraw4 refcount is %u, expected 1\n", ref);

    IDirectDraw4_Release(dd4);
}

START_TEST(ddrawex)
{
    IClassFactory *classfactory = NULL;
    ULONG ref;
    HRESULT hr;
    HMODULE hmod = LoadLibrary("ddrawex.dll");
    if(hmod == NULL) {
        skip("Failed to load ddrawex.dll\n");
        return;
    }
    pDllGetClassObject = (void*)GetProcAddress(hmod, "DllGetClassObject");
    if(pDllGetClassObject == NULL) {
        skip("Failed to get DllGetClassObject\n");
        return;
    }

    hr = pDllGetClassObject(&CLSID_DirectDrawFactory, &IID_IClassFactory, (void **) &classfactory);
    ok(hr == S_OK, "Failed to create a IClassFactory\n");
    hr = IClassFactory_CreateInstance(classfactory, NULL, &IID_IDirectDrawFactory, (void **) &factory);
    ok(hr == S_OK, "Failed to create a IDirectDrawFactory\n");

    RefCountTest();

    if(factory) {
        ref = IDirectDrawFactory_Release(factory);
        ok(ref == 0, "IDirectDrawFactory not cleanly released\n");
    }
    if(classfactory) {
        ref = IClassFactory_Release(classfactory);
        todo_wine ok(ref == 1, "IClassFactory refcount wrong, ref = %u\n", ref);
    }
}
