package version11_2_0.spaceMemory;

import version11_2_0.platform.Agent;
import version11_2_0.Interface.ContinuousInteraction;

/**
 * Decision system.
 * This class selects the intended interactions
 * @author simon
 */
public class Decision {

	private Agent agent;

	public int counter=0;
	
	public int timer=4;
	
	public PredictionNode predictionNode;
	
	public float actionMap[][];
	public float exploitationMap[][];
	
	public float lastLearningVal;
	public float lastExploitationVal;
	public int lastDecisionType;
	
	public static float memory_coef=0.01f;
	
	///////////////////////////////////////////////////////////
	public Decision(Agent a){
		agent=a;
		predictionNode=null;
		actionMap=new float[12][11];
		exploitationMap=new float[12][11];
	}
	
	/**
	 * decision of the next interaction
	 * @return the intended enact
	 */
	public int decision(){
		
		int ret=0;
		
		
		// define prediction of variations through signatures
		agent.environmentContext.predictNextStep();
		
		boolean found=false;
		int i=0;
		
		//////////////////////////////////////////////////////////////////
		// if there are too many events on the timeline: wait
		if (agent.environmentContext.nbEvent7>=2 || agent.environmentContext.nbEvent10>=3){
			ret=0;
			System.out.println("##### too many events");
			//lastDecisionType=0;
		}
		else{
			//////////////////////////////////////////////////////////////////
			// check for non tested variations
			if (agent.action.getNBStep()<100000) {
				while (!found && i<12){
					if (agent.environmentContext.id1>=0 
							&& agent.environmentContext.interactionList[agent.environmentContext.id1].nbIntention[i]==0
							&& agent.environmentContext.interactionList[agent.environmentContext.id1].variations(i)==null) found=true;
					else i++;
				}
			}
			
			if (found){
				ret=i;			// if a variation was not tested before, enact it
				System.out.println("##### sensorimotor discovering");
				lastDecisionType=1;
			}
			else{
				//////////////////////////////////////////////////////////////////
				// otherwise, find the less known sequence of interaction
				if (agent.environmentContext.id1>=0){
					System.out.println("##### sensorimotor learning or eploitation");
					
					/////////////////////////
					// selection for learning
					for (int v=0;v<12;v++){
						for (int j=0;j<11;j++){
							actionMap[v][j]=10;
						}
					}
					LearningNode node=new LearningNode(agent.environmentContext,agent.environmentContext.id1,0, actionMap);

					node.getMinReliable();
					
					float vlearn=0;
					int learn=-1;
					
					for (int v=0;v<12;v++){
						if (node.min[v]>vlearn && node.valide[v]){
							vlearn=node.min[v];
							learn=v;
							System.out.println(" --- "+vlearn);
						}
						else System.out.println(" --- #####");
					}
					System.out.println(" learning mechanism proposes -> "+learn+" ; "+vlearn);/**/
					
					vlearn=0;
					if (vlearn>0.2 && learn!=-1){
						lastDecisionType=2;
						lastLearningVal=vlearn;
						System.out.println(" +++++ learning mechanism proposes -> "+learn);
						ret=learn;
					}
					else{
						
						/////////////////////////////
						// selection for exploitation
						for (int v=0;v<12;v++){
							for (int j=0;j<11;j++){
								exploitationMap[v][j]=-1;
							}
						}

						ExploitationNode enode=new ExploitationNode(agent.environmentContext,agent.environmentContext.id1,0, exploitationMap);
						agent.spaceMemory.predictMemories(exploitationMap);
						
						for (i=0;i<agent.environmentContext.interactionList.length;i++){
							if (agent.environmentContext.interactionList[i]!=null && agent.environmentContext.interactionList[i].isChange()
							&& agent.environmentContext.interactionList[i].signature.delta_s<0.8 && agent.environmentContext.interactionList[i].signature.delta_f<0.8){
								agent.environmentContext.interactionList[i].blurPattern.computeCurrentDistance(agent.spaceMemory.spaceMemory, exploitationMap,agent.spaceMemory.predictedMemories);
								agent.environmentContext.interactionList[i].getUtility();
							}
						}
						
						agent.spaceMemory.getUtilityMap(exploitationMap);
						
						float vexp=-100000;
						int exp=-1;
						
						for (int v=0;v<12;v++){
							int id1=agent.environmentContext.id1;
							float valence=0;
							if (agent.environmentContext.interactionList[id1].variations(v)!=null){
								int successor=agent.environmentContext.interactionList[id1].variations(v).successor;
								valence=ContinuousInteraction.valence(agent.environmentContext.interactionList[successor]);
								
								if (memory_coef*agent.spaceMemory.values[v]+valence>vexp && exploitationMap[v][0]>=0){
									vexp=memory_coef*agent.spaceMemory.values[v]+valence;
									exp=v;
								}
								System.out.println(" --- "+agent.spaceMemory.values[v]+" ; "+valence);
							}
							else System.out.println(" --- ##### ");
						}
						vexp=vexp/200;
						System.out.println(" exploitation mechanism proposes -> "+exp+" ; "+vexp);/**/
						
						lastDecisionType=3;
						lastLearningVal=vlearn;
						lastExploitationVal=vexp;
						System.out.println(" +++++ exploitation mechanism proposes -> "+exp);
						ret=exp;
					}
					/**/
					
					// if there are no decision at this point, a random variation is selected
					if (ret==-1){
						lastDecisionType=4;
						ret=(int)(Math.random()*11+1);
					}
				}
				else ret=0;
			}
			
			//ret=1;
		}
		
		
		//### for tests, compute learning and exploitation node
		/*for (int v=0;v<12;v++){
			for (int j=0;j<11;j++){
				actionMap[v][j]=1000;
			}
		}
		if (agent.environmentContext.id1!=-1){
			LearningNode lnode=new LearningNode(agent.environmentContext,agent.environmentContext.id1,0, actionMap);
		}*/
		/*for (int v=0;v<12;v++){
			for (int j=0;j<11;j++){
				exploitationMap[v][j]=-1;
			}
		}
		if (agent.environmentContext.id1!=-1){
			ExploitationNode enode=new ExploitationNode(agent.environmentContext,agent.environmentContext.id1,0, exploitationMap);
		}
		agent.spaceMemory.predictMemories(exploitationMap);
		
		float[] utilities=new float[12];
		
		for (i=0;i<agent.environmentContext.interactionList.length;i++){
			if (agent.environmentContext.interactionList[i]!=null && agent.environmentContext.interactionList[i].isChange()
			&& agent.environmentContext.interactionList[i].signature.delta_s<0.8 && agent.environmentContext.interactionList[i].signature.delta_f<0.8){
				agent.environmentContext.interactionList[i].blurPattern.computeCurrentDistance(agent.spaceMemory.spaceMemory, exploitationMap,agent.spaceMemory.predictedMemories);
				agent.environmentContext.interactionList[i].getUtility();
				for (int v=0;v<12;v++) utilities[v]+=agent.environmentContext.interactionList[i].utilityMap[v];
			}
		}
		agent.spaceMemory.getUtilityMap();
		*/
		if (agent.environmentContext.id1>=0) agent.environmentContext.interactionList[agent.environmentContext.id1].setIntention(ret);
		System.out.println(" set variation "+ret+" to interaction "+agent.environmentContext.id1);
		
		agent.observer.updateDecisionTrace(lastDecisionType, lastLearningVal, lastExploitationVal);
		
		return ret;
		
	}
}
