#include "Sensor.h"
#include <stdio.h>

//unsigned int Sensor :: number_of_sensors = 0;

void Sensor :: initialize_sensor() {
	this->flag_masteragent_is_mounted = UNMOUNTED;
	this->flag_masteragent_outputport_is_active = INACTIVE;
	this->flag_sensor_value_is_valid = INVALID;
	this->flag_sensor_value_has_changed = NO;
	this->flag_send_value_only_when_changed = NO;

	workingCycleCounter = 1;
}

Sensor :: Sensor() {
	set_name(NO_NAME);
	initialize_sensor();
}

Sensor :: Sensor(char* name) {
	set_name(name);
	initialize_sensor();
}


// ----- Runtime Functions -----
void Sensor :: set_sensorValue(float sensor_value) {
	
	if (sensor_value != sensor_value) { //If NaN
		if (flag_sensor_value_is_valid == true) {
			// don't do anything .. just keep old value
		}
		else {
			this->sensor_value = 0; //xxx - don't know if 0 is the best default value.. but in the beginning of a dataset, it most likely won't affact anything
		}
	}
	else {
		if (flag_sensor_value_is_valid == true) {
			if (this->sensor_value != sensor_value) {
				flag_sensor_value_has_changed = YES;
			}
		}

		flag_sensor_value_is_valid = VALID;
		this->sensor_value = sensor_value;
	}
	

	
	
	
	//printf("Sensor %s updated with: %f\n", name, sensor_value);
}

float Sensor :: get_sensorValue() {
	return sensor_value;
}

void Sensor :: trigger() {
	if (workingCycleCounter == 1) {
		//TODO: difference int and float
		if(this->flag_sensor_value_is_valid && this->flag_masteragent_is_mounted && this->flag_masteragent_outputport_is_active){
			if(flag_send_value_only_when_changed) {
				if(flag_sensor_value_has_changed) {
					mounted_masteragent_outputport->send_MsgUp(sensor_value);
					flag_sensor_value_has_changed = NO;
				}
			}
			else {
				mounted_masteragent_outputport->send_MsgUp(sensor_value);
				flag_sensor_value_has_changed = NO;
			}
		}
	}

	if (workingCycleCounter < get_workingCycle())
		workingCycleCounter++;
	else
		workingCycleCounter = 1;
}


// ----- Setup Functions -----
bool Sensor :: mount_agent(Channel* outputport) {
	if(outputport != NULL) {
		this->mounted_masteragent_outputport = outputport;
		this->flag_masteragent_is_mounted = MOUNTED;
		this->flag_masteragent_outputport_is_active = ACTIVE;
		return true;
	}
	return false;
}

void Sensor :: set_flag_send_value_only_when_changed(bool flag_send_value_only_when_changed) {
	this->flag_send_value_only_when_changed = flag_send_value_only_when_changed;
}

bool Sensor :: get_flag_send_value_only_when_changed() {
	return this->flag_send_value_only_when_changed;
}

// ----- set/get -----
void Sensor :: set_flag_sensor_value_is_valid(bool flag_sensor_value_is_valid) {
	this->flag_sensor_value_is_valid = flag_sensor_value_is_valid;
}

bool Sensor :: get_flag_sensor_value_is_valid() {
	return this->flag_sensor_value_is_valid;
}

void Sensor :: set_flag_sensor_value_has_changed(bool flag_sensor_value_has_changed) {
	this->flag_sensor_value_has_changed = flag_sensor_value_has_changed;
}

bool Sensor :: get_flag_sensor_value_has_changed()  {
	return this->flag_sensor_value_has_changed;
}














/*
void Sensor :: set_sensor_id(unsigned int id) {
	sensor_id = id;
}
unsigned int Sensor :: get_sensor_id() {
	return sensor_id;
}*/



void Sensor :: set_active_state_flag(bool flag) {
	active_state_flag = flag;
}
bool Sensor :: get_active_state_flag() {
	return active_state_flag;
}

/*
void Sensor :: set_number_of_scores (unsigned int number) {
	number_of_scores = number;
}
unsigned int Sensor :: get_number_of_scores() {
	return number_of_scores;
}
*/
float Sensor :: get_hardcoded_threshold(unsigned int score, unsigned int boundary) {
	return hardcoded_thresholds[score][boundary];
}
void Sensor :: set_hardcoded_threshold(unsigned int score, unsigned int boundary, float value) {
	hardcoded_thresholds[score][boundary] = value;
}

float Sensor :: get_learned_threshold(unsigned int score, unsigned int boundary) {
	return learned_thresholds[score][boundary];
}
void Sensor :: set_learned_threshold(unsigned int score, unsigned int boundary, float value) {
	learned_thresholds[score][boundary] = value;
}

void Sensor :: set_flag_learned_boundary_exist(unsigned int score, unsigned int boundary, bool flag) {
	flag_learned_boundary_exist[score][boundary] = flag;
}
bool Sensor :: get_flag_learned_boundary_exist(unsigned int score, unsigned int boundary) {
	return flag_learned_boundary_exist[score][boundary];
}

void Sensor :: set_flag_use_learned_data(bool flag) {
	flag_use_learned_data = flag;
}
bool Sensor :: get_flag_use_learned_data() {
	return flag_use_learned_data;
}
