/* Direct3D ExecuteBuffer
 * Copyright (c) 1998 Lionel ULMER
 *
 * This file contains the implementation of Direct3DExecuteBuffer.
 *
 * 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 <string.h>

#define NONAMELESSUNION
#define NONAMELESSSTRUCT
#include "windef.h"
#include "winerror.h"
#include "objbase.h"
#include "ddraw.h"
#include "d3d.h"
#include "wine/debug.h"

#include "d3d_private.h"
#include "mesa_private.h"

WINE_DEFAULT_DEBUG_CHANNEL(ddraw);

static void _dump_d3dstatus(LPD3DSTATUS lpStatus) {

}

static void _dump_executedata(LPD3DEXECUTEDATA lpData) {
    DPRINTF("dwSize : %ld\n", lpData->dwSize);
    DPRINTF("Vertex      Offset : %ld  Count  : %ld\n", lpData->dwVertexOffset, lpData->dwVertexCount);
    DPRINTF("Instruction Offset : %ld  Length : %ld\n", lpData->dwInstructionOffset, lpData->dwInstructionLength);
    DPRINTF("HVertex     Offset : %ld\n", lpData->dwHVertexOffset);
    _dump_d3dstatus(&(lpData->dsStatus));
}

static void _dump_D3DEXECUTEBUFFERDESC(LPD3DEXECUTEBUFFERDESC lpDesc) {

}

static void execute(IDirect3DExecuteBufferImpl *This,
		    IDirect3DDeviceImpl *lpDevice,
		    IDirect3DViewportImpl *lpViewport)
{
    /* DWORD bs = This->desc.dwBufferSize; */
    DWORD vs = This->data.dwVertexOffset;
    /* DWORD vc = This->data.dwVertexCount; */
    DWORD is = This->data.dwInstructionOffset;
    /* DWORD il = This->data.dwInstructionLength; */

    char *instr = (char *)This->desc.lpData + is;

    /* Should check if the viewport was added or not to the device */

    /* Activate the viewport */
    lpViewport->active_device = lpDevice;
    lpViewport->activate(lpViewport);

    TRACE("ExecuteData : \n");
    if (TRACE_ON(ddraw))
      _dump_executedata(&(This->data));

    while (1) {
        LPD3DINSTRUCTION current = (LPD3DINSTRUCTION) instr;
	BYTE size;
	WORD count;
	
	count = current->wCount;
	size = current->bSize;
	instr += sizeof(D3DINSTRUCTION);
	
	switch (current->bOpcode) {
	    case D3DOP_POINT: {
	        WARN("POINT-s          (%d)\n", count);
		instr += count * size;
	    } break;

	    case D3DOP_LINE: {
	        WARN("LINE-s           (%d)\n", count);
		instr += count * size;
	    } break;

	    case D3DOP_TRIANGLE: {
	        int i;
		D3DTLVERTEX *tl_vx = (D3DTLVERTEX *) This->vertex_data;
		TRACE("TRIANGLE         (%d)\n", count);
		
		if (count*3>This->nb_indices) {
		    This->nb_indices = count * 3;
		    if (This->indices)
		        HeapFree(GetProcessHeap(),0,This->indices);
		    This->indices = HeapAlloc(GetProcessHeap(),0,sizeof(WORD)*This->nb_indices);
		}
			
		for (i = 0; i < count; i++) {
                    LPD3DTRIANGLE ci = (LPD3DTRIANGLE) instr;
		    TRACE("  v1: %d  v2: %d  v3: %d\n",ci->u1.v1, ci->u2.v2, ci->u3.v3);
		    TRACE("  Flags : ");
		    if (TRACE_ON(ddraw)) {
			/* Wireframe */
			if (ci->wFlags & D3DTRIFLAG_EDGEENABLE1)
	        	    TRACE("EDGEENABLE1 ");
	    		if (ci->wFlags & D3DTRIFLAG_EDGEENABLE2)
	        	    TRACE("EDGEENABLE2 ");
	    		if (ci->wFlags & D3DTRIFLAG_EDGEENABLE1)
	        	    TRACE("EDGEENABLE3 ");
	    		/* Strips / Fans */
	    		if (ci->wFlags == D3DTRIFLAG_EVEN)
	        	    TRACE("EVEN ");
	    		if (ci->wFlags == D3DTRIFLAG_ODD)
	        	    TRACE("ODD ");
	    		if (ci->wFlags == D3DTRIFLAG_START)
	        	    TRACE("START ");
	    		if ((ci->wFlags > 0) && (ci->wFlags < 30))
	       		    TRACE("STARTFLAT(%d) ", ci->wFlags);
	    		TRACE("\n");
        	    }
		    This->indices[i*3]=ci->u1.v1;This->indices[i*3+1]=ci->u2.v2;This->indices[i*3+2]=ci->u3.v3;
                    instr += size;
		}
                IDirect3DDevice7_DrawIndexedPrimitive(ICOM_INTERFACE(lpDevice,IDirect3DDevice7),
				                      D3DPT_TRIANGLELIST,D3DFVF_TLVERTEX,tl_vx,0,This->indices,count*3,0);
	    } break;

	    case D3DOP_MATRIXLOAD:
	        WARN("MATRIXLOAD-s     (%d)\n", count);
	        instr += count * size;
	        break;

	    case D3DOP_MATRIXMULTIPLY: {
	        int i;
		TRACE("MATRIXMULTIPLY   (%d)\n", count);
		
		for (i = 0; i < count; i++) {
		    LPD3DMATRIXMULTIPLY ci = (LPD3DMATRIXMULTIPLY) instr;
		    LPD3DMATRIX a = (LPD3DMATRIX) ci->hDestMatrix;
		    LPD3DMATRIX b = (LPD3DMATRIX) ci->hSrcMatrix1;
		    LPD3DMATRIX c = (LPD3DMATRIX) ci->hSrcMatrix2;
		    
		    TRACE("  Dest : %08lx  Src1 : %08lx  Src2 : %08lx\n",
			  ci->hDestMatrix, ci->hSrcMatrix1, ci->hSrcMatrix2);
		    
                    multiply_matrix(a,c,b);

		    instr += size;
		}
	    } break;

	    case D3DOP_STATETRANSFORM: {
	        int i;
		TRACE("STATETRANSFORM   (%d)\n", count);
		
		for (i = 0; i < count; i++) {
		    LPD3DSTATE ci = (LPD3DSTATE) instr;

		    IDirect3DDevice7_SetTransform(ICOM_INTERFACE(lpDevice, IDirect3DDevice7),
						  ci->u1.drstRenderStateType, (LPD3DMATRIX)ci->u2.dwArg[0]);
		    
		    instr += size;
		}
	    } break;

	    case D3DOP_STATELIGHT: {
	        int i;
		TRACE("STATELIGHT       (%d)\n", count);
		
		for (i = 0; i < count; i++) {
		    LPD3DSTATE ci = (LPD3DSTATE) instr;

		    TRACE("(%08x,%08lx)\n",ci->u1.dlstLightStateType, ci->u2.dwArg[0]);

		    if (!ci->u1.dlstLightStateType && (ci->u1.dlstLightStateType > D3DLIGHTSTATE_COLORVERTEX))
			ERR("Unexpected Light State Type\n");
		    else if (ci->u1.dlstLightStateType == D3DLIGHTSTATE_MATERIAL /* 1 */) {
			IDirect3DMaterialImpl *mat = (IDirect3DMaterialImpl *) ci->u2.dwArg[0];

			if (mat != NULL) {
			    mat->activate(mat);
			} else {
			    ERR(" D3DLIGHTSTATE_MATERIAL called with NULL material !!!\n");
			}
		    }
		   else if (ci->u1.dlstLightStateType == D3DLIGHTSTATE_COLORMODEL /* 3 */) {
			switch (ci->u2.dwArg[0]) {
			    case D3DCOLOR_MONO:
			       ERR("DDCOLOR_MONO should not happen!\n");
			       break;
			    case D3DCOLOR_RGB:
			       /* We are already in this mode */
			       break;
			    default:
		               ERR("Unknown color model!\n");
			}
		    } else {
		    	D3DRENDERSTATETYPE rs = 0;
		    	switch (ci->u1.dlstLightStateType) {

		    	    case D3DLIGHTSTATE_AMBIENT:       /* 2 */
				rs = D3DRENDERSTATE_AMBIENT;
				break;		
			    case D3DLIGHTSTATE_FOGMODE:       /* 4 */
				rs = D3DRENDERSTATE_FOGVERTEXMODE;
				break;
			    case D3DLIGHTSTATE_FOGSTART:      /* 5 */
				rs = D3DRENDERSTATE_FOGSTART;
				break;
			    case D3DLIGHTSTATE_FOGEND:        /* 6 */
				rs = D3DRENDERSTATE_FOGEND;
				break;
			    case D3DLIGHTSTATE_FOGDENSITY:    /* 7 */
				rs = D3DRENDERSTATE_FOGDENSITY;
				break;
			    case D3DLIGHTSTATE_COLORVERTEX:   /* 8 */
				rs = D3DRENDERSTATE_COLORVERTEX;
				break;
			    default:
				break;
			}
			
		        IDirect3DDevice7_SetRenderState(ICOM_INTERFACE(lpDevice, IDirect3DDevice7),
	                                		rs,ci->u2.dwArg[0]);
		   }

		}
		instr += size;
	    } break;

	    case D3DOP_STATERENDER: {
	        int i;
		TRACE("STATERENDER      (%d)\n", count);

		for (i = 0; i < count; i++) {
		    LPD3DSTATE ci = (LPD3DSTATE) instr;
		    
		    IDirect3DDevice7_SetRenderState(ICOM_INTERFACE(lpDevice, IDirect3DDevice7),
						    ci->u1.drstRenderStateType, ci->u2.dwArg[0]);

		    instr += size;
		}
	    } break;

	    case D3DOP_PROCESSVERTICES: {
	        int i;
		TRACE("PROCESSVERTICES  (%d)\n", count);

		for (i = 0; i < count; i++) {
		    LPD3DPROCESSVERTICES ci = (LPD3DPROCESSVERTICES) instr;

		    TRACE("  Start : %d Dest : %d Count : %ld\n",
			  ci->wStart, ci->wDest, ci->dwCount);
		    TRACE("  Flags : ");
		    if (TRACE_ON(ddraw)) {
		        if (ci->dwFlags & D3DPROCESSVERTICES_COPY)
			    TRACE("COPY ");
			if (ci->dwFlags & D3DPROCESSVERTICES_NOCOLOR)
			    TRACE("NOCOLOR ");
			if (ci->dwFlags == D3DPROCESSVERTICES_OPMASK)
			    TRACE("OPMASK ");
			if (ci->dwFlags & D3DPROCESSVERTICES_TRANSFORM)
			    TRACE("TRANSFORM ");
			if (ci->dwFlags == D3DPROCESSVERTICES_TRANSFORMLIGHT)
			    TRACE("TRANSFORMLIGHT ");
			if (ci->dwFlags & D3DPROCESSVERTICES_UPDATEEXTENTS)
			    TRACE("UPDATEEXTENTS ");
			TRACE("\n");
		    }
		    
		    /* This is where doing Direct3D on top on OpenGL is quite difficult.
		       This method transforms a set of vertices using the CURRENT state
		       (lighting, projection, ...) but does not rasterize them.
		       They will only be put on screen later (with the POINT / LINE and
		       TRIANGLE op-codes). The problem is that you can have a triangle
		       with each point having been transformed using another state...
		       
		       In this implementation, I will emulate only ONE thing : each
		       vertex can have its own "WORLD" transformation (this is used in the
		       TWIST.EXE demo of the 5.2 SDK). I suppose that all vertices of the
		       execute buffer use the same state.
		       
		       If I find applications that change other states, I will try to do a
		       more 'fine-tuned' state emulation (but I may become quite tricky if
		       it changes a light position in the middle of a triangle).
		       
		       In this case, a 'direct' approach (i.e. without using OpenGL, but
		       writing our own 3D rasterizer) would be easier. */
		    
		    /* The current method (with the hypothesis that only the WORLD matrix
		       will change between two points) is like this :
		       - I transform 'manually' all the vertices with the current WORLD
		         matrix and store them in the vertex buffer
		       - during the rasterization phase, the WORLD matrix will be set to
		         the Identity matrix */
		    
		    /* Enough for the moment */
		    if (ci->dwFlags == D3DPROCESSVERTICES_TRANSFORMLIGHT) {
		        int nb;
			D3DVERTEX  *src = ((LPD3DVERTEX)  ((char *)This->desc.lpData + vs)) + ci->wStart;
			D3DTLVERTEX *dst = ((LPD3DTLVERTEX) (This->vertex_data)) + ci->wDest;
			D3DMATRIX *mat2 = lpDevice->world_mat;
			D3DMATRIX mat;
			D3DVALUE nx,ny,nz;
			D3DVIEWPORT* Viewport = &lpViewport->viewports.vp1;
			
			if (TRACE_ON(ddraw)) {
			    TRACE("  Projection Matrix : (%p)\n", lpDevice->proj_mat);
			    dump_D3DMATRIX(lpDevice->proj_mat);
			    TRACE("  View       Matrix : (%p)\n", lpDevice->view_mat);
			    dump_D3DMATRIX(lpDevice->view_mat);
			    TRACE("  World Matrix : (%p)\n", &mat);
			    dump_D3DMATRIX(&mat);
			}

			multiply_matrix(&mat,lpDevice->view_mat,lpDevice->world_mat);
			multiply_matrix(&mat,lpDevice->proj_mat,&mat);

			for (nb = 0; nb < ci->dwCount; nb++) {
			    /* Normals transformation */
			    nx = (src->u4.nx * mat2->_11) + (src->u5.ny * mat2->_21) + (src->u6.nz * mat2->_31);
			    ny = (src->u4.nx * mat2->_12) + (src->u5.ny * mat2->_22) + (src->u6.nz * mat2->_32);
			    nz = (src->u4.nx * mat2->_13) + (src->u5.ny * mat2->_23) + (src->u6.nz * mat2->_33);
			    
			    /* No lighting yet */
			    dst->u5.color = 0xFFFFFFFF; /* Opaque white */
			    dst->u6.specular = 0xFF000000; /* No specular and no fog factor */
			    
			    dst->u7.tu  = src->u7.tu;
			    dst->u8.tv  = src->u8.tv;
			    
			    /* Now, the matrix multiplication */
			    dst->u1.sx = (src->u1.x * mat._11) + (src->u2.y * mat._21) + (src->u3.z * mat._31) + (1.0 * mat._41);
			    dst->u2.sy = (src->u1.x * mat._12) + (src->u2.y * mat._22) + (src->u3.z * mat._32) + (1.0 * mat._42);
			    dst->u3.sz = (src->u1.x * mat._13) + (src->u2.y * mat._23) + (src->u3.z * mat._33) + (1.0 * mat._43);
			    dst->u4.rhw = (src->u1.x * mat._14) + (src->u2.y * mat._24) + (src->u3.z * mat._34) + (1.0 * mat._44);

			    dst->u1.sx = dst->u1.sx / dst->u4.rhw * Viewport->dwWidth / 2
				       + Viewport->dwX + Viewport->dwWidth / 2;
			    dst->u2.sy = dst->u2.sy / dst->u4.rhw * Viewport->dwHeight / 2
				       + Viewport->dwY + Viewport->dwHeight / 2;
			    dst->u3.sz /= dst->u4.rhw;
			    dst->u4.rhw = 1 / dst->u4.rhw;

			    src++;
			    dst++;
			    
			}
		    } else if (ci->dwFlags == D3DPROCESSVERTICES_TRANSFORM) {
		        int nb;
			D3DLVERTEX *src  = ((LPD3DLVERTEX) ((char *)This->desc.lpData + vs)) + ci->wStart;
			D3DTLVERTEX *dst = ((LPD3DTLVERTEX) (This->vertex_data)) + ci->wDest;
			D3DMATRIX mat;
			D3DVIEWPORT* Viewport = &lpViewport->viewports.vp1;
			
			if (TRACE_ON(ddraw)) {
			    TRACE("  Projection Matrix : (%p)\n", lpDevice->proj_mat);
			    dump_D3DMATRIX(lpDevice->proj_mat);
			    TRACE("  View       Matrix : (%p)\n", lpDevice->view_mat);
			    dump_D3DMATRIX(lpDevice->view_mat);
			    TRACE("  World Matrix : (%p)\n", &mat);
			    dump_D3DMATRIX(&mat);
			}

			multiply_matrix(&mat,lpDevice->view_mat,lpDevice->world_mat);
			multiply_matrix(&mat,lpDevice->proj_mat,&mat);

			for (nb = 0; nb < ci->dwCount; nb++) {
			    dst->u5.color = src->u4.color;
			    dst->u6.specular = src->u5.specular;
			    dst->u7.tu = src->u6.tu;
			    dst->u8.tv = src->u7.tv;
			    
			    /* Now, the matrix multiplication */
			    dst->u1.sx = (src->u1.x * mat._11) + (src->u2.y * mat._21) + (src->u3.z * mat._31) + (1.0 * mat._41);
			    dst->u2.sy = (src->u1.x * mat._12) + (src->u2.y * mat._22) + (src->u3.z * mat._32) + (1.0 * mat._42);
			    dst->u3.sz = (src->u1.x * mat._13) + (src->u2.y * mat._23) + (src->u3.z * mat._33) + (1.0 * mat._43);
			    dst->u4.rhw = (src->u1.x * mat._14) + (src->u2.y * mat._24) + (src->u3.z * mat._34) + (1.0 * mat._44);

			    dst->u1.sx /= dst->u4.rhw * Viewport->dvScaleX * Viewport->dwWidth / 2 + Viewport->dwX;
			    dst->u2.sy /= dst->u4.rhw * Viewport->dvScaleY * Viewport->dwHeight / 2 + Viewport->dwY;
			    dst->u3.sz /= dst->u4.rhw;
			    dst->u4.rhw = 1 / dst->u4.rhw;

			    src++;
			    dst++;
			}
		    } else if (ci->dwFlags == D3DPROCESSVERTICES_COPY) {
		        D3DTLVERTEX *src = ((LPD3DTLVERTEX) ((char *)This->desc.lpData + vs)) + ci->wStart;
			D3DTLVERTEX *dst = ((LPD3DTLVERTEX) (This->vertex_data)) + ci->wDest;
			
			memcpy(dst, src, ci->dwCount * sizeof(D3DTLVERTEX));
		    } else {
		        ERR("Unhandled vertex processing !\n");
		    }

		    instr += size;
		}
	    } break;

	    case D3DOP_TEXTURELOAD: {
	        WARN("TEXTURELOAD-s    (%d)\n", count);

		instr += count * size;
	    } break;

	    case D3DOP_EXIT: {
	        TRACE("EXIT             (%d)\n", count);
		/* We did this instruction */
		instr += size;
		/* Exit this loop */
		goto end_of_buffer;
	    } break;

	    case D3DOP_BRANCHFORWARD: {
	        int i;
		TRACE("BRANCHFORWARD    (%d)\n", count);

		for (i = 0; i < count; i++) {
		    LPD3DBRANCH ci = (LPD3DBRANCH) instr;

		    if ((This->data.dsStatus.dwStatus & ci->dwMask) == ci->dwValue) {
		        if (!ci->bNegate) {
			    TRACE(" Branch to %ld\n", ci->dwOffset);
			    instr = (char*)current + ci->dwOffset;
			    break;
			}
		    } else {
		        if (ci->bNegate) {
			    TRACE(" Branch to %ld\n", ci->dwOffset);
			    instr = (char*)current + ci->dwOffset;
			    break;
			}
		    }

		    instr += size;
		}
	    } break;

	    case D3DOP_SPAN: {
	        WARN("SPAN-s           (%d)\n", count);

		instr += count * size;
	    } break;

	    case D3DOP_SETSTATUS: {
	        int i;
		TRACE("SETSTATUS        (%d)\n", count);

		for (i = 0; i < count; i++) {
		    LPD3DSTATUS ci = (LPD3DSTATUS) instr;
		    
		    This->data.dsStatus = *ci;

		    instr += size;
		}
	    } break;

	    default:
	        ERR("Unhandled OpCode %d !!!\n",current->bOpcode);
	        /* Try to save ... */
	        instr += count * size;
	        break;
	}
    }

