/*
 * Copyright 2000 Marcus Meissner
 * Copyright 2000 Peter Hunnisett
 *
 * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include "config.h"

#include <assert.h>
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#include <fcntl.h>
#include <string.h>
#include <stdio.h>

#include "d3d.h"
#include "ddraw.h"
#include "winerror.h"

#include "ddraw_private.h"
#include "mesa_private.h"

#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(ddraw);

/*******************************************************************************
 *				IDirect3D
 */
static HRESULT WINAPI MESA_IDirect3DImpl_QueryInterface(
    LPDIRECT3D iface,REFIID refiid,LPVOID *obj
) {
    ICOM_THIS(IDirect3DImpl,iface);
    /* FIXME: Not sure if this is correct */

    TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(refiid),obj);
    if (( IsEqualGUID( &IID_IDirectDraw,  refiid ) ) ||
	( IsEqualGUID (&IID_IDirectDraw2, refiid ) ) ||
	( IsEqualGUID( &IID_IDirectDraw4, refiid ) )
    ) {
	*obj = This->ddraw;
	IDirect3D_AddRef(iface);
	TRACE("  Creating IDirectDrawX interface (%p)\n", *obj);
	return S_OK;
    }
    if (( IsEqualGUID( &IID_IDirect3D, refiid ) ) ||
	( IsEqualGUID( &IID_IUnknown,  refiid ) ) ) {
	*obj = This;
	IDirect3D_AddRef(iface);
	TRACE("  Creating IDirect3D interface (%p)\n", *obj);
	return S_OK;
    }
    if ( IsEqualGUID( &IID_IDirect3D2, refiid ) ) {
	IDirect3D2Impl*  d3d;

	d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
	d3d->ref = 1;
	d3d->ddraw = This->ddraw;
	IDirect3D_AddRef(iface);
	ICOM_VTBL(d3d) = &mesa_d3d2vt;
	*obj = d3d;
	TRACE("  Creating IDirect3D2 interface (%p)\n", *obj);
	return S_OK;
    }
    FIXME("(%p):interface for IID %s NOT found!\n",This,debugstr_guid(refiid));
    return OLE_E_ENUM_NOMORE;
}

static ULONG WINAPI MESA_IDirect3DImpl_Release(LPDIRECT3D iface)
{
    ICOM_THIS(IDirect3DImpl,iface);
    TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );

    if (!--(This->ref)) {
	IDirectDraw2_Release((IDirectDraw2*)This->ddraw);
	HeapFree(GetProcessHeap(),0,This);
	return S_OK;
    }
    return This->ref;
}

static HRESULT WINAPI MESA_IDirect3DImpl_EnumDevices(
    LPDIRECT3D iface, LPD3DENUMDEVICESCALLBACK cb, LPVOID context
) {
    ICOM_THIS(IDirect3DImpl,iface);
    FIXME("(%p)->(%p,%p),stub!\n",This,cb,context);

    /* Call functions defined in d3ddevices.c */
    if (!d3d_OpenGL_dx3(cb, context))
	return D3D_OK;

    return D3D_OK;
}

static HRESULT WINAPI MESA_IDirect3DImpl_CreateLight(
    LPDIRECT3D iface, LPDIRECT3DLIGHT *lplight, IUnknown *lpunk
) {
    ICOM_THIS(IDirect3DImpl,iface);
    TRACE("(%p)->(%p,%p): stub\n", This, lplight, lpunk);

    /* Call the creation function that is located in d3dlight.c */
    *lplight = d3dlight_create_dx3(This);

    return D3D_OK;
}

static HRESULT WINAPI MESA_IDirect3DImpl_CreateMaterial(
    LPDIRECT3D iface, LPDIRECT3DMATERIAL *lpmaterial, IUnknown *lpunk
) {
    ICOM_THIS(IDirect3DImpl,iface);
    TRACE("(%p)->(%p,%p): stub\n", This, lpmaterial, lpunk);
    /* Call the creation function that is located in d3dviewport.c */
    *lpmaterial = d3dmaterial_create(This);
    return D3D_OK;
}

