/*
 * 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 "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);
    }
}
