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 version11_2_2_2.platform.Agent;
import version11_2_2_2.agnosticMemory.EnvironmentContext;
import version11_2_2_2.environment.Environment;

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

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

	private static final long serialVersionUID = 1L;
	
	private int clic_x=0;
	private int clic_y=0;
	
	private boolean[] display;
	
	private int size2=EnvironmentContext.size2;
	
	public SpacePanel(Agent a){
		super(a);
		addMouseListener(this);
		
		display=new boolean[agent.spaceMemory.backmoveList.length];
		for (int i=0;i<display.length;i++) display[i]=true;
	}
	
	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.spaceMemory.backmoveList[i]!=null){
					if (agent.spaceMemory.backmoveList[i].detected.size()>0){
						if (display[i]) g.setColor(new Color(0,255,200));
						else g.setColor(new Color(200,255,0));
					}
					else{
						if (display[i]) g.setColor(Color.green);
						else g.setColor(Color.red);
					}
				}
				else g.setColor(Color.lightGray);

				int x1=i%110;
				int y1=i/110;
				g.fillOval(10+6*x1, 15+6*y1, 6, 6);
			}
		}
		
		int x=-1;
		int y=-1;
				
	
		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);
		}
		
		///////////////////////////////////////////////////////////////////////////////////////
		// draw center of object instances
		
		// draw environment
		for (int i=0;i<agent.getMain().env.getWidth();i++){
			for (int j=0;j<agent.getMain().env.getHeight();j++){
				
				if (agent.getMain().env.isWall(i, j)) g.setColor(Environment.WALL1);
				else if (agent.getMain().env.isFood(i, j)) g.setColor(Environment.FISH1);
				else if (agent.getMain().env.isAlga(i, j)) g.setColor(Environment.ALGA1);
				else g.setColor(Environment.FIELD_COLOR);
				
				g.fillRect(700+34*i, 10+34*(agent.getMain().env.getHeight()-1-j), 34, 34);
			}	
		}
		
		// draw agent's position and orientation
		g.setColor(Color.gray);
		g.fillOval((int)(700+34*agent.body.getpx()+10), (int)(10+34*(agent.getMain().env.getHeight()-1-agent.body.getpy())+10), 20, 20);
		
		float dx= 20*(float)Math.cos(agent.body.getrz());
		float dy= 20*(float)Math.sin(-agent.body.getrz());
		g.drawLine((int)(700+34*agent.body.getpx()+20),
				   (int)(10+34*(agent.getMain().env.getHeight()-1-agent.body.getpy())+20),
				   (int)(700+34*agent.body.getpx()+20+dx),
				   (int)(10+34*(agent.getMain().env.getHeight()-1-agent.body.getpy())+20+dy));
		
		
		// draw detected instances of the selected interaction
		for (int b=0;b<agent.spaceMemory.backmoveList.length;b++){
			
			if (agent.spaceMemory.backmoveList[b]!=null && display[b]){
				
				if (agent.environmentContext.interactionList[b].events.get(0)[0]==4 || agent.environmentContext.interactionList[b].events.get(0)[0]==6
				 || agent.environmentContext.interactionList[b].events.get(0)[0]==8 || agent.environmentContext.interactionList[b].events.get(0)[0]==10){
					g.setColor(Color.green);
				}
				else if (agent.environmentContext.interactionList[b].events.get(0)[0]==5 || agent.environmentContext.interactionList[b].events.get(0)[0]==7
				 || agent.environmentContext.interactionList[b].events.get(0)[0]==9 || agent.environmentContext.interactionList[b].events.get(0)[0]==11){
					g.setColor(Color.blue);
				}
				else g.setColor(Color.red);
				
				for (int i=0;i<agent.spaceMemory.backmoveList[b].detected.size();i++){
						float[] position=agent.body.computeMovement(agent.spaceMemory.backmoveList[b].getEventListDetected(i, (short)agent.environmentContext.getOffset(b), agent.environmentContext));
						
						float pos_x= (float)(position[0]*Math.cos(agent.body.getrz()) - position[1]*Math.sin(agent.body.getrz()));
						float pos_y= (float)(position[0]*Math.sin(agent.body.getrz()) + position[1]*Math.cos(agent.body.getrz()));

						g.drawOval((int)(700+34*(pos_x+agent.body.getpx())+12),
								   (int)( 10+34*(agent.getMain().env.getHeight()-1-(pos_y+agent.body.getpy()))+12), 10, 10);
	
						dx= 10*(float)Math.cos(position[2]+agent.body.getrz());
						dy= 10*(float)Math.sin(-position[2]-agent.body.getrz());
						g.drawLine((int)(700+34*(pos_x+agent.body.getpx())+17),
								   (int)(10+34*(agent.getMain().env.getHeight()-1-(pos_y+agent.body.getpy()))+17),
								   (int)(700+34*(pos_x+agent.body.getpx())+17+dx),
								   (int)(10+34*(agent.getMain().env.getHeight()-1-(pos_y+agent.body.getpy()))+17+dy));
				}
			}
		}
		
		
		// draw patterns
		if (agent.spaceMemory.patterns.size()>0)
		for (int j=EnvironmentContext.size2-1;j>=0;j--){
			for (int i=0;i<EnvironmentContext.size1;i++){

				g.setColor(new Color(agent.spaceMemory.patterns.get(0)[i*size2*3+j*3+2]/2+0.5f,
									 agent.spaceMemory.patterns.get(0)[i*size2*3+j*3  ]/2+0.5f,
									 agent.spaceMemory.patterns.get(0)[i*size2*3+j*3+1]/2+0.5f ));

				
				g.fillRect(1350 + i*8, 10+(EnvironmentContext.size2-j)*8, 8, 8);
			}
		}
		
		// draw actionMap
		for (int i=0;i<12;i++){
			for (int j=0;j<10;j++){
				if (agent.spaceMemory.projectionMap[i][j] && agent.spaceMemory.projectionMap2[i][j]>=0){
					if (agent.spaceMemory.actionMap[i][j]>0) g.setColor(Color.green);
					else if (agent.spaceMemory.actionMap[i][j]<0) g.setColor(Color.red);
					else g.setColor(Color.gray);
				}
				else g.setColor(Color.black);
				g.fillRect(1350+21*i, 350-21*j, 20, 20);
			}
		}
		
		for (int i=0;i<12;i++){
			for (int j=0;j<10;j++){
				if (agent.spaceMemory.projectionMap[i][j]) 
					g.setColor(new Color( 1-((  agent.spaceMemory.projectionMap2[i][j])+1)/2, ((  agent.spaceMemory.projectionMap2[i][j])+1)/2, 0) );
				else g.setColor(Color.gray);
				g.fillRect(1350+21*i, 600-21*j, 20, 20);
			}
		}
		
		g.setColor(Color.gray);
		g.fillRect(700, 650, 20, 20);
		g.fillRect(740, 650, 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){
					display[j*110+i]=!display[j*110+i];
				}
			}
		}
		
		if (clic_x>=500 && clic_x<700 && clic_y>=520 && clic_y<720){
			for (int i=0;i<display.length;i++) display[i]=true;
		}
		if (clic_x>=540 && clic_x<700 && clic_y>=560 && clic_y<720){
			for (int i=0;i<display.length;i++) display[i]=false;
		}
	}

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

}
