/* 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.x.x,
	  This->light.dvDirection.y.y,
	  This->light.dvDirection.z.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.x.x;
    direction[1] = -This->light.dvDirection.y.y;
    direction[2] = -This->light.dvDirection.z.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
};
