package version10_2_2_1.agnosticMemory;

import java.util.ArrayList;

import version10_2_2_1.Interface.InteractionList;

public class WorkMemory {

	public Point[] memory;
	public Signature sig;
	
	public WorkMemory(Signature s){
		
		sig=s;
		
		memory=new Point[InteractionList.nbDF];
		for (short i=0;i<InteractionList.nbDF;i++) memory[i]=new Point(i);
	}
	
	public void projection(ArrayList<Signature> signatures){
		Node node=new Node((byte)-1,null);
		
		if (sig.nb_s_f==100){
			
			for (byte i=0;i<6;i++) node.addNext(i);
			
			for (int c=0;c<sig.context_f.size();c++){
				if (sig.context_f.get(c).nb_s==10){
					for (int e=0;e<sig.context_f.get(c).size();e++){
						
						memory[sig.context_f.get(c).get(e)].addPath(node.getPath(), (short)-1, sig.context_f.get(c).get(e));
				
						projection(signatures, 
								   node.getNext((short)signatures.get(sig.context_f.get(c).get(e)).interaction.getIndex()), 
								   sig.context_f.get(c).get(e),
								   sig.context_f.get(c).get(e), 					// origin element of initial signature
								   (short)0, 
								   sig.context_f.get(c).get(e));
					}
				}
			}
		}
	}
	
	public void projection(ArrayList<Signature> signatures, Node node, short previous, short origin, short level, short id){
		
		if (level<Projection.LENGTH){
			
			for (byte i=0;i<6;i++) node.addNext(i);
		
			if (signatures.get(id).nb_s_f==100){
				for (int c=0;c<signatures.get(id).context_f.size();c++){
					if (signatures.get(id).context_f.get(c).nb_s==10){
						for (int e=0;e<signatures.get(id).context_f.get(c).size();e++){
					
							memory[signatures.get(id).context_f.get(c).get(e)].addPath(node.getPath(), previous, origin);
							
							projection(signatures,
									   node.getNext((short)signatures.get(id).interaction.getIndex()), 
									   id, 
									   origin, 
									   (short)(level+1), 
									   signatures.get(id).context_f.get(c).get(e));
						}
					}
				}
			}
		}
		
	}
	
	public void resetMemory(){
		for (short i=0;i<InteractionList.nbDF;i++) memory[i].reset();
	}

	
	//----------------------------------------------------------------------------------------------
	private class Node{
		
		Byte interaction;
		Node previous;
		ArrayList<Node> nexts;
		
		public Node(Byte inter,Node prev){
			interaction=inter;
			previous=prev;
			nexts=new ArrayList<Node>();
		}
		
		public void addNext(Byte inter){
			nexts.add(new Node(inter, this));
		}
		
		public Node getNext(short i){
			return nexts.get(i);
		}
		
		public Byte[] getPath(){
			Byte[] path=new Byte[Projection.LENGTH+1];
			for (int i=0;i<=Projection.LENGTH;i++) path[i]=-1;
			
			return getPath(path, (short)0);
			
		}
		
		private Byte[] getPath(Byte[] path, short level){
			
			if (interaction==-1) return path;
			else{
				path[level]=interaction;
				return previous.getPath(path, (short)(level+1));
			}
		}
	}
	
}
