package version11_2_0.platform;

import version11_2_0.Interface.*;
import version11_2_0.display.*;
import version11_2_0.environment.*;
import version11_2_0.sensorySystem.*;
import version11_2_0.spaceMemory.*;
import version11_2_0.Main;

/**
 * whole learning mechanism
 * This class is used as a bridge between modules
 * @author simon gay
 */
public class Agent {

	public Action action;
	public Perception sensors;
	
	public Robot body;
	public Observer observer;
	public EnvironmentContext environmentContext;
	public SpaceMemory spaceMemory;
	
	//%%%%%%%%%%%%%%%%% specific to simulators %%%%%%%%%%%%%%%%%%%%%%%
	public Probe probe;
	public VisualSystem visual;
	//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
	
	public Decision decision;
	
	private Main main;
	
	private int ident;
	
	public Agent(int id, Main m){

		action=new Action(this);
		sensors=new Perception(this);
		
		body=new Robot();
		decision=new Decision(this);
		observer=new Observer(this);

		environmentContext=new EnvironmentContext(this);
		spaceMemory=new SpaceMemory(this);
		
		//%%%%%%%%%%%%%%%%% specific to simulators %%%%%%%%%%%%%%%%%%%%%%%
		probe=new Probe(this);
		visual=new VisualSystem(this);
		//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

		ident=id;
		
		main=m;
		
	}
	
	// enact a simulation substep
	public void act(){
		action.act();
	}
	
	public boolean isStopped(){
		return action.isStopped();
	}
	
	public int getIdent(){
		return ident;
	}
	
	public Main getMain(){
		return main;
	}
	
	//%%%%%%%%%%%%%%%%% specific to simulators %%%%%%%%%%%%%%%%%%%%%%%
	public void setPosition(float x, float y, float theta){
		body.setPosition(x,y,theta);
		observer.setPosition(x,y);
	}
	
	public void setEnvironment(Environment e){
		body.setEnvironment(e);
		probe.setEnvironment(e);
	}
	//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
	
	
	// initialize the set of panels related to the agent
	public void setDisplay(){
		
		boolean probeDisplay=false;
		boolean context=true;
		boolean signature=true;
		boolean space=false;
		boolean observer=false;
		
		int size;
		int i;
		boolean found;

		//////////////////////
		if (probeDisplay){
			size=main.display.nbFrame();
			i=0;
			found=false; 
			while (i<size && !found){
				if (main.display.get(i).getClass().getName().equals("version11_2_0.display.ProbeFrame")) found=true;
				i++;
			}
			if (!found) main.display.addFrame(new ProbeFrame(this));
			else        
				((ProbeFrame)main.display.get(i-1)).setAgent(this);
		}
		
		//////////////////////
		if (context){
			size=main.display.nbFrame();
			i=0;
			found=false;
			while (i<size && !found){
				if (main.display.get(i).getClass().getName().equals("version11_2_0.display.ContextFrame")) found=true;
				i++;
			}
			if (!found) main.display.addFrame(new ContextFrame(this));
			else        
				((ContextFrame)main.display.get(i-1)).setAgent(this);
		}
		
		//////////////////////
		if (signature){
			size=main.display.nbFrame();
			i=0;
			found=false;
			while (i<size && !found){
				if (main.display.get(i).getClass().getName().equals("version11_2_0.display.SignaturesFrame")) found=true;
				i++;
			}
			if (!found) main.display.addFrame(new SignaturesFrame(this));
			else        
				((SignaturesFrame)main.display.get(i-1)).setAgent(this);
		}
		
		//////////////////////
		if (space){
			size=main.display.nbFrame();
			i=0;
			found=false;
			while (i<size && !found){
				if (main.display.get(i).getClass().getName().equals("version11_2_0.display.SpaceFrame")) found=true;
				i++;
			}
			if (!found) main.display.addFrame(new SpaceFrame(this));
			else        
				((SpaceFrame)main.display.get(i-1)).setAgent(this);
		}
		
		//////////////////////
		if (observer){
			size=main.display.nbFrame();
			i=0;
			found=false;
			while (i<size && !found){
				if (main.display.get(i).getClass().getName().equals("version11_2_0.display.ObserverFrame")) found=true;
				i++;
			}
			if (!found) main.display.addFrame(new ObserverFrame(this));
			else        
				((ObserverFrame)main.display.get(i-1)).setAgent(this);
		}
	}

	// save modules data
	public void save() {
		environmentContext.save();
	}
	
	// save images from displayers
	public void saveImage(String path){
		main.saveImage(path);
	}
	
}