end_of_buffer:
    ;
}

HRESULT WINAPI
Main_IDirect3DExecuteBufferImpl_1_QueryInterface(LPDIRECT3DEXECUTEBUFFER iface,
                                                 REFIID riid,
                                                 LPVOID* obp)
{
    ICOM_THIS_FROM(IDirect3DExecuteBufferImpl, IDirect3DExecuteBuffer, iface);
    TRACE("(%p/%p)->(%s,%p)\n", This, iface, debugstr_guid(riid), obp);

    *obp = NULL;

    if ( IsEqualGUID( &IID_IUnknown,  riid ) ) {
        IDirect3DExecuteBuffer_AddRef(ICOM_INTERFACE(This, IDirect3DExecuteBuffer));
	*obp = iface;
	TRACE("  Creating IUnknown interface at %p.\n", *obp);
	return S_OK;
    }
    if ( IsEqualGUID( &IID_IDirect3DMaterial, riid ) ) {
        IDirect3DExecuteBuffer_AddRef(ICOM_INTERFACE(This, IDirect3DExecuteBuffer));
        *obp = ICOM_INTERFACE(This, IDirect3DExecuteBuffer);
	TRACE("  Creating IDirect3DExecuteBuffer interface %p\n", *obp);
	return S_OK;
    }
    FIXME("(%p): interface for IID %s NOT found!\n", This, debugstr_guid(riid));
    return OLE_E_ENUM_NOMORE;
}

