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

#define NONAMELESSUNION
#define NONAMELESSSTRUCT
#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "d3d.h"
#include "ddraw.h"
#include "winerror.h"

#include "ddraw_private.h"
#include "d3d_private.h"
#include "mesa_private.h"
#include "main.h"

#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(ddraw);

HRESULT WINAPI
GL_IDirect3DImpl_1_EnumDevices(LPDIRECT3D iface,
			       LPD3DENUMDEVICESCALLBACK lpEnumDevicesCallback,
			       LPVOID lpUserArg)
{
    ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D, iface);
    TRACE("(%p/%p)->(%p,%p)\n", This, iface, lpEnumDevicesCallback, lpUserArg);

    /* Call functions defined in d3ddevices.c */
    if (d3ddevice_enumerate(lpEnumDevicesCallback, lpUserArg, 1) != D3DENUMRET_OK)
	return D3D_OK;

    return D3D_OK;
}

HRESULT WINAPI
GL_IDirect3DImpl_3_2T_EnumDevices(LPDIRECT3D3 iface,
				  LPD3DENUMDEVICESCALLBACK lpEnumDevicesCallback,
				  LPVOID lpUserArg)
{
    ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D3, iface);
    TRACE("(%p/%p)->(%p,%p)\n", This, iface, lpEnumDevicesCallback, lpUserArg);

    /* Call functions defined in d3ddevices.c */
    if (d3ddevice_enumerate(lpEnumDevicesCallback, lpUserArg, 3) != D3DENUMRET_OK)
	return D3D_OK;

    return D3D_OK;
}

HRESULT WINAPI
GL_IDirect3DImpl_3_2T_1T_CreateLight(LPDIRECT3D3 iface,
				     LPDIRECT3DLIGHT* lplpDirect3DLight,
				     IUnknown* pUnkOuter)
{
    ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D3, iface);
    IDirect3DGLImpl *glThis = (IDirect3DGLImpl *) This->d3d_private;
    int fl;
    IDirect3DLightImpl *d3dlimpl;
    HRESULT ret_value;
    
    TRACE("(%p/%p)->(%p,%p)\n", This, iface, lplpDirect3DLight, pUnkOuter);
    for (fl = 0; fl < MAX_LIGHTS; fl++) {
        if ((glThis->free_lights & (0x01 << fl)) != 0) {
	    glThis->free_lights &= ~(0x01 << fl);
	    break;
	}
    }
    if (fl == MAX_LIGHTS) {
        return DDERR_INVALIDPARAMS; /* No way to say 'max lights reached' ... */
    }
    ret_value = d3dlight_create(&d3dlimpl, This, GL_LIGHT0 + fl);
    *lplpDirect3DLight = ICOM_INTERFACE(d3dlimpl, IDirect3DLight);

    return ret_value;
}

HRESULT WINAPI
GL_IDirect3DImpl_3_2T_1T_CreateMaterial(LPDIRECT3D3 iface,
					LPDIRECT3DMATERIAL3* lplpDirect3DMaterial3,
					IUnknown* pUnkOuter)
{
    IDirect3DMaterialImpl *D3Dmat_impl;
    HRESULT ret_value;
    ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D3, iface);
    
    TRACE("(%p/%p)->(%p,%p)\n", This, iface, lplpDirect3DMaterial3, pUnkOuter);
    ret_value = d3dmaterial_create(&D3Dmat_impl, This);

    *lplpDirect3DMaterial3 = ICOM_INTERFACE(D3Dmat_impl, IDirect3DMaterial3);

    return ret_value;
}

HRESULT WINAPI
GL_IDirect3DImpl_3_2T_1T_CreateViewport(LPDIRECT3D3 iface,
					LPDIRECT3DVIEWPORT3* lplpD3DViewport3,
					IUnknown* pUnkOuter)
{
    IDirect3DViewportImpl *D3Dvp_impl;
    HRESULT ret_value;
    ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D3, iface);
    
    TRACE("(%p/%p)->(%p,%p)\n", This, iface, lplpD3DViewport3, pUnkOuter);
    ret_value = d3dviewport_create(&D3Dvp_impl, This);

    *lplpD3DViewport3 = ICOM_INTERFACE(D3Dvp_impl, IDirect3DViewport3);

    return ret_value;
}

