#include "Agent.h"
#include "printError.h"
#include <stdio.h>

//TODO: Move this include to ControlModule
#include "instruction_set_architecture.h"

#define PRINT_READING

void Agent :: init_agent() {
	sensorHandlerOfAgent = NULL;
	slaveAgentHandlerOfAgent = NULL;
	masterAgentHandlerOfAgent = NULL;
}

Agent :: Agent() {
	set_name(NO_NAME);
	init_agent();
}

Agent :: Agent(const char* name) {
	set_name(name);
	init_agent();

}

bool Agent :: set_sensorHandlerOfAgent() {
	sensorHandlerOfAgent = new SensorHandlerOfAgent();

	if(sensorHandlerOfAgent == NULL) {
		printError("Couldn't create Sensor Handler!");
		return false;
	}
	return true;
}

bool Agent :: del_sensorHandlerOfAgent() {
	if(sensorHandlerOfAgent != NULL) {
		//TODO: Unmount/delete all sensorSlots with everything inside (history module, confidence module, ...)
		delete sensorHandlerOfAgent;
		return true;
	}
	return false;
}

SensorHandlerOfAgent* Agent :: get_sensorHandlerOfAgent() {
	if(sensorHandlerOfAgent == NULL) {
		set_sensorHandlerOfAgent();
	}
	return sensorHandlerOfAgent;
}

bool Agent :: set_slaveAgentHandlerOfAgent() {
	slaveAgentHandlerOfAgent = new SlaveAgentHandlerOfAgent();

	if(slaveAgentHandlerOfAgent == NULL) {
		printError("Couldn't create Slave Agent Handler!");
		return false;
	}
	return true;
}

bool Agent :: del_slaveAgentHandlerOfAgent() {
	if(slaveAgentHandlerOfAgent != NULL) {
		//TODO: Unmount/delete all SlaveAgentSlots with everything inside (history module, confidence module, ...)
		delete slaveAgentHandlerOfAgent;
		return true;
	}
	return false;
}

SlaveAgentHandlerOfAgent* Agent :: get_slaveAgentHandlerOfAgent() {
	if(slaveAgentHandlerOfAgent == NULL) {
		set_slaveAgentHandlerOfAgent();
	}
	return slaveAgentHandlerOfAgent;
}

bool Agent :: set_masterAgentHandlerOfAgent() {
	masterAgentHandlerOfAgent = new MasterAgentHandlerOfAgent();

	if(masterAgentHandlerOfAgent == NULL) {
		printError("Couldn't create Master Agent Handler!");
		return false;
	}
	return true;
}

bool Agent :: del_masterAgentHandlerOfAgent() {
	if(masterAgentHandlerOfAgent != NULL) {
		//TODO: Unmount/delete (all) MasterAgentSlot(s) with everything inside
		delete masterAgentHandlerOfAgent;
		return true;
	}
	return false;
}

MasterAgentHandlerOfAgent* Agent :: get_masterAgentHandlerOfAgent() {
	if(masterAgentHandlerOfAgent == NULL) {
		set_masterAgentHandlerOfAgent();
	}
	return masterAgentHandlerOfAgent;
}

void Agent :: trigger() {
	
	//TODO: make control_module to set the method of operating for each agent individual

	//Job: Read all sensory data
	if(sensorHandlerOfAgent != NULL) {
		printf("%s->sensorHandler: ", name);
		sensorHandlerOfAgent->read_allSensorValues();
	}

	//Job: Read all slave agent data
	if(slaveAgentHandlerOfAgent != NULL) {
		printf("%s->slaveAgentHandler: ", name);
		slaveAgentHandlerOfAgent->read_allSlaveAgentValues();
	}

	//Job: Just pass the Sensory Data (without abstraction) to master
	if(masterAgentHandlerOfAgent != NULL) {
		if(sensorHandlerOfAgent != NULL) {
			vector<SensorSlotOfAgent*>* vSensoryData = sensorHandlerOfAgent->get_vMountedSensors();
			for(auto &sensorSlot : *vSensoryData) {
				//TODO: also for int
				float sensorValue;
				if(sensorSlot->get_sensorValue(&sensorValue)) {
					masterAgentHandlerOfAgent->pass_msgToSendBuffer(ISA_SensoryData);
					masterAgentHandlerOfAgent->pass_msgToSendBuffer(sensorValue);
				}
			}
		}
		masterAgentHandlerOfAgent->send_msgs();
	}

}

