/**
 * @file
 * $Id$
 * $Revision$
 * $Author$
 * $Date$
 *
 * This file is part of The iWear Framework.
 * In particular this file is part of the Framework Context Library
 *
 * The iWear Framework is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by the
 * Free Software Foundation as in version 2 of the License.

 * 
 * The iWear Framework is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 * more details.
 * 
 * You should have received a copy of the GNU General Public License along with
 * The iWear Framework; if not, write to the Free Software Foundation, Inc., 59
 * Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include <iwear-context/sensorcontext.h>

namespace iwear{
namespace context {

    SensorContext::SensorContext(const string& name, 
		  SensorType sensor_type,
		  double comp_value,
		  Comparison comparison,
		  units unit,
		  double accuracy)
	: AtomicContext(name, SENSOR),
	  sensor_type(sensor_type), 
	  comp_value(comp_value),
	  comparison(comparison), 
	  unit(unit), 
	  accuracy(accuracy)
    {
	related_datasensor_type = map_to_datasensor_type(sensor_type);
	
	if(comparison < 0 || comparison >= num_Comparison){
	    stringstream error_msg; 
	    error_msg << "Invalid argument in SensorContext::SensorContext"
		      << "we have an invalid comparison-operator.";
	    throw invalidargument_error(error_msg.str(), comparison );
	}
	
	if(accuracy < 0){
	    stringstream error_msg; 
	    error_msg << "Invalid argument in SensorContext::SensorContext."
		      << "Accuracy should not be lower than zero.";
	    throw invalidargument_error(error_msg.str(), accuracy);
	}

	sensor_event_functor = NULL;

	d_dbg << ANSI_GREEN << __FFL__ << ":\n\t" << ANSI_NORMAL 
	      << "created sensor context " 
	      << this->name << endl;	
    }

    SensorContext::~SensorContext(void){
	if(sensor_event_functor != NULL){
	    delete sensor_event_functor;
	}
    }

    iwear::sensor::datasensor_type SensorContext::map_to_datasensor_type(SensorType sensor_type){
	switch(sensor_type){
	    case TEMPERATURE:
		return iwear::sensor::temperature;
		break;
	    case LOUDNESS:
		return iwear::sensor::loudness;
		break;
	    case BRIGHTNESS:
		return iwear::sensor::brightness;
		break;
	    case TIME:
		return iwear::sensor::time_data;
		break;
	    case SYSLOAD:
		return iwear::sensor::sysload_data;
		break;
	    case num_SensorType:
		return iwear::sensor::num_datasensor_type;
		break;
	    default:
		return iwear::sensor::num_datasensor_type;
		break;
	}
	return iwear::sensor::num_datasensor_type;
    }

    double SensorContext::get_lower(void){
	switch(comparison){
	case EQUALS:
	    return comp_value - accuracy - 0.00000001;
	    break;
	case NOT_EQUALS: 
	    {
		// there is nothing in the sensormanager that would fit here...
		stringstream error_msg; 
		error_msg << "Invalid argument in SensorContext::get_lower"
			  << "we have an invalid comparison-operator: "
			  << "NOT_EQUALS";
		throw invalidargument_error(error_msg.str(), comparison);
	    }
	    break;
	case GREATER:
	    return comp_value;
	    break;
	case LOWER:
	    return numeric_limits<double>::min();
	    break;
	case GREATER_EQUALS:
	    return comp_value - 0.00000001;
	    break;
	case LOWER_EQUALS:
	    return numeric_limits<double>::min();
	    break;
	default:
	    {
		stringstream error_msg; 
		error_msg << "Invalid argument in SensorContext::get_lower"
			  << "we have an invalid comparison-operator: "
			  << to_string(comparison);
		throw invalidargument_error(error_msg.str(), comparison);
	    }
	}
    }

    double SensorContext::get_upper(void){
	switch(comparison){
	    case EQUALS:
		return comp_value + accuracy + 0.00000001;
		break;
	    case NOT_EQUALS:
		{
		// there is nothing in the sensormanager that would fit here...
		    stringstream error_msg; 
		    error_msg << "Invalid argument in SensorContext::get_upper"
			      << "we have an invalid comparison-operator: "
			      << "NOT_EQUALS";
		    throw invalidargument_error(error_msg.str(), comparison);
		}
		break;
	    case GREATER:
		return numeric_limits<double>::max();
		break;
	    case LOWER:
		return comp_value;
		break;
	    case GREATER_EQUALS:
		return numeric_limits<double>::max();
		break;
	    case LOWER_EQUALS:
		return comp_value + 0.00000001;
		break;
	    default:
		{
		    stringstream error_msg; 
		    error_msg << "Invalid argument in SensorContext::get_upper"
			      << "we have an invalid comparison-operator: "
			      << to_string(comparison);
		    throw invalidargument_error(error_msg.str(), comparison);
		}		
	}
    }
} // namespace context
} // namespace iwear

