package version11_2_2_2.display;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.ArrayList;

import version11_2_2_2.agnosticMemory.Backmove;
import version11_2_2_2.agnosticMemory.EnvironmentContext;
//import version11_2_2_2.environment.Robot;
import version11_2_2_2.platform.Agent;

/**
 * Frame to display signatures of interactions
 * @author simon gay
 */

/* - inherited from EnvPanel :
 *   Agent agent      : pointer to the agent
 */
public class ProjectionPanel extends EnvPanel implements MouseListener{

	private static final long serialVersionUID = 1L;
	
	private int clic_x=0;
	private int clic_y=0;
	
	private int selected_interaction=-1;
	
	private int selected_sequence=-1;
	private int selected_bundle=-1;
	
	private short filter_mode=2;
	
	private int size2=EnvironmentContext.size2;
	
	private Backmove backmove;
	
	private float[][] patterns=null;
	private float[] pattern=null;
	
	public ProjectionPanel(Agent a){
		super(a);
		addMouseListener(this);
		
		backmove=null;
	}
	
	public void setAgent(Agent a){
		agent=a;
	}
	
	public void paintComponent(Graphics g){
		g.setColor(Color.white);
		g.fillRect(0, 0, 1600, 900);
		
		
		// draw enacted interaction
		g.setColor(Color.black);
		g.fillRect(10, 14, 660, 6);
		for (int i=0;i<11;i++){
			for (int j=0;j<11;j++){
				if ((i+j)%2==0) g.setColor(Color.darkGray);
				else g.setColor(Color.gray);
				g.fillRect(10+60*j , 20+60*i , 60, 60);
			}
		}

		for (int i=0;i<111*110;i++){
			if (agent.environmentContext.interactionList[i]!=null && agent.environmentContext.interactionList[i].getNbVar()>0){

				if (agent.environmentContext.interactionList[i].signature.delta_f==2 || agent.environmentContext.interactionList[i].signature.delta_s==2)
					g.setColor(Color.LIGHT_GRAY);
				
				else{
					float val=Math.max(agent.environmentContext.interactionList[i].signature.delta_f, agent.environmentContext.interactionList[i].signature.delta_s)/2;
					g.setColor(new Color(val, 1-val,0));
					
				}
				int x1=i%110;
				int y1=i/110;
				g.fillOval(10+6*x1, 15+6*y1, 6, 6);
			}
		}
		
		int x=-1;
		int y=-1;
				
		
		for (int i=0;i<12210;i++){
			int x1=i%110;
			int y1=i/110;
			
			if (i==selected_interaction){
				
				g.setColor(Color.green);
	
				if (agent.environmentContext.interactionList[i]!=null && agent.environmentContext.interactionList[i].getNbVar()>0){
					g.fillOval(10+6*x1+2, 20+6*y1-3, 2, 2);
					
					if (agent.environmentContext.interactionList[i].getNbVar()>1){
						for (int j=0;j<12;j++){
							
							if (agent.environmentContext.interactionList[i].variations(j)!=null){
							
								int x2=agent.environmentContext.interactionList[i].variations(j).successor%110;
								int y2=agent.environmentContext.interactionList[i].variations(j).successor/110;
								g.drawLine(10+6*x1+3, 20+6*y1-3, 10+6*x2+3, 20+6*y2-3);
							}
						}
					}
				}
			}
		}
		
		g.setColor(Color.red);
		for (int t=10;t>0;t--){
			int x1=agent.environmentContext.timeline[t]%110;
			int y1=agent.environmentContext.timeline[t]/110;
			int x2=agent.environmentContext.timeline[t-1]%110;
			int y2=agent.environmentContext.timeline[t-1]/110;
			g.drawLine(10+6*x1+3, 20+6*y1-3, 10+6*x2+3, 20+6*y2-3);
		}
		
		if (agent.environmentContext.id1!=-1 && agent.environmentContext.interactionList[agent.environmentContext.id1].events.size()>0){
			x=(agent.environmentContext.interactionList[agent.environmentContext.id1].events.get(0)[0]-1)*10+agent.environmentContext.interactionList[agent.environmentContext.id1].events.get(0)[1];
			y=-1;
			if (agent.environmentContext.interactionList[agent.environmentContext.id1].getSize()>1){
				y=(agent.environmentContext.interactionList[agent.environmentContext.id1].events.get(1)[0]-1)*10+agent.environmentContext.interactionList[agent.environmentContext.id1].events.get(1)[1];
			}
			
			g.setColor(Color.blue);
			g.fillRect(10+6*x, 20+6*y, 6, 6);
		}
		
		if (selected_interaction!=-1 && agent.environmentContext.interactionList[selected_interaction]!=null){
			g.setColor(Color.black);
			
			g.drawString(selected_interaction+" = "+agent.environmentContext.interactionList[selected_interaction].name(), 10, 700);
			
			for (int i=0;i<agent.environmentContext.interactionList[selected_interaction].predecessors.size();i++){
				int pred=agent.environmentContext.interactionList[selected_interaction].predecessors.get(i);
				g.drawString(""+pred+" = "+agent.environmentContext.interactionList[pred].name(), 290, 730+12*i);
			}
		}

		int count=0;
		if (backmove!=null){
			if (filter_mode<2){
				for (int i=0;i<backmove.seqList.size();i++){
					
					if ( filter_mode==0 || (filter_mode==1 && backmove.isDetected(i)) || (filter_mode==-1 && backmove.isAbsent(i))){
						if (selected_sequence==i)g.setColor(Color.red);
						else g.setColor(Color.black);
						g.fillRect(680, 1+15*count, 10, 10);
						
						ArrayList<Short> seq=backmove.getSeqence(i);
						g.setColor(Color.black);
						String sequence="";
						for (int n=0;n<seq.size();n++){
							sequence+=seq.get(n)+":"+agent.environmentContext.interactionList[seq.get(n)].name()+" , ";
						}
						g.drawString(sequence+" , "+backmove.getLength(i), 700, 10+15*count);
					
						count++;
					}
				}
			}
			else{
				for (int i=0;i<backmove.detected.size();i++){
					if (selected_sequence==i)g.setColor(Color.red);
					else g.setColor(Color.black);
					g.fillRect(680, 1+15*count, 10, 10);
					
					ArrayList<Short> seq=backmove.getDetected(i);
					g.setColor(Color.black);
					String sequence="";
					for (int n=0;n<seq.size();n++){
						sequence+=seq.get(n)+":"+agent.environmentContext.interactionList[seq.get(n)].name()+" , ";
					}
					g.drawString(sequence+" ; "+backmove.getLengthDetected(i)+", "+backmove.getDelayDetected(i), 700, 10+15*count);
				
					count++;
				}
				
				
				for (int i=0;i<backmove.bundles.size();i++){
					
					if (selected_bundle==i)g.setColor(Color.red);
					else g.setColor(Color.black);
					g.fillRect(680, 1+15*count+50, 10, 10);
					
					String bundle="{";
					for (int j=0;j<backmove.bundles.get(i).size();j++){
						bundle+=backmove.bundles.get(i).get(j)+", ";
					}
					bundle+="}";
					g.drawString(bundle, 700, 10+15*count+50);
					count++;
				}
				
				for (int i=0;i<backmove.bundlePlaces.size();i++){
					for (int j=0;j<backmove.bundlePlaces.get(i).size();j++){
						g.drawString(backmove.bundlePlaces.get(i).get(j).name(agent.environmentContext), 700, 10+15*count+70);
						count++;
					}
					
					count++;
				}
			}
			
			// display patterns
			if (patterns!=null){
				for (int n=0;n<patterns.length;n++){
					
					for (int j=EnvironmentContext.size2-1;j>=0;j--){
						for (int i=0;i<EnvironmentContext.size1;i++){
	
							g.setColor(new Color(patterns[n][i*size2*3+j*3+2]/2+0.5f,
												 patterns[n][i*size2*3+j*3  ]/2+0.5f,
												 patterns[n][i*size2*3+j*3+1]/2+0.5f ));
	
							
							g.fillRect(1600 + i*10, 10+(EnvironmentContext.size2-j)*10 +160*n, 10, 10);
						}
					}
				}
			}
			if (pattern!=null && selected_sequence>=0 && backmove!=null){
				/*for (int j=EnvironmentContext.size2-1;j>=0;j--){
					for (int i=0;i<EnvironmentContext.size1;i++){
	
						g.setColor(new Color(pattern[i*size2*3+j*3+2]/2+0.5f,
											 pattern[i*size2*3+j*3  ]/2+0.5f,
											 pattern[i*size2*3+j*3+1]/2+0.5f ));
	
						
						g.fillRect(1920 + i*10, 10+(EnvironmentContext.size2-j)*10, 10, 10);
					}
				}*/
				
				g.setColor(Color.black);
				if (filter_mode<2){
					if (selected_sequence<backmove.seqList.size())
					for (int t=0;t<10;t++){
						g.drawString(""+backmove.getPrediction(selected_sequence, t), 1930, 500+15*t);
					}
				}
				else{
					if (selected_sequence<backmove.detected.size())
					for (int t=0;t<10;t++){
						g.drawString(""+backmove.getPredictionDetected(selected_sequence, t), 1930, 500+15*t);
					}
				}
			}
			
			if (backmove!=null){
			
				
				for (int b=0;b<backmove.bundlePatterns.size();b++){
					for (int j=EnvironmentContext.size2-1;j>=0;j--){
						for (int i=0;i<EnvironmentContext.size1;i++){
		
							g.setColor(new Color(backmove.bundlePatterns.get(b)[i*size2*3+j*3+2]/2+0.5f,
												 backmove.bundlePatterns.get(b)[i*size2*3+j*3  ]/2+0.5f,
												 backmove.bundlePatterns.get(b)[i*size2*3+j*3+1]/2+0.5f ));
		
							g.fillRect(1920 + i*10 +b*320, 10+(EnvironmentContext.size2-j)*10, 10, 10);
						}
					}
				}
			}
		}
		
		// filter selector
		for (int i=-1;i<=2;i++){
			if (filter_mode==i) g.setColor(Color.red);
			else g.setColor(Color.black);
			g.fillRect(1950+30*i, 300, 20, 20);
		}
	}
	
	
	
