// LightEnvironment.cpp: Implementierung der Klasse LightEnvironment.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"

#include <vector>

#include "Vec.h"

#include "LightPoint.h"
#include "LightZone.h"

// MFC - Assists in finding memory leaks:
#ifdef MFC_DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

/*******************************************************************************
* Destruktor
*******************************************************************************/
LightZone::~LightZone()
{
for (int i =0; i < (int)lightPointList.size(); i++)
   {
   LightPoint* lp = lightPointList[i];
   delete (lp);
   }
}

/*******************************************************************************
* Konstruktor
* @param zone die Zone
*******************************************************************************/
LightZone::LightZone(int zone)
{
init(zone);
}

/*******************************************************************************
* Konstruktor
* @param zone die Zone
* @param ambient Wert f¸r das ambiente Licht (= const)
* @param directionalMax Maximalwert fuer direktes Licht
* @param pointMax Maximalwert fuer PointLights (bzw. die Summe aller PointLights)
*******************************************************************************/
LightZone::LightZone(int zone, float ambient, float directionalMax, float pointMax)
{
init(zone);
set(ambient,  directionalMax,  pointMax);
}

/*******************************************************************************
* Initialisiert das Objekt
* @param zone 
*******************************************************************************/
void LightZone::init(int zone)
{
m_dir.clear(); // = new Vec();
//lightPointList = new java.util.Vector();

m_zone = zone;

m_ambient = 1;
m_directionalMax = 0;
m_pointMax = 0;

setDirectionalLight(1, 1, 0.5);
}

/*******************************************************************************
* setter
* @param ambient Wert f¸r das ambiente Licht (= const)
* @param directionalMax Maximalwert fuer direktes Licht
* @param pointMax Macximalwert fuer Punktlicht
*******************************************************************************/
void LightZone::set(float ambient, float directionalMax, float pointMax)
{
float epsilon = 0.01f;

m_ambient = 1;
m_directionalMax = 0;
m_pointMax = 0;

float sum = ambient + directionalMax + pointMax;
if (sum > epsilon)
   {
   m_ambient =  ambient / sum;
   m_directionalMax = directionalMax / sum;
   m_pointMax = pointMax / sum;
   }
}

/*******************************************************************************
* Setzt die Richtung fuer das Direktional Light 
* @param dirX X-Komponente des Richtungsvektors fuer Directional Light
* @param dirY Y-Komponente des Richtungsvektors fuer Directional Light
* @param dirZ Z-Komponente des Richtungsvektors fuer Directional Light
*******************************************************************************/
void LightZone::setDirectionalLight(float dirX, float dirY, float dirZ)
{
m_dir.set(dirX, dirY, dirZ);
m_dir.normalize();
}

/*******************************************************************************
* Fuegt ein PointLight hinzu 
* @param posX X-Komponente der Position des PointLight
* @param posY Y-Komponente der Position des PointLight
* @param posZ Z-Komponente der Position des PointLight
*******************************************************************************/
void LightZone::addPointLight(float posX, float posY, float posZ)
{
LightPoint* pl = new LightPoint( posX, posY, posZ);
lightPointList.push_back(pl) ;
}

/*******************************************************************************
* liefert die Zone
* @return zone die ZoneNr
*******************************************************************************/
int LightZone::getZone(){return (m_zone);}

/*******************************************************************************
* liefert den max. Wert (normiert auf 1.0) fuer ambientes Licht fuer diese Zone
* @return max ambient Wert
*******************************************************************************/
float LightZone::getAmbient(){return (m_ambient);}
  
/*******************************************************************************
* liefert den max. Wert (normiert auf 1.0) fuer direktes Licht fuer diese Zone
* @return max directional Wert
*******************************************************************************/
float LightZone::getDirectionalMax(){return (m_directionalMax);}

/*******************************************************************************
* liefert den max. Wert (normiert auf 1.0) fuer Punktlicht fuer diese Zone
* @return max PointLight Wert
*******************************************************************************/
float LightZone::getPointMax(){return (m_pointMax);}

/*******************************************************************************
* Liefert Info, ob in dieser Zone PointLights beruecksichtigt werden muessen
* Nur wenn es PointLights in dieser Zone gibt UND der prozentuale Anteil am 
* restlichen Licht > 0.1 ist, muessen PointLights beruecksichtigt werden 
* @return true--> PointLights muessen berechnet werden 
*         false--> Keine PointLights
*******************************************************************************/
bool LightZone::hasPointLights()
{
if ((m_pointMax > 0.1) && (lightPointList.size() > 0))
   return (true);
return (false);
}

/*******************************************************************************
* 
*******************************************************************************/
void LightZone::dump()
{
/*
System.out.println("LightEnvironment m_zone=" + m_zone +
                   " m_ambient="        + m_ambient + 
                   " m_directionalMax=" + m_directionalMax +
                   " m_pointMax="       + m_pointMax);

System.out.println("DirectionalLight=" + m_dir.dump());

for (int i = 0; i < lightPointList.size(); i++)
   {
   LightPoint lp = (LightPoint)lightPointList.get(i);
   lp.dump();
   }
*/
}
