package version7_2_2_2.agnosticMemory;

import version7_2_2_2.Interface.InteractionList;
import version7_2_2_2.Interface.PrimitiveInteraction;

/**
 * signature of an interaction
 * @author simon gay
 */
public class Signature {

	private PrimitiveInteraction interaction;	// primary interaction or associated interaction used to define selected action 
	
	public float[] signature;					// signature of the interaction
	
	public float maxPattern1;					// maximum weight (used to normalize values in displayer)
	public float maxPattern2;
	
	public int accurate=0;
	//public int nbTest=0;
	
	public float prediction=0;
	
	public float average_delta1=0;
	public float average_delta2=0;
	
	public Signature(PrimitiveInteraction inter){
		interaction=inter;
		
		signature=new float[InteractionList.length];
		for (int i=0;i<InteractionList.length;i++){
			signature[i]=0;
		}
		maxPattern1=0;
		maxPattern2=0;

	}
	
	/**
	 * predict the result of an interaction in a given context
	 * @param img : environmental context
	 * @return the certitude of success (1->absolute certitude of success, -1-> absolute certitude of failure 
	 */
	public float prediction(float[] img){
		float result=0;
		for (int i=0;i<InteractionList.length;i++){
			result+=signature[i]*img[i];
		}
		result= (float) ( 1 / (1+Math.exp(-result)))*2-1;
		return result;
	}
	
	/**
	 * integrate the result of enaction cycle
	 * @param img : environmental context E_{t-1} 
	 * @param output result of enaction (success->1, failure->-1)
	 */
	public void learn(float[] img, float output){
		
		float result=prediction(img);
		float delta=output-result;
		
		if (delta>=0) average_delta1= (100*average_delta1 + Math.abs(delta))/101;
		if (delta<=0) average_delta2= (100*average_delta2 + Math.abs(delta))/101;
		
		if (Math.abs(delta)>=0.1){
			maxPattern1=0;
			maxPattern2=0;
			
			for (int i=0;i<InteractionList.length;i++){
				
				signature[i]+= 0.5 * delta * img[i];
				
				if (i< InteractionList.length-8 && Math.abs(signature[i])>maxPattern1) maxPattern1=Math.abs(signature[i]);
				if (i>=InteractionList.length-8 && Math.abs(signature[i])>maxPattern2) maxPattern2=Math.abs(signature[i]);
			}
		}
		
		if (result*output>0.5){
			if (accurate<5) accurate++;
		}
		else accurate=0;
		
		if (output>0) nbTest++;
	}
	
	public boolean isAccurate(){
		return accurate>=5 || Math.abs(prediction)>0.2;
	}
	
	/**
	 * store the prediction of success
	 * @param img : environmental context
	 */
	public void setPrediction(float[] img){
		prediction=prediction(img);
	}
	
	public PrimitiveInteraction interaction(){
		return interaction;
	}
	
}
