/* Direct3D Material
   (c) 1998 Lionel ULMER
   
   This files contains the implementation of Direct3DMaterial2. */

#include "config.h"
#include "windef.h"
#include "winerror.h"
#include "wine/obj_base.h"
#include "heap.h"
#include "ddraw.h"
#include "d3d.h"
#include "debug.h"

#include "d3d_private.h"

DEFAULT_DEBUG_CHANNEL(ddraw)

#ifdef HAVE_MESAGL

static ICOM_VTABLE(IDirect3DMaterial2) material2_vtable;
static ICOM_VTABLE(IDirect3DMaterial) material_vtable;

/*******************************************************************************
 *				Matrial2 static functions
 */
static void activate(IDirect3DMaterial2Impl* This) {
  TRACE(ddraw, "Activating material %p\n", This);
  
  /* First, set the rendering context */
  if (This->use_d3d2)
    This->device.active_device2->set_context(This->device.active_device2);
  else
    This->device.active_device1->set_context(This->device.active_device1);

  /* Set the current Material */
  _dump_colorvalue("Diffuse", This->mat.a.diffuse);
  glMaterialfv(GL_FRONT,
	       GL_DIFFUSE,
	       (float *) &(This->mat.a.diffuse));
  _dump_colorvalue("Ambient", This->mat.b.ambient);
  glMaterialfv(GL_FRONT,
	       GL_AMBIENT,
	       (float *) &(This->mat.b.ambient));
  _dump_colorvalue("Specular", This->mat.c.specular);
  glMaterialfv(GL_FRONT,
	       GL_SPECULAR,
	       (float *) &(This->mat.c.specular));
  _dump_colorvalue("Emissive", This->mat.d.emissive);
  glMaterialfv(GL_FRONT,
	       GL_EMISSION,
	       (float *) &(This->mat.d.emissive));
  
  TRACE(ddraw, "Size  : %ld\n", This->mat.dwSize);
  TRACE(ddraw, "Power : %f\n", This->mat.e.power);

  TRACE(ddraw, "Texture handle : %08lx\n", (DWORD)This->mat.hTexture);
  
  return ;
}

/*******************************************************************************
 *				Matrial2 Creation functions
 */
LPDIRECT3DMATERIAL2 d3dmaterial2_create(IDirect3D2Impl* d3d2)
{
  IDirect3DMaterial2Impl* mat;
  
  mat = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirect3DMaterial2Impl));
  mat->ref = 1;
  mat->lpvtbl = &material2_vtable;

  mat->use_d3d2 = 1;
  mat->d3d.d3d2 = d3d2;

  mat->activate = activate;
  
  return (LPDIRECT3DMATERIAL2)mat;
}

LPDIRECT3DMATERIAL d3dmaterial_create(IDirect3DImpl* d3d1)
{
  IDirect3DMaterial2Impl* mat;
  
  mat = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirect3DMaterial2Impl));
  mat->ref = 1;
  mat->lpvtbl = (ICOM_VTABLE(IDirect3DMaterial2)*)&material_vtable;

  mat->use_d3d2 = 0;
  mat->d3d.d3d1 = d3d1;

  mat->activate = activate;
  
  return (LPDIRECT3DMATERIAL) mat;
}

/*******************************************************************************
 *				IDirect3DMaterial2 methods
 */

static HRESULT WINAPI IDirect3DMaterial2Impl_QueryInterface(LPDIRECT3DMATERIAL2 iface,
							REFIID riid,
							LPVOID* ppvObj)
{
  ICOM_THIS(IDirect3DMaterial2Impl,iface);
  char xrefiid[50];
  
  WINE_StringFromCLSID((LPCLSID)riid,xrefiid);
  FIXME(ddraw, "(%p)->(%s,%p): stub\n", This, xrefiid,ppvObj);
  
  return S_OK;
}



static ULONG WINAPI IDirect3DMaterial2Impl_AddRef(LPDIRECT3DMATERIAL2 iface)
{
  ICOM_THIS(IDirect3DMaterial2Impl,iface);
  TRACE(ddraw, "(%p)->()incrementing from %lu.\n", This, This->ref );
  
  return ++(This->ref);
}



static ULONG WINAPI IDirect3DMaterial2Impl_Release(LPDIRECT3DMATERIAL2 iface)
{
  ICOM_THIS(IDirect3DMaterial2Impl,iface);
  FIXME( ddraw, "(%p)->() decrementing from %lu.\n", This, This->ref );
  
  if (!--(This->ref)) {
    HeapFree(GetProcessHeap(),0,This);
    return 0;
  }
  
  return This->ref;
}

/*** IDirect3DMaterial2 methods ***/
static void dump_material(LPD3DMATERIAL mat)
{
  fprintf(stderr, "  dwSize : %ld\n", mat->dwSize);
}