ULONG WINAPI
Main_IDirect3DExecuteBufferImpl_1_AddRef(LPDIRECT3DEXECUTEBUFFER iface)
{
    ICOM_THIS_FROM(IDirect3DExecuteBufferImpl, IDirect3DExecuteBuffer, iface);
    FIXME("(%p/%p)->()incrementing from %lu.\n", This, iface, This->ref );
    return ++(This->ref);
}

ULONG WINAPI
Main_IDirect3DExecuteBufferImpl_1_Release(LPDIRECT3DEXECUTEBUFFER iface)
{
    ICOM_THIS_FROM(IDirect3DExecuteBufferImpl, IDirect3DExecuteBuffer, iface);
    TRACE("(%p/%p)->()decrementing from %lu.\n", This, iface, This->ref);
    if (!--(This->ref)) {
        if ((This->desc.lpData != NULL) && This->need_free)
	    HeapFree(GetProcessHeap(),0,This->desc.lpData);
	if (This->vertex_data != NULL)
	    HeapFree(GetProcessHeap(),0,This->vertex_data);
	if (This->indices != NULL)
	    HeapFree(GetProcessHeap(),0,This->indices);
	HeapFree(GetProcessHeap(),0,This);
	return 0;
    }

    return This->ref;
}

HRESULT WINAPI
Main_IDirect3DExecuteBufferImpl_1_Initialize(LPDIRECT3DEXECUTEBUFFER iface,
                                             LPDIRECT3DDEVICE lpDirect3DDevice,
                                             LPD3DEXECUTEBUFFERDESC lpDesc)
{
    ICOM_THIS_FROM(IDirect3DExecuteBufferImpl, IDirect3DExecuteBuffer, iface);
    TRACE("(%p/%p)->(%p,%p) no-op....\n", This, iface, lpDirect3DDevice, lpDesc);
    return DD_OK;
}

