package version11_2_2_2.Interface;

import java.util.ArrayList;

import version11_2_2_2.agnosticMemory.EnvironmentContext;
import version11_2_2_2.agnosticMemory.SignatureComponent;
import version11_2_2_2.agnosticMemory.SignatureSimplified;


public class ContinuousInteraction {

	public ArrayList<Integer[]> events;
	
	public int id;
	public int length=1;
	
	public ArrayList<Integer> predecessors;
	
	private Variation[] variations;
	public short[] nbIntention;
	public int nbEnaction;
	
	public SignatureComponent signature;
	public SignatureSimplified[] secondarySignatures;
	
	public ContinuousInteraction(int[] condition){
		
		events=new ArrayList<Integer[]>();
		
		for (int t=0;t<10;t++){
			if (events.size()<2 && condition[t]>0){
				Integer[] event={condition[t],t};
				events.add(event);
			}
		}
		
		if (events.size()==1){
			if (condition[0]>0) length=1;					// interaction under the form {(e0,0)}
			else 				length=events.get(0)[1];	// interaction under the form {(e0,t0)} / t0!=0
		}
		else{
			if (events.size()==2){
				if (condition[0]>0) length=events.get(1)[1];	// interaction under the form {(e1,t1);(e0,0)}  / t1!=0
				else				length=events.get(0)[1];	// interaction under the form {(e1,t1);(e0,t0)} / t0,t1!=0
			}
		}													// if empty interaction, length is 1 by default
		
		id=getId(condition);
		
		predecessors=new ArrayList<Integer>();
		
		variations=new Variation[12];
		for (int i=0;i<12;i++) variations[i]=null;
		
		nbIntention=new short[12];
		for (int i=0;i<12;i++) nbIntention[i]=0;
		
		// signature of the interaction
		signature=new SignatureComponent();
		nbEnaction=0;
		
		// set secondary interactions
		secondarySignatures=new SignatureSimplified[EnvironmentContext.size1*EnvironmentContext.size2*3];
		for (int i=0;i<EnvironmentContext.size1*EnvironmentContext.size2*3;i++) secondarySignatures[i]=new SignatureSimplified();
	}
	
	public float prediction(float[] img, boolean write){
		if (signature.learned) return signature.prediction(img, write);
		return 1;
	}
	
	public void predictSecondary(float[] img, boolean write){
		for (int i=0;i<EnvironmentContext.size1*EnvironmentContext.size2*3;i++){
			secondarySignatures[i].prediction(img, write);
		}
	}
	
	public void learnSecondary(float[] img, float[] result){
		for (int i=0;i<EnvironmentContext.size1*EnvironmentContext.size2*3;i++){
			if (result[i]>0) secondarySignatures[i].learn(img, 1);
			else secondarySignatures[i].learn(img, -1);
		}
	}
	
	public void shareLearnSecondary(float[] img, float[] result){
		for (int i=0;i<EnvironmentContext.size1*EnvironmentContext.size2*3;i++){
			if (result[i]>0) secondarySignatures[i].shareLearn(img, 1);
			else secondarySignatures[i].shareLearn(img, -1);
		}
	}
	
	public Variation variations(int id){
		return variations[id];
	}
	
	public void setVariation(int id, Variation var){
		variations[id]=var;
	}
	
	public int getSize(){
		return events.size();
	}
	
	public int getNbVar(){
		int count=0;
		for (int i=0;i<12;i++){
			if (variations[i]!=null) count++;
		}
		return count;
	}
	
	public Variation getVar(int id, int pos){
		return new Variation(id, pos);
	}
	
	public void addPredecessor(int i){
		if (predecessors.indexOf(i)==-1) predecessors.add(i);
	}
	
	public void setIntention(int id){
		
		if (id>=0 & id<12){
			for (int i=0;i<12;i++){
				if (i==id){
					nbIntention[id]=10;
				}
				else{
					if (nbIntention[i]>1) nbIntention[i]--;
				}
			}
		}
	}
	
	public void enaction(){
		//if (nbEnaction<255) 
		nbEnaction++;
	}
	
