#include "create_unit.h"
#include <stdio.h>
#include "errno.h"
#include "rlutil.h"

using namespace rlutil;

void print_agent(Agent agent) {
	
}

Agent* create_agent() {
	return create_agent(NO_NAME);
}

Agent* create_agent(char* name) {
	Agent* agent = new Agent(name);
#ifdef PRINT	
	printf(" > Agent ");
	setColor(TXTCOLOR_LIGHTCYAN);
	printf("%s ", agent->get_name());
	setColor(TXTCOLOR_GREY);
	printf("(id: %03u) ", agent->get_id());
	setColor(TXTCOLOR_LIGHTGREEN);
	printf("created\n");
	setColor(TXTCOLOR_GREY);
#endif // PRINT
	return agent;
}


Sensor* create_sensor() {
	return create_sensor(NO_NAME);
}

Sensor* create_sensor(char* name) {
	Sensor* sensor = new Sensor(name);
#ifdef PRINT	
	printf(" > Sensor ");
	setColor(TXTCOLOR_LIGHTCYAN);
	printf("%s ", sensor->get_name());
	setColor(TXTCOLOR_GREY);
	printf("(id: %03u) ", sensor->get_id());
	setColor(TXTCOLOR_LIGHTGREEN);
	printf("created\n");
	setColor(TXTCOLOR_GREY);
#endif //  PRINT
	return sensor;
}


HistoryModule create_historyModule(unsigned int history_length, int delimitation_mode) {
	return create_historyModule(NO_NAME, history_length, delimitation_mode);
}

HistoryModule create_historyModule(char* name, unsigned int history_length, int delimitation_mode) {
	
	HistoryModule historyModule(name);
#ifdef PRINT	
	printf(" > History ");
	setColor(TXTCOLOR_LIGHTCYAN);
	printf("%s ", historyModule.get_name());
	setColor(TXTCOLOR_GREY);
	printf("(id: %03u) ", historyModule.get_id());
	setColor(TXTCOLOR_LIGHTGREEN);
	printf("created\n");
	setColor(TXTCOLOR_GREY);
#endif //  PRINT
	if(historyModule.set_maxHistoryLength(history_length)) {
#ifdef PRINT
		printf("   > History length ");
		setColor(TXTCOLOR_LIGHTGREEN);
		printf("set ");
		setColor(TXTCOLOR_GREY);
		printf("to %u\n", history_length);
#endif //  PRINT
	}
	else {
		setColor(TXTCOLOR_LIGHTRED);
		printf("   > historyLength could not set (out of allowed range).");
		setColor(TXTCOLOR_GREY);
	}
	if(historyModule.set_delimitationMode(delimitation_mode)) {
#ifdef PRINT
		printf("   > Delimitation Mode ");
		setColor(TXTCOLOR_LIGHTGREEN);
		printf("set ");
		setColor(TXTCOLOR_GREY);
		printf("to %u\n", delimitation_mode);
#endif //  PRINT
	}
	else {
		setColor(TXTCOLOR_LIGHTRED);
		printf("   > Delimitation Mode could not set (out of allowed range).");
		setColor(TXTCOLOR_GREY);
	}

	return historyModule;
}

Channel* create_channel(unsigned int transfer_rate) {
	return create_channel(NO_NAME, transfer_rate);
}

Channel* create_channel(char* name, unsigned int transfer_rate) {

	Channel* channel = new Channel(name);
#ifdef PRINT
	printf(" > Channel ");
	setColor(TXTCOLOR_LIGHTCYAN);
	printf("%s ", channel->get_name());
	setColor(TXTCOLOR_GREY);
	printf("(id: %03u) ", channel->get_id());
	setColor(TXTCOLOR_LIGHTGREEN);
	printf("created\n");
	setColor(TXTCOLOR_GREY);
#endif // PRINT
	if(channel->set_transferRate(transfer_rate)) {
		if(transfer_rate != 0) {
#ifdef  PRINT
			printf("   > transfer rate ");
			setColor(TXTCOLOR_LIGHTGREEN);
			printf("set ");
			setColor(TXTCOLOR_GREY);
			printf("to %i\n", transfer_rate);
#endif // PRINT
		}
		else {
#ifdef  PRINT
			printf("   > transfer ");
			setColor(TXTCOLOR_LIGHTGREEN);
			printf("set ");
			setColor(TXTCOLOR_GREY);
			printf("to immediately transportation\n");
#endif //  PRINT
		}
	}
	else {
#ifdef  PRINT
		setColor(TXTCOLOR_LIGHTRED);
		printf("   > Transfer Rate out of allowed bounds!\n");
		setColor(TXTCOLOR_GREY);
#endif //  PRINT
	}

	return channel;
}




Testbench* create_testbench() {
	return create_testbench(NO_NAME);
}