HRESULT WINAPI
Main_IDirect3DExecuteBufferImpl_1_Lock(LPDIRECT3DEXECUTEBUFFER iface,
                                       LPD3DEXECUTEBUFFERDESC lpDesc)
{
    ICOM_THIS_FROM(IDirect3DExecuteBufferImpl, IDirect3DExecuteBuffer, iface);
    DWORD dwSize;
    TRACE("(%p/%p)->(%p)\n", This, iface, lpDesc);

    dwSize = lpDesc->dwSize;
    memset(lpDesc, 0, dwSize);
    memcpy(lpDesc, &This->desc, dwSize);
    
    if (TRACE_ON(ddraw)) {
        TRACE("  Returning description : \n");
	_dump_D3DEXECUTEBUFFERDESC(lpDesc);
    }
    return DD_OK;
}

HRESULT WINAPI
Main_IDirect3DExecuteBufferImpl_1_Unlock(LPDIRECT3DEXECUTEBUFFER iface)
{
    ICOM_THIS_FROM(IDirect3DExecuteBufferImpl, IDirect3DExecuteBuffer, iface);
    TRACE("(%p/%p)->() no-op...\n", This, iface);
    return DD_OK;
}

HRESULT WINAPI
Main_IDirect3DExecuteBufferImpl_1_SetExecuteData(LPDIRECT3DEXECUTEBUFFER iface,
                                                 LPD3DEXECUTEDATA lpData)
{
    ICOM_THIS_FROM(IDirect3DExecuteBufferImpl, IDirect3DExecuteBuffer, iface);
    DWORD nbvert;
    TRACE("(%p/%p)->(%p)\n", This, iface, lpData);

    memcpy(&This->data, lpData, lpData->dwSize);

    /* Get the number of vertices in the execute buffer */
    nbvert = This->data.dwVertexCount;
    
    /* Prepares the transformed vertex buffer */
    if (This->vertex_data != NULL)
        HeapFree(GetProcessHeap(), 0, This->vertex_data);
    This->vertex_data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, nbvert * sizeof(D3DTLVERTEX));

    if (TRACE_ON(ddraw)) {
        _dump_executedata(lpData);
    }

    return DD_OK;
}