	public boolean isChange(){
		if (events.size()>0) return events.get(0)[1]==0;
		else return false;
	}
	
	public boolean previousDefaultTrue(EnvironmentContext env){
		boolean ret=false;
		int p=0;
		while (!ret && p<predecessors.size()){
			if (env.interactionList[predecessors.get(p)].signature.getBias()>=0) ret=true;
			p++;
		}
		
		return ret;
	}
	
	
	
	public String name(){
		String ret="{";
		for (int e=0;e<events.size();e++){
			if (events.get(e)[0]==1) ret+="(>,"+events.get(e)[1]+"), ";
			if (events.get(e)[0]==2) ret+="(^,"+events.get(e)[1]+"), ";
			if (events.get(e)[0]==3) ret+="(v,"+events.get(e)[1]+"), ";
			if (events.get(e)[0]==4) ret+="(X,"+events.get(e)[1]+"), ";
			if (events.get(e)[0]==5) ret+="(F,"+events.get(e)[1]+"), ";
			if (events.get(e)[0]==6) ret+="(> X,"+events.get(e)[1]+"), ";
			if (events.get(e)[0]==7) ret+="(> F,"+events.get(e)[1]+"), ";
			if (events.get(e)[0]==8) ret+="(^ X,"+events.get(e)[1]+"), ";
			if (events.get(e)[0]==9) ret+="(^ F,"+events.get(e)[1]+"), ";
			if (events.get(e)[0]==10)ret+="(v X,"+events.get(e)[1]+"), ";
			if (events.get(e)[0]==11)ret+="(v F,"+events.get(e)[1]+"), ";
		}
		ret+="}";
		
		return ret;
	}
	
	public void print(){
		
		System.out.print("{");
		for (int e=0;e<events.size();e++){
			if (events.get(e)[0]==1) System.out.print("(>,"+events.get(e)[1]+"), ");
			if (events.get(e)[0]==2) System.out.print("(^,"+events.get(e)[1]+"), ");
			if (events.get(e)[0]==3) System.out.print("(v,"+events.get(e)[1]+"), ");
			if (events.get(e)[0]==4) System.out.print("(X,"+events.get(e)[1]+"), ");
			if (events.get(e)[0]==5) System.out.print("(F,"+events.get(e)[1]+"), ");
			if (events.get(e)[0]==6) System.out.print("(> X,"+events.get(e)[1]+"), ");
			if (events.get(e)[0]==7) System.out.print("(> F,"+events.get(e)[1]+"), ");
			if (events.get(e)[0]==8) System.out.print("(^ X,"+events.get(e)[1]+"), ");
			if (events.get(e)[0]==9) System.out.print("(^ F,"+events.get(e)[1]+"), ");
			if (events.get(e)[0]==10)System.out.print("(v X,"+events.get(e)[1]+"), ");
			if (events.get(e)[0]==11)System.out.print("(v F,"+events.get(e)[1]+"), ");
		}
		System.out.print("}");
	}
	
	public static int getId(int[] condition){
		
		int ident=0;

		int t=0;
		int count=0;
		while (count<2 && t<10){
			if (condition[t]>0){
				if (count==0) ident=(condition[t]-1)*10+t;
				else if (count==1) ident+=110*((condition[t]-1)*10+t+1);
				count++;
			}
			t++;
		}
		
		return ident;
	}
	
	public static float valence(ContinuousInteraction inter){
		if (inter.id==0 || inter.events.get(0)[1]!=0) return 0;
		else {
			if (inter.events.get(0)[0]==1) return 2;			// >
			else if (inter.events.get(0)[0]==2 || inter.events.get(0)[0]==3) return -2;		// ^ or v
			else if (inter.events.get(0)[0]==4 || inter.events.get(0)[0]==6 || inter.events.get(0)[0]==8 || inter.events.get(0)[0]==10) return -10;
			else if (inter.events.get(0)[0]==5 || inter.events.get(0)[0]==7 || inter.events.get(0)[0]==9 || inter.events.get(0)[0]==11) return 500;
			else return 0;
		}

	}
	
}