Testbench* create_testbench(char* name) {
	Testbench* testbench = new Testbench(name);
#ifdef PRINT
	printf(" > ");
	rlutil::setColor(TXTCOLOR_LIGHTCYAN);
	printf("%s ", testbench->get_name());
	rlutil::setColor(TXTCOLOR_GREY);
	printf("(id: %03u) ", testbench->get_id());
	rlutil::setColor(TXTCOLOR_LIGHTGREEN);
	printf("created\n");
	rlutil::setColor(TXTCOLOR_GREY);
#endif // PRINT
	testbench->init_testbench();
	return testbench;
}

/*
Lookuptable create_lookuptable() {
	Lookuptable lut;

	printf(" > ");
	rlutil::setColor(TXTCOLOR_LIGHTCYAN);
	printf("%s ", lut.get_name());
	rlutil::setColor(TXTCOLOR_GREY);
	printf("(id: %03u) ", lut.get_id());
	rlutil::setColor(TXTCOLOR_LIGHTGREEN);
	printf("created\n");
	rlutil::setColor(TXTCOLOR_GREY);

	return lut;
}

Lookuptable create_lookuptable(char* name) {
	Lookuptable lut(name);

	printf(" > ");
	rlutil::setColor(TXTCOLOR_LIGHTCYAN);
	printf("%s ", lut.get_name());
	rlutil::setColor(TXTCOLOR_GREY);
	printf("(id: %03u) ", lut.get_id());
	rlutil::setColor(TXTCOLOR_LIGHTGREEN);
	printf("created\n");
	rlutil::setColor(TXTCOLOR_GREY);

	return lut;
}

void print_confidence_validator(Confidence_Validator conf_valid) {
	printf(" > ");
	rlutil::setColor(TXTCOLOR_LIGHTCYAN);
	printf("%s ", conf_valid.get_name());
	rlutil::setColor(TXTCOLOR_GREY);
	printf("(id: %03u) ", conf_valid.get_id());
	rlutil::setColor(TXTCOLOR_LIGHTGREEN);
	printf("created\n");
	rlutil::setColor(TXTCOLOR_GREY);

	printf("   - range of validity ");
	if(conf_valid.get_flag_lower_bound_exist())
		printf("[ %.3f, ", conf_valid.get_lower_bound());
	else
		printf("] -inf, ");
	if(conf_valid.get_flag_upper_bound_exist())
		printf("%.3f ] ", conf_valid.get_upper_bound());
	else
		printf("+inf [ ");
	rlutil::setColor(TXTCOLOR_LIGHTGREEN);
	printf("set\n");
	rlutil::setColor(TXTCOLOR_GREY);

	if(conf_valid.get_flag_rates_of_change_exist()) {
		printf("   - validity for rates of change of ");
		printf("%.3f ", conf_valid.get_rates_of_change());
		rlutil::setColor(TXTCOLOR_LIGHTGREEN);
		printf("set\n");
		rlutil::setColor(TXTCOLOR_GREY);
	}
}

Confidence_Validator create_confidence_validator(float lower_bound, bool flag_lower_bound_exist, float upper_bound, bool flag_upper_bound_exist, float rates_of_change, bool flag_rates_of_change_exist) {
	Confidence_Validator conf_valid(lower_bound, flag_lower_bound_exist, upper_bound, flag_upper_bound_exist, rates_of_change, flag_rates_of_change_exist);
	print_confidence_validator(conf_valid);

	return conf_valid;
}

Confidence_Validator create_confidence_validator(char* name, float lower_bound, bool flag_lower_bound_exist, float upper_bound, bool flag_upper_bound_exist, float rates_of_change, bool flag_rates_of_change_exist) {
	Confidence_Validator conf_valid(name, lower_bound, flag_lower_bound_exist, upper_bound, flag_upper_bound_exist, rates_of_change, flag_rates_of_change_exist);
	print_confidence_validator(conf_valid);

	return conf_valid;
}

void print_abstraction_module(Abstraction abstraction) {
	printf(" > ");
	rlutil::setColor(TXTCOLOR_LIGHTCYAN);
	printf("%s ", abstraction.get_name());
	rlutil::setColor(TXTCOLOR_GREY);
	printf("(id: %03u) ", abstraction.get_id());
	rlutil::setColor(TXTCOLOR_LIGHTGREEN);
	printf("created\n");
	rlutil::setColor(TXTCOLOR_GREY);

	//TODO: abstraction method printen
	printf("   - abstraction method %u ", abstraction.get_abstraction_method());
	rlutil::setColor(TXTCOLOR_LIGHTGREEN);
	printf("set\n");
	rlutil::setColor(TXTCOLOR_GREY);

	//TODO: auch das hier bissl sch�ner machen
	if(abstraction.get_flag_lookuptable_exist(0)) {
		printf("   - position 0 connected mit Look up Table ");
		rlutil::setColor(TXTCOLOR_LIGHTCYAN);
		printf("%s ", abstraction.get_lookuptable(0)->get_name());
		rlutil::setColor(TXTCOLOR_GREY);
		printf("(id: %03u) ", abstraction.get_lookuptable(0)->get_id());
		rlutil::setColor(TXTCOLOR_LIGHTGREEN);
		printf("set\n");
		rlutil::setColor(TXTCOLOR_GREY);
	}
} 

Abstraction create_abstraction_module(Lookuptable* lut, unsigned int abstraction_method) {
	Abstraction abstraction(lut, abstraction_method);
	print_abstraction_module(abstraction);

	return abstraction;
}

Abstraction create_abstraction_module(char* name, Lookuptable* lut, unsigned int abstraction_method) {
	Abstraction abstraction(name, lut, abstraction_method);
	print_abstraction_module(abstraction);

	return abstraction;
}

void print_bunch_module(Bunch_Module bunch_module) {
	printf(" > ");
	rlutil::setColor(TXTCOLOR_LIGHTCYAN);
	printf("%s ", bunch_module.get_name());
	rlutil::setColor(TXTCOLOR_GREY);
	printf("(id: %03u) ", bunch_module.get_id());
	rlutil::setColor(TXTCOLOR_LIGHTGREEN);
	printf("created\n");
	rlutil::setColor(TXTCOLOR_GREY);

	//TODO: abstraction method printen
	printf("   - abstraction method %u ", bunch_module.get_bunch_method());
	rlutil::setColor(TXTCOLOR_LIGHTGREEN);
	printf("set\n");
	rlutil::setColor(TXTCOLOR_GREY);
} 


Bunch_Module create_bunch_module(unsigned int bunch_method) {
	Bunch_Module bunch_module(bunch_method);
	print_bunch_module(bunch_module);

	return bunch_module;
}

Bunch_Module create_bunch_module(char* name, unsigned int bunch_method) {
	Bunch_Module bunch_module(name, bunch_method);
	print_bunch_module(bunch_module);

	return bunch_module;
}
*/