static HRESULT
create_device_helper(IDirectDrawImpl *This,
		     REFCLSID iid,
		     IDirectDrawSurfaceImpl *lpDDS,
		     void **obj,
		     int version) {
    IDirect3DDeviceImpl *lpd3ddev;
    HRESULT ret_value;

    ret_value = d3ddevice_create(&lpd3ddev, This, lpDDS, FALSE);
    if (FAILED(ret_value)) return ret_value;
    
    if ((iid == NULL) ||
	(IsEqualGUID(&IID_D3DDEVICE_OpenGL, iid)) ||
	(IsEqualGUID(&IID_IDirect3DHALDevice, iid)) ||
	(IsEqualGUID(&IID_IDirect3DTnLHalDevice, iid)) ||
	(IsEqualGUID(&IID_IDirect3DRGBDevice, iid)) ||
	(IsEqualGUID(&IID_IDirect3DRefDevice, iid))) {
        switch (version) {
	    case 1:
		*obj = ICOM_INTERFACE(lpd3ddev, IDirect3DDevice);
	        TRACE(" returning OpenGL D3DDevice %p.\n", *obj);
		return D3D_OK;

	    case 2:
		*obj = ICOM_INTERFACE(lpd3ddev, IDirect3DDevice2);
	        TRACE(" returning OpenGL D3DDevice2 %p.\n", *obj);
		return D3D_OK;

	    case 3:
		*obj = ICOM_INTERFACE(lpd3ddev, IDirect3DDevice3);
	        TRACE(" returning OpenGL D3DDevice3 %p.\n", *obj);
		return D3D_OK;

	    case 7:
		*obj = ICOM_INTERFACE(lpd3ddev, IDirect3DDevice7);
	        TRACE(" returning OpenGL D3DDevice7 %p.\n", *obj);
		return D3D_OK;
        }
    }

    *obj = NULL;
    ERR(" Interface unknown when creating D3DDevice (%s)\n", debugstr_guid(iid));
    IDirect3DDevice7_Release(ICOM_INTERFACE(lpd3ddev, IDirect3DDevice7));
    return DDERR_INVALIDPARAMS;
}
     

HRESULT WINAPI
GL_IDirect3DImpl_2_CreateDevice(LPDIRECT3D2 iface,
				REFCLSID rclsid,
				LPDIRECTDRAWSURFACE lpDDS,
				LPDIRECT3DDEVICE2* lplpD3DDevice2)
{
    ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D2, iface);
    IDirectDrawSurfaceImpl *ddsurfaceimpl = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface3, lpDDS);
    TRACE("(%p/%p)->(%s,%p,%p)\n", This, iface, debugstr_guid(rclsid), lpDDS, lplpD3DDevice2);
    return create_device_helper(This, rclsid, ddsurfaceimpl, (void **) lplpD3DDevice2, 2);
}

HRESULT WINAPI
GL_IDirect3DImpl_3_CreateDevice(LPDIRECT3D3 iface,
				REFCLSID rclsid,
				LPDIRECTDRAWSURFACE4 lpDDS,
				LPDIRECT3DDEVICE3* lplpD3DDevice3,
				LPUNKNOWN lpUnk)
{
    ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D3, iface);
    IDirectDrawSurfaceImpl *ddsurfaceimpl = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, lpDDS);
    TRACE("(%p/%p)->(%s,%p,%p)\n", This, iface, debugstr_guid(rclsid), lpDDS, lplpD3DDevice3);
    return create_device_helper(This, rclsid, ddsurfaceimpl, (void **) lplpD3DDevice3, 3);
}

HRESULT WINAPI
GL_IDirect3DImpl_3_2T_1T_FindDevice(LPDIRECT3D3 iface,
				    LPD3DFINDDEVICESEARCH lpD3DDFS,
				    LPD3DFINDDEVICERESULT lpD3DFDR)
{
    ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D3, iface);
    TRACE("(%p/%p)->(%p,%p)\n", This, iface, lpD3DDFS, lpD3DFDR);
    return d3ddevice_find(This, lpD3DDFS, lpD3DFDR);
}

HRESULT WINAPI
GL_IDirect3DImpl_7_3T_EnumZBufferFormats(LPDIRECT3D7 iface,
					 REFCLSID riidDevice,
					 LPD3DENUMPIXELFORMATSCALLBACK lpEnumCallback,
					 LPVOID lpContext)
{
    ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D7, iface);
    DDPIXELFORMAT pformat;
    
    TRACE("(%p/%p)->(%s,%p,%p)\n", This, iface, debugstr_guid(riidDevice), lpEnumCallback, lpContext);

    memset(&pformat, 0, sizeof(pformat));
    pformat.dwSize = sizeof(DDPIXELFORMAT);
    pformat.dwFourCC = 0;   
    TRACE("Enumerating dummy ZBuffer format (16 bits)\n");
    pformat.dwFlags = DDPF_ZBUFFER;
    pformat.u1.dwZBufferBitDepth = 16;
    pformat.u3.dwZBitMask =    0x0000FFFF;
    pformat.u5.dwRGBZBitMask = 0x0000FFFF;

    /* Whatever the return value, stop here.. */
    lpEnumCallback(&pformat, lpContext);
    
    return D3D_OK;
}