static HRESULT WINAPI IDirect3DMaterial2Impl_GetMaterial(LPDIRECT3DMATERIAL2 iface,
						     LPD3DMATERIAL lpMat)
{
  ICOM_THIS(IDirect3DMaterial2Impl,iface);
  TRACE(ddraw, "(%p)->(%p)\n", This, lpMat);
  if (TRACE_ON(ddraw))
    dump_material(lpMat);
  
  /* Copies the material structure */
  *lpMat = This->mat;
  
  return DD_OK;
}

static HRESULT WINAPI IDirect3DMaterial2Impl_SetMaterial(LPDIRECT3DMATERIAL2 iface,
						     LPD3DMATERIAL lpMat)
{
  ICOM_THIS(IDirect3DMaterial2Impl,iface);
  TRACE(ddraw, "(%p)->(%p)\n", This, lpMat);
  if (TRACE_ON(ddraw))
    dump_material(lpMat);
  
  /* Stores the material */
  This->mat = *lpMat;
  
  return DD_OK;
}

static HRESULT WINAPI IDirect3DMaterial2Impl_GetHandle(LPDIRECT3DMATERIAL2 iface,
						   LPDIRECT3DDEVICE2 lpD3DDevice2,
						   LPD3DMATERIALHANDLE lpMatHandle)

{
  ICOM_THIS(IDirect3DMaterial2Impl,iface);
  FIXME(ddraw, "(%p)->(%p,%p): stub\n", This, lpD3DDevice2, lpMatHandle);

  if (This->use_d3d2)
    This->device.active_device2 = (IDirect3DDevice2Impl*)lpD3DDevice2;
  else
    This->device.active_device1 = (IDirect3DDeviceImpl*)lpD3DDevice2;
  
  *lpMatHandle = (DWORD) This; /* lpD3DDevice2->store_material(This); */
  
  return DD_OK;
}

static HRESULT WINAPI IDirect3DMaterialImpl_Reserve(LPDIRECT3DMATERIAL iface)
{
  ICOM_THIS(IDirect3DMaterial2Impl,iface);
  FIXME(ddraw, "(%p)->(): stub\n", This);

  return DDERR_INVALIDPARAMS;
}
						  
static HRESULT WINAPI IDirect3DMaterialImpl_Unreserve(LPDIRECT3DMATERIAL iface)
{
  ICOM_THIS(IDirect3DMaterial2Impl,iface);
  FIXME(ddraw, "(%p)->(): stub\n", This);

  return DDERR_INVALIDPARAMS;
}

static HRESULT WINAPI IDirect3DMaterialImpl_Initialize(LPDIRECT3DMATERIAL iface,
						   LPDIRECT3D lpDirect3D)

{
  ICOM_THIS(IDirect3DMaterial2Impl,iface);
  TRACE(ddraw, "(%p)->(%p)\n", This, lpDirect3D);
  
  return DDERR_ALREADYINITIALIZED;
}


/*******************************************************************************
 *				IDirect3DMaterial VTable
 */
static ICOM_VTABLE(IDirect3DMaterial) material_vtable = {
  /*** IUnknown methods ***/
  IDirect3DMaterial2Impl_QueryInterface,
  IDirect3DMaterial2Impl_AddRef,
  IDirect3DMaterial2Impl_Release,
  /*** IDirect3DMaterial methods ***/
  IDirect3DMaterialImpl_Initialize,
  IDirect3DMaterial2Impl_SetMaterial,
  IDirect3DMaterial2Impl_GetMaterial,
  IDirect3DMaterial2Impl_GetHandle,
  IDirect3DMaterialImpl_Reserve,
  IDirect3DMaterialImpl_Unreserve
};


/*******************************************************************************
 *				IDirect3DMaterial2 VTable
 */
static ICOM_VTABLE(IDirect3DMaterial2) material2_vtable = {
  /*** IUnknown methods ***/
  IDirect3DMaterial2Impl_QueryInterface,
  IDirect3DMaterial2Impl_AddRef,
  IDirect3DMaterial2Impl_Release,
  /*** IDirect3DMaterial methods ***/
  IDirect3DMaterial2Impl_SetMaterial,
  IDirect3DMaterial2Impl_GetMaterial,
  IDirect3DMaterial2Impl_GetHandle
};

#else /* HAVE_MESAGL */

LPDIRECT3DMATERIAL d3dmaterial_create(IDirect3DImpl* d3d1) {
  ERR(ddraw, "Should not be called...\n");
  return NULL;
}

LPDIRECT3DMATERIAL2 d3dmaterial2_create(IDirect3D2Impl* d3d2) {
  ERR(ddraw, "Should not be called...\n");
  return NULL;
}


#endif /* HAVE_MESAGL */
