/*
 * Copyright 2000 Marcus Meissner
 *
 * 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 "winerror.h"
#include "ddraw.h"
#include "d3d.h"
#include "wine/debug.h"

#include "d3d_private.h"

WINE_DEFAULT_DEBUG_CHANNEL(ddraw);


HRESULT WINAPI
Main_IDirect3DImpl_1_Initialize(LPDIRECT3D iface,
                                REFIID riid)
{
    ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D, iface);
    TRACE("(%p/%p)->(%s) no-op...\n", This, iface, debugstr_guid(riid));
    return D3D_OK;
}

HRESULT WINAPI
Main_IDirect3DImpl_3_2T_1T_EnumDevices(LPDIRECT3D3 iface,
                                       LPD3DENUMDEVICESCALLBACK lpEnumDevicesCallback,
                                       LPVOID lpUserArg)
{
    ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D3, iface);
    FIXME("(%p/%p)->(%p,%p): stub!\n", This, iface, lpEnumDevicesCallback, lpUserArg);
    return D3D_OK;
}

HRESULT WINAPI
Main_IDirect3DImpl_3_2T_1T_CreateLight(LPDIRECT3D3 iface,
                                       LPDIRECT3DLIGHT* lplpDirect3DLight,
                                       IUnknown* pUnkOuter)
{
    ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D3, iface);
    FIXME("(%p/%p)->(%p,%p): stub!\n", This, iface, lplpDirect3DLight, pUnkOuter);
    return D3D_OK;
}

HRESULT WINAPI
Main_IDirect3DImpl_3_2T_1T_CreateMaterial(LPDIRECT3D3 iface,
					  LPDIRECT3DMATERIAL3* lplpDirect3DMaterial3,
					  IUnknown* pUnkOuter)
{
    ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D3, iface);
    FIXME("(%p/%p)->(%p,%p): stub!\n", This, iface, lplpDirect3DMaterial3, pUnkOuter);
    return D3D_OK;
}

HRESULT WINAPI
Main_IDirect3DImpl_3_2T_1T_CreateViewport(LPDIRECT3D3 iface,
					  LPDIRECT3DVIEWPORT3* lplpD3DViewport3,
					  IUnknown* pUnkOuter)
{
    ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D3, iface);
    FIXME("(%p/%p)->(%p,%p): stub!\n", This, iface, lplpD3DViewport3, pUnkOuter);
    return D3D_OK;
}

HRESULT WINAPI
Main_IDirect3DImpl_3_2T_1T_FindDevice(LPDIRECT3D3 iface,
				      LPD3DFINDDEVICESEARCH lpD3DDFS,
				      LPD3DFINDDEVICERESULT lpD3DFDR)
{
    ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D3, iface);
    FIXME("(%p/%p)->(%p,%p): stub!\n", This, iface, lpD3DDFS, lpD3DFDR);
    return D3D_OK;
}

HRESULT WINAPI
Main_IDirect3DImpl_2_CreateDevice(LPDIRECT3D2 iface,
                                  REFCLSID rclsid,
                                  LPDIRECTDRAWSURFACE lpDDS,
                                  LPDIRECT3DDEVICE2* lplpD3DDevice2)
{
    ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D2, iface);
    FIXME("(%p/%p)->(%s,%p,%p): stub!\n", This, iface, debugstr_guid(rclsid), lpDDS, lplpD3DDevice2);
    return D3D_OK;
}

HRESULT WINAPI
Main_IDirect3DImpl_3_CreateDevice(LPDIRECT3D3 iface,
                                  REFCLSID rclsid,
                                  LPDIRECTDRAWSURFACE4 lpDDS,
                                  LPDIRECT3DDEVICE3* lplpD3DDevice3,
                                  LPUNKNOWN lpUnk)
{
    ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D3, iface);
    FIXME("(%p/%p)->(%s,%p,%p,%p): stub!\n", This, iface, debugstr_guid(rclsid), lpDDS, lplpD3DDevice3, lpUnk);
    return D3D_OK;
}

HRESULT WINAPI
Main_IDirect3DImpl_7_3T_EnumZBufferFormats(LPDIRECT3D7 iface,
                                           REFCLSID riidDevice,
                                           LPD3DENUMPIXELFORMATSCALLBACK lpEnumCallback,
                                           LPVOID lpContext)
{
    ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D7, iface);
    FIXME("(%p/%p)->(%s,%p,%p): stub!\n", This, iface, debugstr_guid(riidDevice), lpEnumCallback, lpContext);
    return D3D_OK;
}

HRESULT WINAPI
Main_IDirect3DImpl_7_3T_EvictManagedTextures(LPDIRECT3D7 iface)
{
    ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D7, iface);
    FIXME("(%p/%p)->(): stub!\n", This, iface);
    return D3D_OK;
}

HRESULT WINAPI
Main_IDirect3DImpl_7_EnumDevices(LPDIRECT3D7 iface,
                                 LPD3DENUMDEVICESCALLBACK7 lpEnumDevicesCallback,
                                 LPVOID lpUserArg)
{
    ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D7, iface);
    FIXME("(%p/%p)->(%p,%p): stub!\n", This, iface, lpEnumDevicesCallback, lpUserArg);
    return D3D_OK;
}

HRESULT WINAPI
Main_IDirect3DImpl_7_CreateDevice(LPDIRECT3D7 iface,
                                  REFCLSID rclsid,
                                  LPDIRECTDRAWSURFACE7 lpDDS,
                                  LPDIRECT3DDEVICE7* lplpD3DDevice)
{
    ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D7, iface);
    FIXME("(%p/%p)->(%s,%p,%p): stub!\n", This, iface, debugstr_guid(rclsid), lpDDS, lplpD3DDevice);
    return D3D_OK;
}

HRESULT WINAPI
Main_IDirect3DImpl_7_3T_CreateVertexBuffer(LPDIRECT3D7 iface,
					   LPD3DVERTEXBUFFERDESC lpD3DVertBufDesc,
					   LPDIRECT3DVERTEXBUFFER7* lplpD3DVertBuf,
					   DWORD dwFlags)
{
    ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D7, iface);
    FIXME("(%p/%p)->(%p,%p,%08lx): stub!\n", This, iface, lpD3DVertBufDesc, lplpD3DVertBuf, dwFlags);
    return D3D_OK;
}

HRESULT WINAPI
Thunk_IDirect3DImpl_7_QueryInterface(LPDIRECT3D7 iface,
                                     REFIID riid,
                                     LPVOID* obp)
{
    TRACE("(%p)->(%s,%p) thunking to IDirectDraw7 interface.\n", iface, debugstr_guid(riid), obp);
    return IDirectDraw7_QueryInterface(COM_INTERFACE_CAST(IDirectDrawImpl, IDirect3D7, IDirectDraw7, iface),
				       riid,
				       obp);
}

HRESULT WINAPI
Thunk_IDirect3DImpl_3_QueryInterface(LPDIRECT3D3 iface,
                                     REFIID riid,
                                     LPVOID* obp)
{
    TRACE("(%p)->(%s,%p) thunking to IDirectDraw7 interface.\n", iface, debugstr_guid(riid), obp);
    return IDirectDraw7_QueryInterface(COM_INTERFACE_CAST(IDirectDrawImpl, IDirect3D3, IDirectDraw7, iface),
				       riid,
				       obp);
}

HRESULT WINAPI
Thunk_IDirect3DImpl_2_QueryInterface(LPDIRECT3D2 iface,
                                     REFIID riid,
                                     LPVOID* obp)
{
    TRACE("(%p)->(%s,%p) thunking to IDirectDraw7 interface.\n", iface, debugstr_guid(riid), obp);
    return IDirectDraw7_QueryInterface(COM_INTERFACE_CAST(IDirectDrawImpl, IDirect3D2, IDirectDraw7, iface),
				       riid,
				       obp);
}

HRESULT WINAPI
Thunk_IDirect3DImpl_1_QueryInterface(LPDIRECT3D iface,
                                     REFIID riid,
                                     LPVOID* obp)
{
    TRACE("(%p)->(%s,%p) thunking to IDirectDraw7 interface.\n", iface, debugstr_guid(riid), obp);
    return IDirectDraw7_QueryInterface(COM_INTERFACE_CAST(IDirectDrawImpl, IDirect3D, IDirectDraw7, iface),
				       riid,
				       obp);
}

ULONG WINAPI
Thunk_IDirect3DImpl_7_AddRef(LPDIRECT3D7 iface)
{
    TRACE("(%p)->() thunking to IDirectDraw7 interface.\n", iface);
    return IDirectDraw7_AddRef(COM_INTERFACE_CAST(IDirectDrawImpl, IDirect3D7, IDirectDraw7, iface));
}

ULONG WINAPI
Thunk_IDirect3DImpl_3_AddRef(LPDIRECT3D3 iface)
{
    TRACE("(%p)->() thunking to IDirectDraw7 interface.\n", iface);
    return IDirectDraw7_AddRef(COM_INTERFACE_CAST(IDirectDrawImpl, IDirect3D3, IDirectDraw7, iface));
}

ULONG WINAPI
Thunk_IDirect3DImpl_2_AddRef(LPDIRECT3D2 iface)
{
    TRACE("(%p)->() thunking to IDirectDraw7 interface.\n", iface);
    return IDirectDraw7_AddRef(COM_INTERFACE_CAST(IDirectDrawImpl, IDirect3D2, IDirectDraw7, iface));
}

ULONG WINAPI
Thunk_IDirect3DImpl_1_AddRef(LPDIRECT3D iface)
{
    TRACE("(%p)->() thunking to IDirectDraw7 interface.\n", iface);
    return IDirectDraw7_AddRef(COM_INTERFACE_CAST(IDirectDrawImpl, IDirect3D, IDirectDraw7, iface));
}

ULONG WINAPI
Thunk_IDirect3DImpl_7_Release(LPDIRECT3D7 iface)
{
    TRACE("(%p)->() thunking to IDirectDraw7 interface.\n", iface);
    return IDirectDraw7_Release(COM_INTERFACE_CAST(IDirectDrawImpl, IDirect3D7, IDirectDraw7, iface));
}

ULONG WINAPI
Thunk_IDirect3DImpl_3_Release(LPDIRECT3D3 iface)
{
    TRACE("(%p)->() thunking to IDirectDraw7 interface.\n", iface);
    return IDirectDraw7_Release(COM_INTERFACE_CAST(IDirectDrawImpl, IDirect3D3, IDirectDraw7, iface));
}

ULONG WINAPI
Thunk_IDirect3DImpl_2_Release(LPDIRECT3D2 iface)
{
    TRACE("(%p)->() thunking to IDirectDraw7 interface.\n", iface);
    return IDirectDraw7_Release(COM_INTERFACE_CAST(IDirectDrawImpl, IDirect3D2, IDirectDraw7, iface));
}

ULONG WINAPI
Thunk_IDirect3DImpl_1_Release(LPDIRECT3D iface)
{
    TRACE("(%p)->() thunking to IDirectDraw7 interface.\n", iface);
    return IDirectDraw7_Release(COM_INTERFACE_CAST(IDirectDrawImpl, IDirect3D, IDirectDraw7, iface));
}

HRESULT WINAPI
Thunk_IDirect3DImpl_3_EnumZBufferFormats(LPDIRECT3D3 iface,
                                         REFCLSID riidDevice,
                                         LPD3DENUMPIXELFORMATSCALLBACK lpEnumCallback,
                                         LPVOID lpContext)
{
    TRACE("(%p)->(%s,%p,%p) thunking to IDirect3D7 interface.\n", iface, debugstr_guid(riidDevice), lpEnumCallback, lpContext);
    return IDirect3D7_EnumZBufferFormats(COM_INTERFACE_CAST(IDirectDrawImpl, IDirect3D3, IDirect3D7, iface),
                                         riidDevice,
                                         lpEnumCallback,
                                         lpContext);
}

HRESULT WINAPI
Thunk_IDirect3DImpl_3_EvictManagedTextures(LPDIRECT3D3 iface)
{
    TRACE("(%p)->() thunking to IDirect3D7 interface.\n", iface);
    return IDirect3D7_EvictManagedTextures(COM_INTERFACE_CAST(IDirectDrawImpl, IDirect3D3, IDirect3D7, iface));
}

HRESULT WINAPI
Thunk_IDirect3DImpl_2_EnumDevices(LPDIRECT3D2 iface,
                                  LPD3DENUMDEVICESCALLBACK lpEnumDevicesCallback,
                                  LPVOID lpUserArg)
{
    TRACE("(%p)->(%p,%p) thunking to IDirect3D3 interface.\n", iface, lpEnumDevicesCallback, lpUserArg);
    return IDirect3D3_EnumDevices(COM_INTERFACE_CAST(IDirectDrawImpl, IDirect3D2, IDirect3D3, iface),
                                  lpEnumDevicesCallback,
                                  lpUserArg);
}

HRESULT WINAPI
Thunk_IDirect3DImpl_2_CreateLight(LPDIRECT3D2 iface,
                                  LPDIRECT3DLIGHT* lplpDirect3DLight,
                                  IUnknown* pUnkOuter)
{
    TRACE("(%p)->(%p,%p) thunking to IDirect3D3 interface.\n", iface, lplpDirect3DLight, pUnkOuter);
    return IDirect3D3_CreateLight(COM_INTERFACE_CAST(IDirectDrawImpl, IDirect3D2, IDirect3D3, iface),
                                  lplpDirect3DLight,
                                  pUnkOuter);
}

HRESULT WINAPI
Thunk_IDirect3DImpl_1_CreateLight(LPDIRECT3D iface,
                                  LPDIRECT3DLIGHT* lplpDirect3DLight,
                                  IUnknown* pUnkOuter)
{
    TRACE("(%p)->(%p,%p) thunking to IDirect3D3 interface.\n", iface, lplpDirect3DLight, pUnkOuter);
    return IDirect3D3_CreateLight(COM_INTERFACE_CAST(IDirectDrawImpl, IDirect3D, IDirect3D3, iface),
                                  lplpDirect3DLight,
                                  pUnkOuter);
}

HRESULT WINAPI
Thunk_IDirect3DImpl_1_CreateMaterial(LPDIRECT3D iface,
				     LPDIRECT3DMATERIAL* lplpDirect3DMaterial,
				     IUnknown* pUnkOuter)
{
    HRESULT ret;
    LPDIRECT3DMATERIAL3 ret_val;

    TRACE("(%p)->(%p,%p) thunking to IDirect3D3 interface.\n", iface, lplpDirect3DMaterial, pUnkOuter);
    ret = IDirect3D3_CreateMaterial(COM_INTERFACE_CAST(IDirectDrawImpl, IDirect3D, IDirect3D3, iface),
				    &ret_val,
				    pUnkOuter);

    *lplpDirect3DMaterial = COM_INTERFACE_CAST(IDirect3DMaterialImpl, IDirect3DMaterial3, IDirect3DMaterial, ret_val);

    TRACE(" returning interface %p.\n", *lplpDirect3DMaterial);
    
    return ret;
}

HRESULT WINAPI
Thunk_IDirect3DImpl_1_CreateViewport(LPDIRECT3D iface,
				     LPDIRECT3DVIEWPORT* lplpD3DViewport,
				     IUnknown* pUnkOuter)
{
    TRACE("(%p)->(%p,%p) thunking to IDirect3D3 interface.\n", iface, lplpD3DViewport, pUnkOuter);
    return IDirect3D3_CreateViewport(COM_INTERFACE_CAST(IDirectDrawImpl, IDirect3D, IDirect3D3, iface),
				    (LPDIRECT3DVIEWPORT3 *) lplpD3DViewport /* No need to cast here */,
				    pUnkOuter);
}