static HRESULT WINAPI MESA_IDirect3DImpl_CreateViewport(
    LPDIRECT3D iface, LPDIRECT3DVIEWPORT *lpviewport, IUnknown *lpunk
) {
    ICOM_THIS(IDirect3DImpl,iface);
    TRACE("(%p)->(%p,%p): stub\n", This, lpviewport, lpunk);

    /* Call the creation function that is located in d3dviewport.c */
    *lpviewport = d3dviewport_create(This);

    return D3D_OK;
}

static HRESULT WINAPI MESA_IDirect3DImpl_FindDevice(
    LPDIRECT3D iface, LPD3DFINDDEVICESEARCH lpfinddevsrc,
    LPD3DFINDDEVICERESULT lpfinddevrst)
{
    ICOM_THIS(IDirect3DImpl,iface);
    FIXME("(%p)->(%p,%p): stub\n", This, lpfinddevsrc, lpfinddevrst);

    return D3D_OK;
}

ICOM_VTABLE(IDirect3D) mesa_d3dvt =
{
    ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
    MESA_IDirect3DImpl_QueryInterface,
    IDirect3DImpl_AddRef,
    MESA_IDirect3DImpl_Release,
    IDirect3DImpl_Initialize,
    MESA_IDirect3DImpl_EnumDevices,
    MESA_IDirect3DImpl_CreateLight,
    MESA_IDirect3DImpl_CreateMaterial,
    MESA_IDirect3DImpl_CreateViewport,
    MESA_IDirect3DImpl_FindDevice
};

/*******************************************************************************
 *				IDirect3D2
 */
static HRESULT WINAPI MESA_IDirect3D2Impl_QueryInterface(
    LPDIRECT3D2 iface,REFIID refiid,LPVOID *obj) {
    ICOM_THIS(IDirect3D2Impl,iface);

    /* FIXME: Not sure if this is correct */

    TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(refiid),obj);
    if ( ( IsEqualGUID( &IID_IDirectDraw,  refiid ) ) ||
	 ( IsEqualGUID( &IID_IDirectDraw2, refiid ) ) ||
	 ( IsEqualGUID( &IID_IDirectDraw4, refiid ) ) ) {
	*obj = This->ddraw;
	IDirect3D2_AddRef(iface);

	TRACE("  Creating IDirectDrawX interface (%p)\n", *obj);

	return S_OK;
    }
    if ( ( IsEqualGUID( &IID_IDirect3D2, refiid ) ) ||
	 ( IsEqualGUID( &IID_IUnknown,   refiid ) ) ) {
	*obj = This;
	IDirect3D2_AddRef(iface);

	TRACE("  Creating IDirect3D2 interface (%p)\n", *obj);

	return S_OK;
    }
    if ( IsEqualGUID( &IID_IDirect3D, refiid ) ) {
	IDirect3DImpl*  d3d;

	d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
	d3d->ref = 1;
	d3d->ddraw = This->ddraw;
	IDirect3D2_AddRef(iface);
	ICOM_VTBL(d3d) = &mesa_d3dvt;
	*obj = d3d;
	TRACE("  Creating IDirect3D interface (%p)\n", *obj);
	return S_OK;
    }
    FIXME("(%p):interface for IID %s NOT found!\n",This,debugstr_guid(refiid));
    return OLE_E_ENUM_NOMORE;
}

static ULONG WINAPI MESA_IDirect3D2Impl_Release(LPDIRECT3D2 iface) {
    ICOM_THIS(IDirect3D2Impl,iface);
    TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );

    if (!--(This->ref)) {
	IDirectDraw2_Release((IDirectDraw2*)This->ddraw);
	HeapFree(GetProcessHeap(),0,This);
	return S_OK;
    }
    return This->ref;
}

