#include "Sensor.h"
#include <stdio.h>

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;
}

Sensor::Sensor() {
  set_name(NO_NAME);
  initialize_sensor();
}

Sensor::Sensor(const char *name) {
  set_name(name);
  initialize_sensor();
}

// ----- Runtime Functions -----
void Sensor::set_sensorValue(float sensor_value) {
  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() {
  // 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;
    }
  }
}

// ----- 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_active_state_flag(bool flag) { active_state_flag = flag; }
bool Sensor::get_active_state_flag() { return active_state_flag; }

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; }