HRESULT WINAPI
Thunk_IDirect3DImpl_2_CreateMaterial(LPDIRECT3D2 iface,
				     LPDIRECT3DMATERIAL2* lplpDirect3DMaterial2,
				     IUnknown* pUnkOuter)
{
    HRESULT ret;
    LPDIRECT3DMATERIAL3 ret_val;

    TRACE("(%p)->(%p,%p) thunking to IDirect3D3 interface.\n", iface, lplpDirect3DMaterial2, pUnkOuter);
    ret = IDirect3D3_CreateMaterial(COM_INTERFACE_CAST(IDirectDrawImpl, IDirect3D2, IDirect3D3, iface),
				    &ret_val,
				    pUnkOuter);

    *lplpDirect3DMaterial2 = COM_INTERFACE_CAST(IDirect3DMaterialImpl, IDirect3DMaterial3, IDirect3DMaterial2, ret_val);

    TRACE(" returning interface %p.\n", *lplpDirect3DMaterial2);
    
    return ret;
}

HRESULT WINAPI
Thunk_IDirect3DImpl_2_CreateViewport(LPDIRECT3D2 iface,
				     LPDIRECT3DVIEWPORT* lplpD3DViewport2,
				     IUnknown* pUnkOuter)
{
    TRACE("(%p)->(%p,%p) thunking to IDirect3D3 interface.\n", iface, lplpD3DViewport2, pUnkOuter);
    return IDirect3D3_CreateViewport(COM_INTERFACE_CAST(IDirectDrawImpl, IDirect3D2, IDirect3D3, iface),
				     (LPDIRECT3DVIEWPORT3 *) lplpD3DViewport2 /* No need to cast here */,
				     pUnkOuter);
}