FILE* make_file_pointer(const char* filepath, int mode) {
	
    FILE* fpointer = nullptr;
	
	if(mode == CSV_MODE_READ) {
		// file_opened = fopen_s(&fpointer, filepath, "r"); //only windows compatible
        fpointer = fopen(filepath, "r");
	}
	else if(mode == CSV_MODE_WRITE) {
		// file_opened = fopen_s(&fpointer, filepath, "w"); //only windows compatible
		fpointer = fopen(filepath, "w"); 
	}
	else {
#ifdef PRINT
		printf("File pointer mode for \"%s\" ", filepath);
		rlutil::setColor(TXTCOLOR_LIGHTRED);
		printf("is not supported!\n");
		rlutil::setColor(TXTCOLOR_GREY);
#endif // PRINT
		return NULL;
	}

	//if(file_opened == 0) {
    if(fpointer != nullptr) {
		return fpointer;
	}
#ifdef PRINT
	printf("File pointer \"%s\" ", filepath);
	rlutil::setColor(TXTCOLOR_LIGHTRED);
	printf("could not created!\n");
	rlutil::setColor(TXTCOLOR_GREY);
#endif // PRINT
	return NULL;
}

void print_csv_reader(CSVreaderModule* csvReaderModule,const char* filepath) {
	printf(" > ");
	rlutil::setColor(TXTCOLOR_LIGHTCYAN);
	printf("%s ", csvReaderModule->get_name());
	rlutil::setColor(TXTCOLOR_GREY);
	printf("(id: %03u) for \"%s\" ", csvReaderModule->get_id(), filepath);
	rlutil::setColor(TXTCOLOR_LIGHTGREEN);
	printf("created\n");
	rlutil::setColor(TXTCOLOR_GREY);
}  

CSVreaderModule* create_CSVreaderModule(const char* filepath, unsigned int column, unsigned int start_row) {
	
	FILE* fpointer =  make_file_pointer(filepath, CSV_MODE_READ);

	if(fpointer) {
		CSVreaderModule* csvr = new CSVreaderModule(fpointer, column, start_row);
		print_csv_reader(csvr, filepath);
		
		return csvr;
	}
	else {
		CSVreaderModule* csvr = new CSVreaderModule();

		return csvr;
	}
}

CSVreaderModule* create_CSVreaderModule(char* name,const char* filepath, unsigned int column, unsigned int start_row) {
	
	FILE* fpointer =  make_file_pointer(filepath, CSV_MODE_READ);

	if(fpointer) {
		CSVreaderModule* csvr = new CSVreaderModule(name, fpointer, column, start_row);
#ifdef PRINT
		print_csv_reader(csvr, filepath);
#endif // PRINT
		return csvr;
	}
	else {
		CSVreaderModule* csvr = new CSVreaderModule;

		return csvr;
	}
}


StateHandler create_stateHandler() {
	return create_stateHandler(NO_NAME);
}

StateHandler create_stateHandler(char* name) {
	StateHandler stateHandler(name);
	return stateHandler;
}
