/*****************************************************************************
* Create list of light sorces initialized for use with rendering.	     *
******************************************************************************
* (C) Gershon Elber, Technion, Israel Institute of Technology                *
******************************************************************************
* Written by:  Bassarab Dmitri & Plavnik Michael       Ver 0.2, Apr. 1995    *
*****************************************************************************/

#include "program.h"

/*****************************************************************************
* DESCRIPTION:                                                               *
*   Scans object list and counts light sources in it. Two light sources      *
*   interpreted as two different light sources.                              *
*                                                                            *
* PARAMETERS:                                                                *
*   Object:  IN, linked list of Irit objects get from the dat file.          *
*                                                                            *
* RETURN VALUE:                                                              *
*   int:  number of light sources in the list of objects.                    *
*                                                                            *
*****************************************************************************/
static int CountLights(IPObjectStruct *Object)
{
    int n;
    for (n = 0; Object; Object = Object -> Pnext)
        if (AttrGetObjectIntAttrib(Object, "LIGHT_SOURCE") != IP_ATTR_BAD_INT){
            n++;
            if (AttrGetObjectIntAttrib(Object, "TWOLIGHT") != IP_ATTR_BAD_INT)
                n++;
	}
    return n;
}

/*****************************************************************************
* DESCRIPTION:                                                               *
*   Creates default light sources.                                           *
*                                                                            *
* PARAMETERS:                                                                *
*   Lights:   OUT, pointer to LightList object which is initialized through. *
*                                                                            *
* RETURN VALUE:                                                              *
*   void                                                                     *
*****************************************************************************/
static void MakeDefaultLights(LightListStruct *Lights)
{
    static PointType
	ThreeOne = { 1., 1., 1. };

    Lights -> n = 2;
    Lights -> src = MALLOC(LightStruct, Lights -> n);
    Lights -> src[0].type = VECTOR_LIGHT;
    PT_COPY(Lights -> src[0].where, ThreeOne);
    PT_NORMALIZE(Lights -> src[0].where);
    PT_COPY(Lights -> src[0].color, ThreeOne);
    Lights -> src[1] = Lights -> src[0];
    PT_SCALE(Lights -> src[1].where, -1.);
}

/*****************************************************************************
* DESCRIPTION:                                                               M
*   Creates vector-list of light sources and initalizes every one of them    M
*   (dynamic dispatch also).                                                 M
*                                                                            *
* PARAMETERS:                                                                M
*   Lights:   OUT, pointer to LightList object which is initialized through. M
*   Objects:  IN, linked list of Irit objects get from the dat file.         M
*                                                                            *
* RETURN VALUE:                                                              M
*   IPObjectStruct *: pointer to objects list.                               M
*                                                                            *
* KEYWORDS:                                                                  M
*   GatherLights, light source                                               M
*****************************************************************************/
IPObjectStruct *GatherLights(LightListStruct *Lights, IPObjectStruct *Objects)
{
    IPObjectStruct *o;
    LightStruct *l;
    char *t;
    int r, g, b;

    Lights -> n = CountLights(Objects);
    if (!Lights -> n) {
        MakeDefaultLights(Lights);
	return Objects;
    }
    Lights -> src = l = MALLOC(LightStruct, Lights -> n);
    for (o = Objects; o; o = o -> Pnext)
        if (AttrGetObjectIntAttrib(o, "LIGHT_SOURCE") != IP_ATTR_BAD_INT){
            t = AttrGetObjectStrAttrib(o, "TYPE");
            if (!t || stricmp(t, "POINT_POS")) {
                l -> type = VECTOR_LIGHT;
                l -> descriptor = &Context.VectorLightDescriptor;
            }
	    else {
                l -> type = POINT_LIGHT;
                l -> descriptor = &Context.PointLightDescriptor;
            }
            PT_COPY(l -> where, o -> U.Pt);
            if (l -> type == VECTOR_LIGHT)
                PT_NORMALIZE(l -> where);
            l -> shadow = Options.Shadows &&
	        (AttrGetObjectIntAttrib(o, "SHADOW") != IP_ATTR_BAD_INT);
            if (AttrGetObjectRGBColor(o, &r, &g, &b)) {
                l -> color[R] = r;
                l -> color[G] = g;
                l -> color[B] = b;
                PT_SCALE(l -> color, 1. / 0xff);
            }
	    else
                l -> color[R] = l -> color[G] = l -> color[B] = 1.;
            if (AttrGetObjectIntAttrib(o, "TWOLIGHT") != IP_ATTR_BAD_INT) {
                *(l + 1) = *l;
                ++l;
                PT_SCALE(l -> where, -1);
            }
            ++l;
        }
    return Objects;
}