HRESULT WINAPI
GL_IDirect3DImpl_7_EnumDevices(LPDIRECT3D7 iface,
			       LPD3DENUMDEVICESCALLBACK7 lpEnumDevicesCallback,
			       LPVOID lpUserArg)
{
    ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D7, iface);
    TRACE("(%p/%p)->(%p,%p)\n", This, iface, lpEnumDevicesCallback, lpUserArg);

    if (d3ddevice_enumerate7(lpEnumDevicesCallback, lpUserArg) != D3DENUMRET_OK)
	return D3D_OK;
    
    return D3D_OK;
}

HRESULT WINAPI
GL_IDirect3DImpl_7_CreateDevice(LPDIRECT3D7 iface,
				REFCLSID rclsid,
				LPDIRECTDRAWSURFACE7 lpDDS,
				LPDIRECT3DDEVICE7* lplpD3DDevice)
{
    ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D7, iface);
    IDirectDrawSurfaceImpl *ddsurfaceimpl = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, lpDDS);
    TRACE("(%p/%p)->(%s,%p,%p)\n", This, iface, debugstr_guid(rclsid), lpDDS, lplpD3DDevice);
    return create_device_helper(This, rclsid, ddsurfaceimpl, (void **) lplpD3DDevice, 7);
}

HRESULT WINAPI
GL_IDirect3DImpl_7_3T_CreateVertexBuffer(LPDIRECT3D7 iface,
					 LPD3DVERTEXBUFFERDESC lpD3DVertBufDesc,
					 LPDIRECT3DVERTEXBUFFER7* lplpD3DVertBuf,
					 DWORD dwFlags)
{
    ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D7, iface);
    IDirect3DVertexBufferImpl *vbimpl;
    HRESULT res;
    
    TRACE("(%p/%p)->(%p,%p,%08lx)\n", This, iface, lpD3DVertBufDesc, lplpD3DVertBuf, dwFlags);

    res = d3dvertexbuffer_create(&vbimpl, This, lpD3DVertBufDesc, dwFlags);

    *lplpD3DVertBuf = ICOM_INTERFACE(vbimpl, IDirect3DVertexBuffer7);
    
    return res;
}

static void light_released(IDirectDrawImpl *This, GLenum light_num)
{
    IDirect3DGLImpl *glThis = (IDirect3DGLImpl *) This->d3d_private;
    glThis->free_lights |= (light_num - GL_LIGHT0);
}

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

IDirect3D7Vtbl VTABLE_IDirect3D7 =
{
    XCAST(QueryInterface) Thunk_IDirect3DImpl_7_QueryInterface,
    XCAST(AddRef) Thunk_IDirect3DImpl_7_AddRef,
    XCAST(Release) Thunk_IDirect3DImpl_7_Release,
    XCAST(EnumDevices) GL_IDirect3DImpl_7_EnumDevices,
    XCAST(CreateDevice) GL_IDirect3DImpl_7_CreateDevice,
    XCAST(CreateVertexBuffer) GL_IDirect3DImpl_7_3T_CreateVertexBuffer,
    XCAST(EnumZBufferFormats) GL_IDirect3DImpl_7_3T_EnumZBufferFormats,
    XCAST(EvictManagedTextures) Main_IDirect3DImpl_7_3T_EvictManagedTextures,
};

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


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

IDirect3D3Vtbl VTABLE_IDirect3D3 =
{
    XCAST(QueryInterface) Thunk_IDirect3DImpl_3_QueryInterface,
    XCAST(AddRef) Thunk_IDirect3DImpl_3_AddRef,
    XCAST(Release) Thunk_IDirect3DImpl_3_Release,
    XCAST(EnumDevices) GL_IDirect3DImpl_3_2T_EnumDevices,
    XCAST(CreateLight) GL_IDirect3DImpl_3_2T_1T_CreateLight,
    XCAST(CreateMaterial) GL_IDirect3DImpl_3_2T_1T_CreateMaterial,
    XCAST(CreateViewport) GL_IDirect3DImpl_3_2T_1T_CreateViewport,
    XCAST(FindDevice) GL_IDirect3DImpl_3_2T_1T_FindDevice,
    XCAST(CreateDevice) GL_IDirect3DImpl_3_CreateDevice,
    XCAST(CreateVertexBuffer) Thunk_IDirect3DImpl_3_CreateVertexBuffer,
    XCAST(EnumZBufferFormats) Thunk_IDirect3DImpl_3_EnumZBufferFormats,
    XCAST(EvictManagedTextures) Thunk_IDirect3DImpl_3_EvictManagedTextures,
};

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


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