static HRESULT WINAPI MESA_IDirect3D2Impl_EnumDevices(
    LPDIRECT3D2 iface,LPD3DENUMDEVICESCALLBACK cb, LPVOID context
) {
    ICOM_THIS(IDirect3D2Impl,iface);
    FIXME("(%p)->(%p,%p),stub!\n",This,cb,context);

    /* Call functions defined in d3ddevices.c */
    if (!d3d_OpenGL(cb, context))
	return D3D_OK;
    return D3D_OK;
}

static HRESULT WINAPI MESA_IDirect3D2Impl_CreateLight(
    LPDIRECT3D2 iface, LPDIRECT3DLIGHT *lplight, IUnknown *lpunk
) {
    ICOM_THIS(IDirect3D2Impl,iface);
    TRACE("(%p)->(%p,%p): stub\n", This, lplight, lpunk);

    /* Call the creation function that is located in d3dlight.c */
    *lplight = d3dlight_create(This);

    return D3D_OK;
}

static HRESULT WINAPI MESA_IDirect3D2Impl_CreateMaterial(
    LPDIRECT3D2 iface, LPDIRECT3DMATERIAL2 *lpmaterial, IUnknown *lpunk
) {
    ICOM_THIS(IDirect3D2Impl,iface);
    TRACE("(%p)->(%p,%p): stub\n", This, lpmaterial, lpunk);

    /* Call the creation function that is located in d3dviewport.c */
    *lpmaterial = d3dmaterial2_create(This);

    return D3D_OK;
}

static HRESULT WINAPI MESA_IDirect3D2Impl_CreateViewport(
    LPDIRECT3D2 iface, LPDIRECT3DVIEWPORT2 *lpviewport, IUnknown *lpunk
) {
    ICOM_THIS(IDirect3D2Impl,iface);
    TRACE("(%p)->(%p,%p): stub\n", This, lpviewport, lpunk);

    /* Call the creation function that is located in d3dviewport.c */
    *lpviewport = d3dviewport2_create(This);

    return D3D_OK;
}

static HRESULT WINAPI MESA_IDirect3D2Impl_FindDevice(
    LPDIRECT3D2 iface, LPD3DFINDDEVICESEARCH lpfinddevsrc,
    LPD3DFINDDEVICERESULT lpfinddevrst)
{
    ICOM_THIS(IDirect3D2Impl,iface);
    FIXME("(%p)->(%p,%p): stub\n", This, lpfinddevsrc, lpfinddevrst);
    return D3D_OK;
}

static HRESULT WINAPI MESA_IDirect3D2Impl_CreateDevice(
    LPDIRECT3D2 iface, REFCLSID rguid, LPDIRECTDRAWSURFACE surface,
    LPDIRECT3DDEVICE2 *device)
{
    ICOM_THIS(IDirect3D2Impl,iface);

    FIXME("(%p)->(%s,%p,%p): stub\n",This,debugstr_guid(rguid),surface,device);

    if (is_OpenGL(rguid, (IDirectDrawSurfaceImpl*)surface, (IDirect3DDevice2Impl**)device, This)) {
	IDirect3D2_AddRef(iface);
	return D3D_OK;
    }

    return DDERR_INVALIDPARAMS;
}

ICOM_VTABLE(IDirect3D2) mesa_d3d2vt =
{
    ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
    MESA_IDirect3D2Impl_QueryInterface,
    IDirect3D2Impl_AddRef,
    MESA_IDirect3D2Impl_Release,
    MESA_IDirect3D2Impl_EnumDevices,
    MESA_IDirect3D2Impl_CreateLight,
    MESA_IDirect3D2Impl_CreateMaterial,
    MESA_IDirect3D2Impl_CreateViewport,
    MESA_IDirect3D2Impl_FindDevice,
    MESA_IDirect3D2Impl_CreateDevice
};

static HRESULT WINAPI MESA_IDirect3D3Impl_CreateVertexBuffer(
    LPDIRECT3D3 iface,
    LPD3DVERTEXBUFFERDESC lpD3DVertBufDesc,
    LPDIRECT3DVERTEXBUFFER* lplpD3DVertBuf,
    DWORD dwFlags,
    LPUNKNOWN lpUnk)
{
  FIXME(":stub\n");
  return D3D_OK;
}

