////////////////////////////////////////////////////////
//
// GEM - Graphics Environment for Multimedia
//
// mdanks@cybermed.ucsd.edu
//
// Implementation file
//
//    Copyright (c) 1997-1998 Mark Danks.
//    For information on usage and redistribution, and for a DISCLAIMER OF ALL
//    WARRANTIES, see the file, "GEM.LICENSE.TERMS" in this distribution.
//
/////////////////////////////////////////////////////////

#include "world_light.h"

#include "Base/GemMan.h"

CPPEXTERN_NEW(world_light)

/////////////////////////////////////////////////////////
//
// world_light
//
/////////////////////////////////////////////////////////
// Constructor
//
/////////////////////////////////////////////////////////
world_light :: world_light()
{
    m_color[0] = m_color[1] = m_color[2] = m_color[3] = 1.0;

    m_position[0] = 0.0;
    m_position[1] = 0.0;
    m_position[2] = 1.0;
    m_position[3] = 0.0;

    m_light = GemMan::requestLight();    
    m_on = 1;
    m_dirty = 1;
    m_windowNumber = GemMan::windowNumber();
    
    // create the color inlet
    inlet_new(this->x_obj, &this->x_obj->ob_pd, gensym("list"), gensym("clrlist"));
}

/////////////////////////////////////////////////////////
// Destructor
//
/////////////////////////////////////////////////////////
world_light :: ~world_light()
{
    if (m_light) GemMan::freeLight(m_light);
}

/////////////////////////////////////////////////////////
// lightOnOffMess
//
/////////////////////////////////////////////////////////
void world_light :: lightOnOffMess(int state)
{
    m_on = state;
    m_dirty = 1;
    setModified();
}

/////////////////////////////////////////////////////////
// lightColorMess
//
/////////////////////////////////////////////////////////
void world_light :: lightColorMess(float red, float green, float blue)
{
    m_color[0] = red;
    m_color[1] = green;
    m_color[2] = blue;
    m_dirty = 1;
    setModified();
}

/////////////////////////////////////////////////////////
// render
//
/////////////////////////////////////////////////////////
void world_light :: render(GemState *state)
{
    if (m_windowNumber != GemMan::windowNumber())
    {
    	m_dirty = 1;
    	m_windowNumber = GemMan::windowNumber();
    }
    if (!m_dirty || !state->lighting || !m_light) return;

    m_dirty = 0;
    if ( !m_on )
    {
    	glDisable(m_light);
    	return;
    }

    glEnable(m_light);
    glLightfv(m_light, GL_POSITION, m_position);
    glLightfv(m_light, GL_DIFFUSE,  m_color);
    glLightfv(m_light, GL_SPECULAR, m_color);
}

/////////////////////////////////////////////////////////
// static member functions
//
/////////////////////////////////////////////////////////
void world_light :: obj_setupCallback(t_class *classPtr)
{
    class_addmethod(classPtr, (t_method)&world_light::lightColorMessCallback,
    	    gensym("clrlist"), A_FLOAT, A_FLOAT, A_FLOAT, A_NULL);

    class_addint(classPtr, (t_method)&world_light::lightOnOffMessCallback);
}
void world_light :: lightColorMessCallback(void *data, t_floatarg red, t_floatarg green, t_floatarg blue)
{
    GetMyClass(data)->lightColorMess((float)red, (float)green, (float)blue);
}
void world_light :: lightOnOffMessCallback(void *data, int n)
{
    GetMyClass(data)->lightOnOffMess(n);
}
