package version11_2_2_2.platform;


/**
 * This class extract data about agents' behaviors for an external observer
 * @author simon gay
 */
public class Observer {

	private Agent agent;
	
	private int counter;								// number of completed decision cycle
	
	public int[] timelinePrimitive;					// sequence of enacted interactions (limited to the "length" last interactions)
	
	public static int length=200;						// length of the timeline
	
	//////////////////////////////////////////////////////
	
	public float[][] trace;							// sequence of previous positions of the agent
	public int[] interactionType;
	public static int pathLength=300;					//length of the trace
	
	//////////////////////////////////////////////////////
	private boolean picture=false;					// if true, frames associated to the agent can be saved as jpeg images (if allowed)
	private int frame;									// index of captured images
	
	private static int capture_delay=200;				// nb of decision cycles between two image captures
	public static String path=System.getProperty("user.home") +"/IDEAL/version11_2_2_2/";

	//////////////////////////////////////////////////////
	public int[] decisionType;							// type of decision (sensorimotor, learning, exploitation, random)
	public float[][] decisionValues;					// values given by learning and exploitation mechanisms
	public int index;									// index in the trace table
	
	public int[][] nbInteractions;
	
	private int counter1=0;
	public int index1=0;
	
	//////////////////////////////////////////////////////
	private XMLStreamTracer m_tracer;
	
	//////////////////////////////////////////////////////
	
	public Observer(Agent a){
		agent=a;
		
		timelinePrimitive=new int[length];
		for (int i=0;i<length;i++){
			timelinePrimitive[i]=-1;
		}
			
		// trace
		trace=new float[pathLength][2];
		interactionType=new int[pathLength];
		
		frame=0;
		counter=0;
		
		decisionType=new int[1000];
		decisionValues=new float[2][1000];
		index=0;
		
		nbInteractions=new int[3][1000];
		
		/*
		m_tracer=new XMLStreamTracer("http://134.214.128.53/abstract/lite/php/stream/",
				                     "dsyRyrlVFmaeVjpOdSDCeNPsGcmfwr");
		/**/
		
		/*
		m_tracer=new XMLStreamTracer("http://localhost/alite/php/stream/",
				                     "LUAsNP-QqEAStUfzDFwewQIPcwRlnM");
		/**/
	}
	
	public void updateObserver(int inter){
		
		/////////////////////////////////////////////////////////////
		// update timeline
		/////////////////////////////////////////////////////////////
		for (int i=length-1;i>0;i--){
			timelinePrimitive[i]=timelinePrimitive[i-1];
		}
		timelinePrimitive[0]=inter;
		
		
		/////////////////////////////////////////////////////////////
		// update trace
		/////////////////////////////////////////////////////////////
		for (int i=pathLength-1;i>0;i--){
			trace[i][0]=trace[i-1][0];
			trace[i][1]=trace[i-1][1];
			interactionType[i]=interactionType[i-1];
		}
		trace[0][0]=agent.body.getpx();
		trace[0][1]=agent.body.getpy();
		
		//if (inter.getAction().getId()==0) interactionType[0]=inter.getPerception().getId();	
		//else 						   interactionType[0]=2+inter.getAction().getId();
		
		interactionType[0]=inter;
		
		/////////////////////////////////////////////////////////////
		// screen shot
		/////////////////////////////////////////////////////////////
		
		if (picture){
			frame++;
			if (frame>=capture_delay){
				frame=0;
				agent.saveImage(Observer.path);
			}
		}
	}
	
	//////////////////////////////////////////////////////
	public void updateDecisionTrace(int type, float val1, float val2){
		decisionType[index]=type;
		decisionValues[0][index]=val1;
		decisionValues[1][index]=val2;
		
		if (counter1==400){
			nbInteractions[0][index1]=0;
			nbInteractions[1][index1]=0;
			nbInteractions[2][index1]=0;
			for (int i=0;i<agent.environmentContext.interactionList.length;i++){
				if (agent.environmentContext.interactionList[i]!=null && agent.environmentContext.interactionList[i].signature.learned&& agent.environmentContext.interactionList[i].isChange()){
					nbInteractions[0][index1]++;
					if (agent.environmentContext.interactionList[i].signature.delta_s<0.8 && agent.environmentContext.interactionList[i].signature.delta_f<0.8)nbInteractions[1][index1]++;
					if (agent.environmentContext.interactionList[i].signature.delta_s<0.7 && agent.environmentContext.interactionList[i].signature.delta_f<0.7)nbInteractions[2][index1]++;
				}
			}
			counter1=0;
			
			System.out.print("*********** "+nbInteractions[0][index1]+" ; "+nbInteractions[1][index1]+" ; "+nbInteractions[2][index1]);
			if (nbInteractions[0][index1]>0) System.out.println(" ; "+(nbInteractions[1][index1]/nbInteractions[0][index1]));
			else System.out.println();
			
			index1++;
			index1=index1%1000;
		}
		else counter1++;
		
		index++;
		index=index%1000;
		
	}
	
	//////////////////////////////////////////////////////
	// send data to Abstract-Lite module
	public void trace(){
		
		// abstract lite trace
		m_tracer.startNewEvent(counter);
		
		m_tracer.addEventElement("Source", "VacuumSG");
		m_tracer.addEventElement("clock", ""+counter);
		
		counter++;
		
		m_tracer.finishEvent();
	}
	
	// initialize every position of the trace to (x,y)
	public void setPosition(float x,float y){
		for (int i=0;i<pathLength;i++){
			trace[i][0]=x;
			trace[i][1]=y;
		}
	}
	
	// clear trace
	public void clearTrace(){
		setPosition(agent.body.getpx(),agent.body.getpy());
		for (int i=0;i<pathLength;i++){
			interactionType[i]=0;
		}
	}
	
}