static HRESULT WINAPI MESA_IDirect3D3Impl_EnumZBufferFormats(
    LPDIRECT3D3 iface,
    REFCLSID riidDevice,
    LPD3DENUMPIXELFORMATSCALLBACK lpEnumCallback,
    LPVOID lpContext)
{
  FIXME(":stub\n");
  return DDERR_NOZBUFFERHW; /* Pretend we don't have valid HW */
}

static HRESULT WINAPI MESA_IDirect3D3Impl_EvictManagedTextures(
    LPDIRECT3D3 iface)
{
  FIXME(":stub\n");
  return D3D_OK;
}


#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
# define XCAST(fun)	(typeof(mesa_d3d3vt.fun))
#else
# define XCAST(fun)	(void*)
#endif

ICOM_VTABLE(IDirect3D3) mesa_d3d3vt =
{
    ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
    XCAST(QueryInterface)MESA_IDirect3D2Impl_QueryInterface,
    XCAST(AddRef)IDirect3D2Impl_AddRef,
    XCAST(Release)MESA_IDirect3D2Impl_Release,
    XCAST(EnumDevices)MESA_IDirect3D2Impl_EnumDevices,
    XCAST(CreateLight)MESA_IDirect3D2Impl_CreateLight,
    XCAST(CreateMaterial)MESA_IDirect3D2Impl_CreateMaterial,
    XCAST(CreateViewport)MESA_IDirect3D2Impl_CreateViewport,
    XCAST(FindDevice)MESA_IDirect3D2Impl_FindDevice,
    XCAST(CreateDevice)MESA_IDirect3D2Impl_CreateDevice,
    XCAST(CreateVertexBuffer)MESA_IDirect3D3Impl_CreateVertexBuffer,
    XCAST(EnumZBufferFormats)MESA_IDirect3D3Impl_EnumZBufferFormats,
    XCAST(EvictManagedTextures)MESA_IDirect3D3Impl_EvictManagedTextures
};

#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
#undef XCAST
#endif

HRESULT create_direct3d(LPVOID *obj,IDirectDrawImpl* ddraw) {
    IDirect3DImpl* d3d;

    d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
    d3d->ref = 1;
    d3d->ddraw = (IDirectDrawImpl *) ddraw;
    d3d->private = NULL; /* unused for now */
    IDirectDraw_AddRef((LPDIRECTDRAW)ddraw);
    ICOM_VTBL(d3d) = &mesa_d3dvt;
    *obj = (LPUNKNOWN)d3d;
    TRACE("  Created IDirect3D interface (%p)\n", *obj);

    return S_OK;
}

HRESULT create_direct3d2(LPVOID *obj,IDirectDrawImpl* ddraw) {
    IDirect3D2Impl* d3d;

    d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
    d3d->ref = 1;
    d3d->ddraw = (IDirectDrawImpl *) ddraw;
    d3d->private = NULL; /* unused for now */
    IDirectDraw_AddRef((LPDIRECTDRAW)ddraw);
    ICOM_VTBL(d3d) = &mesa_d3d2vt;
    *obj = (LPUNKNOWN)d3d;
    TRACE("  Creating IDirect3D2 interface (%p)\n", *obj);

    return S_OK;
}

HRESULT create_direct3d3(LPVOID *obj,IDirectDrawImpl* ddraw) {
    IDirect3D3Impl* d3d;

    d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
    d3d->ref = 1;
    d3d->ddraw = (IDirectDrawImpl *) ddraw;
    d3d->private = NULL; /* unused for now */

    IDirectDraw_AddRef((LPDIRECTDRAW)ddraw);
    ICOM_VTBL(d3d) = &mesa_d3d3vt;
    *obj = (LPUNKNOWN)d3d;

    TRACE("  Creating IDirect3D3 interface (%p)\n", *obj);

    return S_OK;
}