HRESULT WINAPI
Main_IDirect3DExecuteBufferImpl_1_GetExecuteData(LPDIRECT3DEXECUTEBUFFER iface,
                                                 LPD3DEXECUTEDATA lpData)
{
    ICOM_THIS_FROM(IDirect3DExecuteBufferImpl, IDirect3DExecuteBuffer, iface);
    DWORD dwSize;
    TRACE("(%p/%p)->(%p): stub!\n", This, iface, lpData);

    dwSize = lpData->dwSize;
    memset(lpData, 0, dwSize);
    memcpy(lpData, &This->data, dwSize);

    if (TRACE_ON(ddraw)) {
        TRACE("Returning data : \n");
	_dump_executedata(lpData);
    }

    return DD_OK;
}

HRESULT WINAPI
Main_IDirect3DExecuteBufferImpl_1_Validate(LPDIRECT3DEXECUTEBUFFER iface,
                                           LPDWORD lpdwOffset,
                                           LPD3DVALIDATECALLBACK lpFunc,
                                           LPVOID lpUserArg,
                                           DWORD dwReserved)
{
    ICOM_THIS_FROM(IDirect3DExecuteBufferImpl, IDirect3DExecuteBuffer, iface);
    FIXME("(%p/%p)->(%p,%p,%p,%08lx): stub!\n", This, iface, lpdwOffset, lpFunc, lpUserArg, dwReserved);
    return DD_OK;
}

