#ifndef ABSTRACTION_HEADERFILE
#define ABSTRACTION_HEADERFILE

#include "Lookuptable.h"



#define MAX_NUM_OF_INPUT_VALUES 10
#define MAX_NUM_OF_SCORES		10


//abstraction methods
#define NUM_OF_ABSTRACTIONS 2
#define ABSTRACTION_METHOD_NOT_SPECIFIED 0
#define ABSTRACTION_LOOKUPTABLE			 1


#define MAX_NUM_OF_LOOKUPTABLES 5

class AbstractionModule : public Unit {
//class AbstractionModule : public Module {

	private:
		unsigned int abstraction_method;

		unsigned int num_of_lookuptables;
		Lookuptable* list_lookuptables[MAX_NUM_OF_LOOKUPTABLES];
		bool flag_lookuptable_exist[MAX_NUM_OF_LOOKUPTABLES];

		unsigned int lookuptable_to_use;




		//TODO: lut factor

		//private functions
		void initialize_abstraction(Lookuptable* lut, unsigned int abstraction_method);

		bool abstract_via_lookuptable(float input, int* output);
		bool abstract_via_factorized_lookuptable_and_condition_variable();
		bool abstract_via_lookuptables_and_condition_variable();




		//unsigned int num_of_slaveagents;
		//unsigned int num_of_sensors;

		/*
		int abstracted_data;
		bool flag_input_data_float_is_in_use[MAX_NUM_OF_INPUT_VALUES];
		float input_data_float[MAX_NUM_OF_INPUT_VALUES];
		*/

		/*
		bool flag_input_data_int_is_in_use[MAX_NUM_OF_INPUT_VALUES];
		int input_data_int[MAX_NUM_OF_INPUT_VALUES];
		*/

	public:
		AbstractionModule(Lookuptable* lut, unsigned int abstraction_method);
		AbstractionModule(char* name, Lookuptable* lut, unsigned int abstraction_method);

		bool set_abstraction_method(unsigned int abstraction_method);
		unsigned int get_abstraction_method();

		//TODO irgendwie muss man wissen an welcher position das is .. geht also im moment nur mit einer lookupttable
		bool add_lookuptable(Lookuptable* lut);
		bool get_flag_lookuptable_exist(unsigned int position);
		Lookuptable* get_lookuptable(unsigned int position);

		/*
		void set_num_of_slaveagents(unsigned int num_of_slaveagents);
		unsigned int get_num_of_slaveagents();

		void set_num_of_sensors(unsigned int num_of_sensors);
		unsigned int get_num_of_sensors();
		*/
		/*
		bool set_input_parameter(unsigned int position, int input_parameter);
		bool set_input_parameter(unsigned int position, float input_parameter);
		bool get_input_parameter(unsigned int position, int* input_parameter);
		bool get_input_parameter(unsigned int position, float* input_parameter);
		*/

		bool abstract(float input, int* output);

		//bool add_score_to_input_data_lookuptable(unsigned int position, float lower_boundary, float upper_boundary, int score, bool flag_lower_boundary_exist, bool flag_upper_boundary_exist, bool flag_lower_boundary_included, bool flag_upper_boundary_included);
};

#endif