IDirect3D2Vtbl VTABLE_IDirect3D2 =
{
    XCAST(QueryInterface) Thunk_IDirect3DImpl_2_QueryInterface,
    XCAST(AddRef) Thunk_IDirect3DImpl_2_AddRef,
    XCAST(Release) Thunk_IDirect3DImpl_2_Release,
    XCAST(EnumDevices) Thunk_IDirect3DImpl_2_EnumDevices,
    XCAST(CreateLight) Thunk_IDirect3DImpl_2_CreateLight,
    XCAST(CreateMaterial) Thunk_IDirect3DImpl_2_CreateMaterial,
    XCAST(CreateViewport) Thunk_IDirect3DImpl_2_CreateViewport,
    XCAST(FindDevice) Thunk_IDirect3DImpl_2_FindDevice,
    XCAST(CreateDevice) GL_IDirect3DImpl_2_CreateDevice,
};

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


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

IDirect3DVtbl VTABLE_IDirect3D =
{
    XCAST(QueryInterface) Thunk_IDirect3DImpl_1_QueryInterface,
    XCAST(AddRef) Thunk_IDirect3DImpl_1_AddRef,
    XCAST(Release) Thunk_IDirect3DImpl_1_Release,
    XCAST(Initialize) Main_IDirect3DImpl_1_Initialize,
    XCAST(EnumDevices) GL_IDirect3DImpl_1_EnumDevices,
    XCAST(CreateLight) Thunk_IDirect3DImpl_1_CreateLight,
    XCAST(CreateMaterial) Thunk_IDirect3DImpl_1_CreateMaterial,
    XCAST(CreateViewport) Thunk_IDirect3DImpl_1_CreateViewport,
    XCAST(FindDevice) Thunk_IDirect3DImpl_1_FindDevice,
};

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

static HRESULT d3d_add_device(IDirectDrawImpl *This, IDirect3DDeviceImpl *device)
{
    if  (This->current_device == NULL) {
        /* Create delayed textures now that we have an OpenGL context...
	   For that, go through all surface attached to our DDraw object and create
	   OpenGL textures for all textures.. */
        IDirectDrawSurfaceImpl *surf = This->surfaces;

	while (surf != NULL) {
	    if (surf->surface_desc.ddsCaps.dwCaps & DDSCAPS_TEXTURE) {
	        /* Found a texture.. Now create the OpenGL part */
	        d3dtexture_create(This, surf, FALSE, surf->mip_main);
	    }
	    surf = surf->next_ddraw;
	}
    }
    /* For the moment, only one device 'supported'... */
    This->current_device = device;

    return DD_OK;
}

static HRESULT d3d_remove_device(IDirectDrawImpl *This, IDirect3DDeviceImpl *device)
{
    This->current_device = NULL;
    return DD_OK;
}

HRESULT direct3d_create(IDirectDrawImpl *This)
{
    IDirect3DGLImpl *globject;
    
    globject = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DGLImpl));
    if (globject == NULL) return DDERR_OUTOFMEMORY;

    This->d3d_create_texture = d3dtexture_create;
    This->d3d_added_device = d3d_add_device;
    This->d3d_removed_device = d3d_remove_device;

    ICOM_INIT_INTERFACE(This, IDirect3D,  VTABLE_IDirect3D);
    ICOM_INIT_INTERFACE(This, IDirect3D2, VTABLE_IDirect3D2);
    ICOM_INIT_INTERFACE(This, IDirect3D3, VTABLE_IDirect3D3);
    ICOM_INIT_INTERFACE(This, IDirect3D7, VTABLE_IDirect3D7);

    globject->free_lights = (0x01 << MAX_LIGHTS) - 1; /* There are, in total, 8 lights in OpenGL */
    globject->light_released = light_released;

    This->d3d_private = globject;

    TRACE(" creating OpenGL private storage at %p.\n", globject);
    
    return D3D_OK;
}