HRESULT WINAPI
Main_IDirect3DExecuteBufferImpl_1_Optimize(LPDIRECT3DEXECUTEBUFFER iface,
                                           DWORD dwDummy)
{
    ICOM_THIS_FROM(IDirect3DExecuteBufferImpl, IDirect3DExecuteBuffer, iface);
    TRACE("(%p/%p)->(%08lx) no-op...\n", This, iface, dwDummy);
    return DD_OK;
}

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

ICOM_VTABLE(IDirect3DExecuteBuffer) VTABLE_IDirect3DExecuteBuffer =
{
    ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
    XCAST(QueryInterface) Main_IDirect3DExecuteBufferImpl_1_QueryInterface,
    XCAST(AddRef) Main_IDirect3DExecuteBufferImpl_1_AddRef,
    XCAST(Release) Main_IDirect3DExecuteBufferImpl_1_Release,
    XCAST(Initialize) Main_IDirect3DExecuteBufferImpl_1_Initialize,
    XCAST(Lock) Main_IDirect3DExecuteBufferImpl_1_Lock,
    XCAST(Unlock) Main_IDirect3DExecuteBufferImpl_1_Unlock,
    XCAST(SetExecuteData) Main_IDirect3DExecuteBufferImpl_1_SetExecuteData,
    XCAST(GetExecuteData) Main_IDirect3DExecuteBufferImpl_1_GetExecuteData,
    XCAST(Validate) Main_IDirect3DExecuteBufferImpl_1_Validate,
    XCAST(Optimize) Main_IDirect3DExecuteBufferImpl_1_Optimize,
};

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


