/*	Legacy Direct3DLight interface
 *
 * Copyright 2001 TransGaming Technologies Inc.
 */

#include "config.h"

#include <assert.h>
#include <stdlib.h>

#include "wine/debug.h"
#include "ddrawi.h"
#include "d3dhal.h"
#include "d3d_private.h"
#include "d3ddevice/main.h"

WINE_DEFAULT_DEBUG_CHANNEL(ddraw);

static ICOM_VTABLE(IDirect3DLight) IDirect3DLight_VTable;

/* Non-interface functions */
HRESULT
Direct3DLight_Construct(IDirect3DLightImpl* This,
			IDirectDrawImpl* pDD)
{
    This->ref = 1;
    This->d3d_owner = pDD;

    ICOM_INIT_INTERFACE(This, IDirect3DLight,
			IDirect3DLight_VTable);

    /* Direct3D_AddLight(This->d3d_owner, This); */

    return D3D_OK;
}

HRESULT
Direct3DLight_Create(IDirectDrawImpl *pDD,
		     LPDIRECT3DLIGHT *ppd3dl)
{
    IDirect3DLightImpl* This;
    HRESULT hr;

    This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
		     sizeof(*This));
    if (This == NULL) return E_OUTOFMEMORY;

    hr = Direct3DLight_Construct(This, pDD);
    if (FAILED(hr))
	HeapFree(GetProcessHeap(), 0, This);
    else
	*ppd3dl = ICOM_INTERFACE(This, IDirect3DLight);

    return hr;
}

static void Direct3DLight_Destroy(IDirect3DLightImpl* This)
{
    /* Direct3D_RemoveLight(This->d3d_owner, This); */
    HeapFree(GetProcessHeap(), 0, This);
}

void Direct3DLight_ForceDestroy(IDirect3DLightImpl* This)
{
    WARN("destroying 3D light %p with refcnt %lu\n", This, This->ref);
    Direct3DLight_Destroy(This);
}

/* Interface functions */
ULONG WINAPI Direct3DLight_Release(LPDIRECT3DLIGHT iface)
{
    ICOM_THIS(IDirect3DLightImpl, iface);

    if (--This->ref == 0)
    {
	Direct3DLight_Destroy(This);
	return 0;
    }

    return This->ref;
}

ULONG WINAPI Direct3DLight_AddRef(LPDIRECT3DLIGHT iface)
{
    ICOM_THIS(IDirect3DLightImpl, iface);

    return ++This->ref;
}

HRESULT WINAPI
Direct3DLight_QueryInterface(LPDIRECT3DLIGHT iface, REFIID riid,
				  LPVOID* ppObj)
{
    ICOM_THIS(IDirect3DLightImpl, iface);
    TRACE("(%p)->(%s,%p)\n", This, debugstr_guid(riid), ppObj);

    return E_NOINTERFACE;
}

HRESULT WINAPI
Direct3DLight_Initialize(LPDIRECT3DLIGHT iface, LPDIRECT3D pd3d)
{
    ICOM_THIS(IDirect3DLightImpl, iface);
    TRACE("(%p)->(%p)\n", This, pd3d);
    return DDERR_ALREADYINITIALIZED;
}

HRESULT WINAPI
Direct3DLight_SetLight(LPDIRECT3DLIGHT iface, LPD3DLIGHT lpLight)
{
    static D3DCOLORVALUE zeroc = {{0},{0},{0},{0}};
    ICOM_THIS(IDirect3DLightImpl, iface);
    TRACE("(%p)->(%p)\n", This, lpLight);
    This->l.dltType        = lpLight->dltType;
    This->l.dcvDiffuse     = lpLight->dcvColor;
    This->l.dcvSpecular    = lpLight->dcvColor;
    This->l.dcvAmbient     = zeroc;
    This->l.dvPosition     = lpLight->dvPosition;
    This->l.dvDirection    = lpLight->dvDirection;
    This->l.dvRange        = lpLight->dvRange;
    This->l.dvFalloff      = lpLight->dvFalloff;
    This->l.dvAttenuation0 = lpLight->dvAttenuation0;
    This->l.dvAttenuation1 = lpLight->dvAttenuation1;
    This->l.dvAttenuation2 = lpLight->dvAttenuation2;
    This->l.dvTheta        = lpLight->dvTheta;
    This->l.dvPhi          = lpLight->dvPhi;

    if (This->view_owner) {
	IDirect3DViewportImpl* view = This->view_owner;
	if (view->bound && view->dev_owner)
	    IDirect3DDevice7_SetLight(ICOM_INTERFACE(view->dev_owner, IDirect3DDevice7),
				      This->view_index, &This->l);
    }

    return DD_OK;
}

HRESULT WINAPI
Direct3DLight_GetLight(LPDIRECT3DLIGHT iface, LPD3DLIGHT lpLight)
{
    ICOM_THIS(IDirect3DLightImpl, iface);
    TRACE("(%p)->(%p)\n", This, lpLight);
    lpLight->dltType        = This->l.dltType;
    lpLight->dcvColor       = This->l.dcvDiffuse;
    lpLight->dvPosition     = This->l.dvPosition;
    lpLight->dvDirection    = This->l.dvDirection;
    lpLight->dvRange        = This->l.dvRange;
    lpLight->dvFalloff      = This->l.dvFalloff;
    lpLight->dvAttenuation0 = This->l.dvAttenuation0;
    lpLight->dvAttenuation1 = This->l.dvAttenuation1;
    lpLight->dvAttenuation2 = This->l.dvAttenuation2;
    lpLight->dvTheta        = This->l.dvTheta;
    lpLight->dvPhi          = This->l.dvPhi;
    return DD_OK;
}

static ICOM_VTABLE(IDirect3DLight) IDirect3DLight_VTable =
{
    Direct3DLight_QueryInterface,
    Direct3DLight_AddRef,
    Direct3DLight_Release,
    Direct3DLight_Initialize,
    Direct3DLight_SetLight,
    Direct3DLight_GetLight
};
