package version11_2_2_1.agnosticMemory;

import version11_2_2_1.Interface.ContinuousInteraction;
import version11_2_2_1.Interface.InteractionList;
import version11_2_2_1.Interface.Variation;
import version11_2_2_1.platform.Agent;

/**
 * Environmental context.
 * This class can also generate a predicted and an improved context
 * @author simon gay
 */
public class EnvironmentContext{
	
	//private Agent agent;
	
	public int[][] enactedActions;
	public int[][] perceptions;

	public ContinuousInteraction enactedInteraction;
	public ContinuousInteraction previousInteraction;
	
	public int id0;
	public int id1;

	//public int[][] enactedSets;
	
	//public float[][] enactedEnsembles;				// enacted ensembles E_t and E_{t-1}

	public int[] timeline;
	//public ArrayList<Variation>[] variations;		// list of delta and successors of each continuous interaction
	public ContinuousInteraction[] interactionList;
	
	public EnvironmentContext(Agent a){
		
		//agent = a;
		
		enactedActions=new int[11][5];
		
		perceptions=new int[11][InteractionList.size1*InteractionList.size2*3+2];
		for (int t=0;t<11;t++){
			for (int i=0;i<InteractionList.size1*InteractionList.size2*3+2;i++){
				perceptions[t][i]=0;
			}
		}
		
		enactedInteraction=null;
		previousInteraction=null;
		
		id0=-1;
		id1=-1;

		/*enactedSets=new int[2][InteractionList.length];
		for (int i=0;i<InteractionList.length;i++){
			enactedSets[0][i]=0;
			enactedSets[1][i]=0;
		}
		
		enactedEnsembles=new float[2][InteractionList.length];
		for (int i=0;i<InteractionList.length;i++){
			enactedEnsembles[0][i]=0;
			enactedEnsembles[1][i]=0;
		}*/
		
		/*variations=new ArrayList[51*50];
		for (int i=0;i<2550;i++){
			variations[i]=new ArrayList<Variation>();
		}*/
		interactionList=new ContinuousInteraction[2550];
		
		timeline=new int[11];
	}
	
	
	/**
	 * update the environmental context
	 * @param inter : last enacted primitive interaction
	 */
	//public void updateContext(int action, int[] percep, PrimitiveInteraction inter, float[] enacted){
	public void updateContext(int variation, int[] percep){	

		// update timelines
		for (int t=10;t>0;t--){
			for (int i=0;i<5;i++) enactedActions[t][i]=enactedActions[t-1][i];
		}
		for (int i=0;i<5;i++) enactedActions[0][i]=0;
		
		// last action
		if ((int)(variation/4)!=0) enactedActions[0][(int)(variation/4)-1]=1;
		
		// define perception
		//int obs=0;
		//if (percep[InteractionList.size1*InteractionList.size2*3]==1) obs=1;
		//else if (percep[InteractionList.size1*InteractionList.size2*3+1]==1) obs=2;

		// last perceptions
		if (variation%4==1){
			enactedActions[0][3]=1;
		}
		if (variation%4==2) enactedActions[0][4]=1;
		
		// update enacted interaction
		previousInteraction=enactedInteraction;
		enactedInteraction=new ContinuousInteraction(enactedActions);
		
		// get index of current interaction
		id0=id1;
		id1=enactedInteraction.id;
		
		if (interactionList[id1]==null) interactionList[id1]=enactedInteraction;
		
		if (id0!=-1){
			
			int length=previousInteraction.length;
			System.out.println("+++ context : "+id0+" ; "+length+" ; "+timeline[length]);
			
			// define variation
			Variation var=enactedInteraction.getVar(id1);
			int varIndex=var.getIndex();
			//int k=0;

			/*while (varIndex==-1 && k<interactionList[id0].variations.size()){
				if (interactionList[id0].variations.get(k).isEqual(var)) varIndex=k;
				k++;
			}
			if (varIndex==-1){
				varIndex=interactionList[id0].variations.size();
				interactionList[id0].variations.add(var);
			}*/
			
			if (interactionList[id0].variations[varIndex]==null){
				interactionList[id0].variations[varIndex]=var;
			}
			
			
			
			////////////////////////////////////////////////////////////////////////////////////////////////////////////
			// learn signature of enacted interaction
			
			// detect alternative delta
			int counter=0;

			for (int i=0;i<interactionList[id0].variations.length;i++){
				if (i!=varIndex && interactionList[id0].variations[i]!=null){
					if (interactionList[id0].variations[varIndex].isAlternative(interactionList[id0].variations[i])){
						counter++;
						System.out.print(interactionList[id0].variations[i].getName());
						System.out.println(" -> learn "+interactionList[id0].variations[i].successor+" as a failure with "+id0+" context");
						
						if (timeline[length]!=0){
							interactionList[id0].variations[i].signature.learn(perceptions[length], -1);	// learn alternative result of id0 as a failure
						}
					}
				}
			}

			if (counter>0){
				System.out.print("variation : "+interactionList[id0].variations[varIndex].getName()/*+" ; alternatives : "*/);
				System.out.println(" -> learn "+interactionList[id0].variations[varIndex].successor+" as a success with "+id0+" context");
				
				if (timeline[length]!=0){
					interactionList[id0].variations[varIndex].signature.learn(perceptions[length], 1);			// learn id1 (successor of id0 by var) as a success
				}
			}
			
			// display enacted interaction
			System.out.print("Observed : ");
			previousInteraction.print();
			System.out.print(" - "+var.getName()+" -> ");
			enactedInteraction.print();
			System.out.println();
		}

		
		// perception timeline used for display panels
		for (int t=10;t>0;t--) perceptions[t]=perceptions[t-1];
		perceptions[0]=percep;

		for (int t=10;t>0;t--){
			timeline[t]=timeline[t-1];
		}
		timeline[0]=id1;
		
		interactionList[id1].addPredecessor(timeline[interactionList[id1].length]);
		
		//////////////////////////////////////////////////////////////////////
		// update timeline
		/*for (int i=0;i<InteractionList.length;i++){
			enactedEnsembles[1][i]=enactedEnsembles[0][i];
			enactedEnsembles[0][i]=enacted[i];
		}*/
		
		// update signatures
		//agent.signatureList.learn(enactedEnsembles[1],enactedEnsembles[0] , inter);
		
		// compute predictions
		//agent.signatureList.setPredictions(enactedEnsembles[0]);
	}
	
	public void predictNextStep(){
		if (id1>=0){
			for (int i=0;i<16;i++){
				if (interactionList[id1].variations[i]!=null){
					
					interactionList[id1].variations[i].prediction(perceptions[interactionList[id1].length], true);
					
				}
			}
		}
	}
	
}