HRESULT WINAPI
Thunk_IDirect3DImpl_3_CreateVertexBuffer(LPDIRECT3D3 iface,
					 LPD3DVERTEXBUFFERDESC lpD3DVertBufDesc,
					 LPDIRECT3DVERTEXBUFFER* lplpD3DVertBuf,
					 DWORD dwFlags,
					 LPUNKNOWN lpUnk)
{
    HRESULT ret;
    LPDIRECT3DVERTEXBUFFER7 ret_val;

    TRACE("(%p)->(%p,%p,%08lx,%p) thunking to IDirect3D7 interface.\n", iface, lpD3DVertBufDesc, lplpD3DVertBuf, dwFlags, lpUnk);
    
    /* dwFlags is not used in the D3D7 interface, use the vertex buffer description instead */
    if (dwFlags & D3DDP_DONOTCLIP) lpD3DVertBufDesc->dwCaps |= D3DVBCAPS_DONOTCLIP;

    ret = IDirect3D7_CreateVertexBuffer(COM_INTERFACE_CAST(IDirectDrawImpl, IDirect3D3, IDirect3D7, iface),
					lpD3DVertBufDesc,
					&ret_val,
					dwFlags);

    *lplpD3DVertBuf = COM_INTERFACE_CAST(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, IDirect3DVertexBuffer, ret_val);

    TRACE(" returning interface %p.\n", *lplpD3DVertBuf);
    
    return ret;
}

HRESULT WINAPI
Thunk_IDirect3DImpl_1_FindDevice(LPDIRECT3D iface,
				 LPD3DFINDDEVICESEARCH lpD3DDFS,
				 LPD3DFINDDEVICERESULT lplpD3DDevice)
{
    TRACE("(%p)->(%p,%p) thunking to IDirect3D3 interface.\n", iface, lpD3DDFS, lplpD3DDevice);
    return IDirect3D3_FindDevice(COM_INTERFACE_CAST(IDirectDrawImpl, IDirect3D, IDirect3D3, iface),
				 lpD3DDFS,
				 lplpD3DDevice);
}

HRESULT WINAPI
Thunk_IDirect3DImpl_2_FindDevice(LPDIRECT3D2 iface,
				 LPD3DFINDDEVICESEARCH lpD3DDFS,
				 LPD3DFINDDEVICERESULT lpD3DFDR)
{
    TRACE("(%p)->(%p,%p) thunking to IDirect3D3 interface.\n", iface, lpD3DDFS, lpD3DFDR);
    return IDirect3D3_FindDevice(COM_INTERFACE_CAST(IDirectDrawImpl, IDirect3D2, IDirect3D3, iface),
				 lpD3DDFS,
				 lpD3DFDR);
}