HRESULT d3dexecutebuffer_create(IDirect3DExecuteBufferImpl **obj, IDirectDrawImpl *d3d, IDirect3DDeviceImpl *d3ddev, LPD3DEXECUTEBUFFERDESC lpDesc)
{
    IDirect3DExecuteBufferImpl* object;

    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DExecuteBufferImpl));

    ICOM_INIT_INTERFACE(object, IDirect3DExecuteBuffer, VTABLE_IDirect3DExecuteBuffer);
    
    object->ref = 1;
    object->d3d = d3d;
    object->d3ddev = d3ddev;

    /* Initializes memory */
    memcpy(&object->desc, lpDesc, lpDesc->dwSize);

    /* No buffer given */
    if ((object->desc.dwFlags & D3DDEB_LPDATA) == 0)
        object->desc.lpData = NULL;

    /* No buffer size given */
    if ((lpDesc->dwFlags & D3DDEB_BUFSIZE) == 0)
        object->desc.dwBufferSize = 0;

    /* Create buffer if asked */
    if ((object->desc.lpData == NULL) && (object->desc.dwBufferSize > 0)) {
        object->need_free = TRUE;
	object->desc.lpData = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,object->desc.dwBufferSize);
    } else {
        object->need_free = FALSE;
    }

    /* No vertices for the moment */
    object->vertex_data = NULL;

    object->desc.dwFlags |= D3DDEB_LPDATA;

    object->execute = execute;

    object->indices = NULL;
    object->nb_indices = 0;

    *obj = object;
    
    TRACE(" creating implementation at %p.\n", *obj);
    
    return DD_OK;
}