	///////////////////////////////////////////////////////////////////////////
	public void mouseClicked(MouseEvent e) {

		clic_x=e.getX();
		clic_y=e.getY();
		
		for (int i=0;i<110;i++){
			for (int j=0;j<111;j++){
				if (clic_x>=10+i*6 && clic_x<16+i*6 && clic_y>=15+j*6 && clic_y<21+j*6){
					selected_interaction=j*110+i;
					System.out.println("selected : "+selected_interaction);

					if (agent.environmentContext.interactionList[selected_interaction]!=null 
					 && agent.environmentContext.interactionList[selected_interaction].isChange()){

						backmove=agent.spaceMemory.backmoveList[selected_interaction];
						selected_sequence=-1;
						selected_bundle=-1;
						
						if (backmove!=null){
							//backmove.setPredictions(agent.environmentContext.interactionList[selected_interaction], agent.environmentContext);
							System.out.println(" +++ predecessors : "+backmove.seqList.size());
						}
					}
				}
			}
		}
		if (selected_interaction>=0 && agent.environmentContext.interactionList[selected_interaction]==null) selected_interaction=-1;
		

		if (backmove!=null){
			int counter=0;
			
			if (filter_mode<2){
				for (int i=0;i<backmove.seqList.size();i++){
					if ( filter_mode==0 || (filter_mode==1 && backmove.isDetected(i)) || (filter_mode==-1 && backmove.isAbsent(i))){
						if (clic_x>=680 && clic_x<690 && clic_y>=1+15*counter && clic_y<11+15*counter){
							selected_sequence=i;
							
							ArrayList<Short> seq=backmove.getSeqence(i);
							String sequence="";
							for (int n=0;n<seq.size();n++){
								sequence+=seq.get(n)+":"+agent.environmentContext.interactionList[seq.get(n)].name()+" , ";
							}
							System.out.println(sequence+" length : "+backmove.getLength(i));
							
							patterns=backmove.getPatterns(i);
							pattern=backmove.getPatternOf(i);
							
							/*for (short o=0;o<10;o++){
							int[] eventList=backmove.getEventList(i, o, agent.environmentContext);
							
							System.out.print("offset "+o+" : ");
							
							for (int t=0;t<eventList.length;t++){
								if (eventList[t]==0){
									if (t%10==0) System.out.print(".");
									else System.out.print("-");
								}
								else if (eventList[t]==1) System.out.print(">");
								else if (eventList[t]==2) System.out.print("^");
								else if (eventList[t]==3) System.out.print("v");
								else if (eventList[t]==4) System.out.print("X");
								else if (eventList[t]==5) System.out.print("F");
								else if (eventList[t]==6) System.out.print("B");
								else if (eventList[t]==7) System.out.print("E");
								else if (eventList[t]==8) System.out.print("6");
								else if (eventList[t]==9) System.out.print("/");
								else if (eventList[t]==10) System.out.print("9");
								else if (eventList[t]==11) System.out.print("\\");
								else System.out.print("@");
								
							}
							System.out.println();
							
							System.out.println(agent.environmentContext.getOffset(backmove.getIndex(i)));
							
							float[] transformation=Robot.computeMovement(eventList);
							System.out.println(transformation[0]+" , "+transformation[1]+" , "+transformation[2]);
							}*/
							
						}
						counter++;
					}
				}
			}
			else{
				for (int i=0;i<backmove.detected.size();i++){
					if (clic_x>=680 && clic_x<690 && clic_y>=1+15*counter && clic_y<11+15*counter){
						selected_sequence=i;
						
						ArrayList<Short> seq=backmove.getDetected(i);
						String sequence="";
						for (int n=0;n<seq.size();n++){
							sequence+=seq.get(n)+":"+agent.environmentContext.interactionList[seq.get(n)].name()+" , ";
						}
						System.out.println(sequence);
						
						patterns=backmove.getPatternsDetected(i);
						pattern=backmove.getPatternOfDetected(i);

						backmove.printWeights(i);
					}
					counter++;
				}
				
				for (int i=0;i<backmove.bundles.size();i++){
					if (clic_x>=680 && clic_x<690 && clic_y>=1+15*counter+50 && clic_y<11+15*counter+50){
						selected_bundle=i;
					}
					counter++;
				}
			}
		}
		
		for (int i=-1;i<=2;i++){
			if (clic_x>=1950+30*i && clic_x<1970+30*i && clic_y>=300 && clic_y<320){
				filter_mode=(short)i;
				selected_sequence=-1;
				selected_bundle=-1;
			}
		}
	}

	@Override
	public void mouseEntered(MouseEvent e) {}
	public void mouseExited(MouseEvent e) {}
	public void mousePressed(MouseEvent e) {}
	public void mouseReleased(MouseEvent e) {}

}
