/***************************************************************************
 *   Copyright (C) 2004 by Raphael Langerhorst                             *
 *   raphael-langerhorst@gmx.at                                            *
 *                                                                         *
 *   Permission is hereby granted, free of charge, to any person obtaining *
 *   a copy of this software and associated documentation files (the       *
 *   "Software"), to deal in the Software without restriction, including   *
 *   without limitation the rights to use, copy, modify, merge, publish,   *
 *   distribute, sublicense, and/or sell copies of the Software, and to    *
 *   permit persons to whom the Software is furnished to do so, subject to *
 *   the following conditions:                                             *
 *                                                                         *
 *   The above copyright notice and this permission notice shall be        *
 *   included in all copies or substantial portions of the Software.       *
 *                                                                         *
 *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       *
 *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    *
 *   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*
 *   IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR     *
 *   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, *
 *   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR *
 *   OTHER DEALINGS IN THE SOFTWARE.                                       *
 ***************************************************************************/

#include "GEnergyFormAgent.h"

#include <GEnergy.h>
#include <GForm.h>
#include <GObject.h>

#include <exception>

using namespace GCS;
using namespace std;

namespace GBE
{

GEnergyFormAgent::GEnergyFormAgent()
{
}


GEnergyFormAgent::~GEnergyFormAgent()
{
}

void GEnergyFormAgent::run()
{
  if (requestObject()->hasEnergy() && requestObject()->hasForm())
  {
    while(!shutdown)
    {
      bool ok;
      double LevelRangeMin = xmlGetDouble("/appearance/energyrange/minlevel",ok);
      double LevelRangeMax = xmlGetDouble("/appearance/energyrange/maxlevel",ok);
      
      GVector3 FormFactor = xmlGetVector3("/form/sizefactor",ok);
      
      if (!ok)
      {
        qWarning("size factor was not found in element data, initializing to 1,1,1");
        FormFactor.set(1,1,1);
        initSizeFactor(FormFactor);
      }
      
      if (LevelRangeMax - LevelRangeMin <= 0)
      {
        qDebug("wrong range settings: min is " + QString::number(LevelRangeMin) + ", max is "  + QString::number(LevelRangeMax));
        qDebug(" falling back to default range 0 to 10");
        LevelRangeMin = 0;
        LevelRangeMax = 10;
        initRangeMin(LevelRangeMin);
        initRangeMax(LevelRangeMax);
      }
      
      bool size_enabled = xmlGetFlag("/form/sizefactor/enabled",ok);
      if (!ok)
      {
        qWarning("size factor enable flag was not found, initializing to true");
        initSizeFactorEnabled(true);
      }
      
      bool colour_enabled = xmlGetFlag("/appearance/colour/enabled",ok);
      if (!ok)
      {
        qWarning("colour enable flag was not found, initializing to true");
        initColourEnabled(true);
      }
      
      GForm* f = requestForm();
      GEnergy* e = requestEnergy();
      
      if (colour_enabled)
      {
        double half_range = (LevelRangeMax - LevelRangeMin)*0.5;
        double middle_value = LevelRangeMin + half_range;
        double half_range_inv = 1/half_range;
        
        //we want a default value for the blue component
        xmlSetDouble("/appearance/colour/b",0.5,ok);
        
        if (e->level() > middle_value)
        {
          xmlSetDouble("/appearance/colour/r",(e->level() - middle_value)*half_range_inv,ok);
          xmlSetDouble("/appearance/colour/g",1,ok);
        }
        else
        {
          xmlSetDouble("/appearance/colour/r",0,ok);
          xmlSetDouble("/appearance/colour/g",1-(middle_value - e->level())*half_range_inv,ok);
        }
      }
      
      if (size_enabled)
      {
        //the radius of the form should represent the amount of the energy
        f->Ellipsoid = (FormFactor*e->amount());
      }
      
      //we update every second by default
      msleep(1000);
    }
    
  }
}

void GEnergyFormAgent::initRangeMin(double energy_range_min)
{
  bool ok;
  xmlSetDouble("/appearance/energyrange/minlevel",energy_range_min,ok);
}

void GEnergyFormAgent::initRangeMax(double energy_range_max)
{
  bool ok;
  xmlSetDouble("/appearance/energyrange/maxlevel",energy_range_max,ok);
}

void GEnergyFormAgent::initAlpha(double alpha_colour_component)
{
  bool ok;
  xmlSetDouble("/appearance/colour/a",alpha_colour_component,ok);
}

void GEnergyFormAgent::initSizeFactor(const GVector3& size_factor)
{
  bool ok;
  xmlSetVector3("/form/sizefactor",size_factor,ok);
}

void GEnergyFormAgent::initColourEnabled(bool enabled)
{
  bool ok;
  xmlSetFlag("/appearance/colour/enabled",enabled,ok);
}

void GEnergyFormAgent::initSizeFactorEnabled(bool enabled)
{
  bool ok;
  xmlSetFlag("/form/sizefactor/enabled",enabled,ok);
}

};


syntax highlighted by Code2HTML, v. 0.9.1