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


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

#include "mesa_private.h"

DEFAULT_DEBUG_CHANNEL(ddraw);
    
#define D3DLPRIVATE(x) mesa_d3dl_private*dlpriv=((mesa_d3dl_private*)x->private)

static ICOM_VTABLE(IDirect3DLight) light_vtable;

enum {
  D3D_1,
  D3D_2
};

/*******************************************************************************
 *				Light static functions
 */
static const float zero_value[] = {
  0.0, 0.0, 0.0, 0.0
};

static void update(IDirect3DLightImpl* This) {
  D3DLPRIVATE(This);
  switch (This->light.dltType) {
  case D3DLIGHT_POINT:         /* 1 */
    TRACE("Activating POINT\n");
    break;
    
  case D3DLIGHT_SPOT:          /* 2 */
    TRACE("Activating SPOT\n");
    break;
    
  case D3DLIGHT_DIRECTIONAL: {  /* 3 */
    float direction[4];
    
    TRACE("Activating DIRECTIONAL\n");
    TRACE("  direction : %f %f %f\n",
	  This->light.dvDirection.u1.x,
	  This->light.dvDirection.u2.y,
	  This->light.dvDirection.u3.z);
    _dump_colorvalue(" color    ", This->light.dcvColor);

    glLightfv(dlpriv->light_num, GL_AMBIENT, (float *) zero_value);
    glLightfv(dlpriv->light_num, GL_DIFFUSE, (float *) &(This->light.dcvColor));

    direction[0] = -This->light.dvDirection.u1.x;
    direction[1] = -This->light.dvDirection.u2.y;
    direction[2] = -This->light.dvDirection.u3.z;
    direction[3] = 0.0; /* This is a directional light */

    glLightfv(dlpriv->light_num, GL_POSITION, (float *) direction);
  } break;
    
  case D3DLIGHT_PARALLELPOINT:  /* 4 */
    TRACE("Activating PARRALLEL-POINT\n");
    break;

  default:
    TRACE("Not a known Light Type: %d\n",This->light.dltType);
    break;
  }
}

static void activate(IDirect3DLightImpl* This) {
  D3DLPRIVATE(This);

  ENTER_GL();
  update(This);
  /* If was not active, activate it */
  if (This->is_active == 0) {
    glEnable(dlpriv->light_num);
    This->is_active = 1;
  }
  LEAVE_GL();

  return ;
}

/*******************************************************************************
 *				Light Creation functions
 */
LPDIRECT3DLIGHT d3dlight_create(IDirect3D2Impl* d3d2)
{
  IDirect3DLightImpl* light;
  
  light = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirect3DLightImpl));
  light->ref = 1;
  ICOM_VTBL(light) = &light_vtable;
  light->d3d.d3d2 = d3d2;
  light->type = D3D_2;

  light->next = NULL;
  light->prev = NULL;
  light->activate = activate;
  light->is_active = 0;
  
  return (LPDIRECT3DLIGHT)light;
}

LPDIRECT3DLIGHT d3dlight_create_dx3(IDirect3DImpl* d3d1)
{
  IDirect3DLightImpl* light;
  
  light = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirect3DLightImpl));
  light->ref = 1;
  ICOM_VTBL(light) = &light_vtable;
  
  light->d3d.d3d1 = d3d1;
  light->type = D3D_1;
  
  light->next = NULL;
  light->prev = NULL;
  light->activate = activate;
  light->is_active = 0;
  
  return (LPDIRECT3DLIGHT)light;
}

/*******************************************************************************
 *				IDirect3DLight methods
 */

static HRESULT WINAPI IDirect3DLightImpl_QueryInterface(LPDIRECT3DLIGHT iface,
						    REFIID riid,
						    LPVOID* ppvObj)
{
  ICOM_THIS(IDirect3DLightImpl,iface);
  
  FIXME("(%p)->(%s,%p): stub\n", This, debugstr_guid(riid),ppvObj);
  
  return S_OK;
}



static ULONG WINAPI IDirect3DLightImpl_AddRef(LPDIRECT3DLIGHT iface)
{
  ICOM_THIS(IDirect3DLightImpl,iface);
  TRACE("(%p)->()incrementing from %lu.\n", This, This->ref );
  
  return ++(This->ref);
}



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

/*** IDirect3DLight methods ***/
static void dump_light(LPD3DLIGHT light)
{
  DPRINTF("  dwSize : %ld\n", light->dwSize);
}

static HRESULT WINAPI IDirect3DLightImpl_GetLight(LPDIRECT3DLIGHT iface,
					      LPD3DLIGHT lpLight)
{
  ICOM_THIS(IDirect3DLightImpl,iface);
  TRACE("(%p)->(%p)\n", This, lpLight);
  if (TRACE_ON(ddraw))
    dump_light(lpLight);
  
  /* Copies the light structure */
  switch (This->type) {
  case D3D_1:
    *((LPD3DLIGHT)lpLight) = *((LPD3DLIGHT) &(This->light));
    break;
  case D3D_2:
    *((LPD3DLIGHT2)lpLight) = *((LPD3DLIGHT2) &(This->light));
    break;
  }
  
  return DD_OK;
}

static HRESULT WINAPI IDirect3DLightImpl_SetLight(LPDIRECT3DLIGHT iface,
					      LPD3DLIGHT lpLight)
{
  ICOM_THIS(IDirect3DLightImpl,iface);
  TRACE("(%p)->(%p)\n", This, lpLight);
  if (TRACE_ON(ddraw))
    dump_light(lpLight);
  
  /* Stores the light */
  switch (This->type) {
  case D3D_1:
    *((LPD3DLIGHT) &(This->light)) = *((LPD3DLIGHT)lpLight);
    break;
  case D3D_2:
    *((LPD3DLIGHT2) &(This->light)) = *((LPD3DLIGHT2)lpLight);
    break;
  }
  
  ENTER_GL();
  if (This->is_active)
    update(This);
  LEAVE_GL();
  
  return DD_OK;
}

static HRESULT WINAPI IDirect3DLightImpl_Initialize(LPDIRECT3DLIGHT iface,
						LPDIRECT3D lpDirect3D)

{
  ICOM_THIS(IDirect3DLightImpl,iface);
  TRACE("(%p)->(%p)\n", This, lpDirect3D);

  return DDERR_ALREADYINITIALIZED;
}


/*******************************************************************************
 *				IDirect3DLight VTable
 */
static ICOM_VTABLE(IDirect3DLight) light_vtable = 
{
  ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
  /*** IUnknown methods ***/
  IDirect3DLightImpl_QueryInterface,
  IDirect3DLightImpl_AddRef,
  IDirect3DLightImpl_Release,
  /*** IDirect3DLight methods ***/
  IDirect3DLightImpl_Initialize,
  IDirect3DLightImpl_SetLight,
  IDirect3DLightImpl_GetLight
};
