/*
 * Interface.java
 *
 * Created on 8 of February 2006, 2:04
 */
/**
 *
 * @author  Paulo Roque Silva
 */
import javax.swing.*;
import java.awt.*;
import java.util.Date;

public class Interface extends JPanel {
    
    public static final long    serialVersionUID = 2016L; // Interface Version
    static final int	MaxDisplay = 300; // maximum neurons to be displayed = #neurons C. elegans
    final int 			RESETCiclo = 30;
	public static int   Ink; // ink color 0=black 1=red 2=green 3=blue
	public static int	[]Taste;
	public static int	[]Vision;
	public static int	[]Sound;
	public static int	[]Smell;
	public static int   Lovely;
	public static int   QF;
    public static boolean Warned; // true if self warned
    public static boolean WarnSense[]; // true if self warned
	Brain	      		mind; // pointer for Liberu mind
    boolean     		execute; // if displays Liberu data
    Font        		fontDefault, font, sansBold14, sansBold28;
    Color       		colorBefore;
    int         		i, n; // indexes
    long				ciclo;
    int					resetCiclo;
    Image 				imge;
    
    /** Creates new form Interface */
    public Interface() {
    	int i;

        imge = Toolkit.getDefaultToolkit().getImage("formicaLogo120pxl.jpg");
        execute = false;
        ciclo = 0;
        resetCiclo = RESETCiclo;
    	Ink = 0;
    	Taste = new int[Brain.NanalogTaste];
        for (i=0; i<Taste.length; i++)
        	Taste[i] = 0;
    	Vision = new int[Brain.NanalogVision];
        for (i=0; i<Vision.length; i++)
        	Vision[i] = 0;
    	Sound = new int[Brain.NanalogSound];
        for (i=0; i<Sound.length; i++)
        	Sound[i] = 0;
    	Smell = new int[Brain.NanalogSmell];
        for (i=0; i<Smell.length; i++)
        	Smell[i] = 0;
        Lovely = 0;
        QF = 0;
        Warned = false;
        WarnSense = new boolean[Brain.SENSES];
        for (i=0; i < Brain.SENSES; i++)
        	WarnSense[i] = false;
    }
    
    public void displayRobot(Brain m, boolean ex) {
        
    	mind = m;
        execute = ex;
    }
    
    public void paintComponent(Graphics g) {
    	int n, m, rct, bom, //index
    		inicioJanela,
    		fimJanela,
    		pointerJanela,
    		temp; // Defines window
   		float t=0;
   		Font fDefault, f;
       
        super.paintComponent(g);
        g.drawImage(imge, 500, 200, null, null);
        sansBold14 = new Font("SansSerif", Font.BOLD, 14);
        sansBold28 = new Font("SansSerif", Font.BOLD, 28);
        font = new Font("SansSerif", Font.PLAIN, 28);
        fontDefault = g.getFont();
        colorBefore = g.getColor();
        g.setFont(font);

        if (Cortex.Warn && Emotions.WARNING || Warned) {
        	Warned = true;
            g.setColor(Color.RED);
            g.setFont(sansBold28);
            for (n=0; n < Brain.SENSES; n++) {
            	if (Remember.NewSense[n])
                	WarnSense[n] = Remember.NewSense[n];
            	if (WarnSense[n])
            		switch (n) {
            		case Brain.Taste: {
                        g.drawString("WARNING - New event!" + " TASTE", 650, 280 + 0 * 30);
                        break;
            		}
            		case Brain.Vision: {
                        g.drawString("WARNING - New event!" + " VISION", 650, 280 + 1 * 30);
                        break;
            		}
            		case Brain.Tact: {
                        g.drawString("WARNING - New event!" + " TACT", 650, 280 + 2 * 30);
                        break;
            		}
            		case Brain.Sound: {
                        g.drawString("WARNING - New event!" + " SOUND", 650, 280 + 3 * 30);
                        break;
            		}
            		case Brain.Smell: {
                        g.drawString("WARNING - New event!" + " SMELL", 650, 280 + 4 * 30);
                        break;
            		}
            		case Brain.ProSelf: {
                        g.drawString("WARNING - New event!" + " SELF", 650, 280 + 5 * 30);
                        break;
            		}
            		default:
                        g.drawString("ERROR case...", 650, 280 + 5 * 30);
            		}
            }
        	g.setColor(colorBefore);
            g.setFont(font);
        }
        
        g.drawString("Step= ", 65, 30);
        g.drawString(Integer.toString(Mind.NStep), 250, 30);
        if (Mind.NStep <= Emotions.ActRandom) {
            g.setColor(Color.RED);
            g.drawString("Womb", 300, 30);
        	g.setColor(colorBefore);
        }

        g.drawString("Time(s)= ", 65, 70);
    	t = (float)mind.past.timeLifeReal/1000/60/60; // t in hours fraction
        g.drawString("hr", 250, 70);
        g.drawString(Long.toString((long)Math.floor(t)) , 220, 70);
    	t = (float)(t - (int)Math.floor(t)); // t = rest in hours
        g.drawString("min", 360, 70);
        t = t * 60; // t in minutes fraction
        g.drawString(Long.toString((long)Math.floor(t)) , 330, 70);
        g.drawString("s", 470, 70);
        t = (float)(t - (int)Math.floor(t)); // t = rest in minutes
        g.drawString(Long.toString((long)Math.floor(t*60)) , 430, 70); // t in seconds
    
        g.drawString("Percentage (Lovely/Neurons)= ", 65, 110);
        if (Liberu.Already)
            g.drawString(Integer.toString((int)(Lovely/(float)mind.past.nNeuronsTime*100)), 480, 110);

        g.drawString("Born: ", 65, 150);
        if (!execute)
            g.drawString((new Date()).toString() , 150, 150);
        else
            g.drawString((new Date(mind.past.bornTime).toString()) , 150, 150);
        
        g.drawString("Cycle(ms): ", 65, 190);
        if (mind.past.getCicle() > ciclo && execute)
        	ciclo = mind.past.getCicle();
        g.drawString(Long.toString(ciclo) , 300, 190);
        resetCiclo -= 1;
        if (resetCiclo < 0) {
        	resetCiclo = RESETCiclo;
        	ciclo = 0;
        }
        //  ###################################################################
        if (execute) {
            g.drawString("Remember" , 350, 230);
            g.drawString("Real" , 200, 230);
        }
        // TASTE
        if (Liberu.Already)
        	if (Remember.NewSense[0])
                g.setColor(Color.BLUE);
        g.drawString("Taste  = ", 65, 270);
    	for (n=0; n<Brain.NanalogTaste; n++) {
            g.drawString(Integer.toString(Taste[n]), 200+n*40, 270);
            if (execute)
                g.drawString(Integer.toString((int)mind.past.time[Math.abs(Emotions.Good)][Brain.Taste].getPerception(n).recPower), 350+n*40, 270);
    	}
        g.setColor(colorBefore);
        // VISION
        if (Liberu.Already)
            if (Remember.NewSense[1])
                g.setColor(Color.BLUE);
        g.drawString("Vision  = ", 65, 310);
    	for (n=0; n < Brain.NanalogVision; n++) {
            g.drawString(Integer.toString(Vision[n]), 200+n*40, 310);
            if (execute)
                g.drawString(Integer.toString((int)mind.past.time[Math.abs(Emotions.Good)][Brain.Vision].getPerception(n).recPower), 350+n*40, 310);
    	}
        g.setColor(colorBefore);
        // TACT
        if (Liberu.Already)
            if (Remember.NewSense[2])
                g.setColor(Color.BLUE);
        g.drawString("Tact     = ", 65, 350);
        if (Mind.Tact[0] == Brain.TACT)
        	g.drawString("Obstacle", 200, 350);
        else
            g.drawString("        ", 200, 350);
        if (Liberu.Already && execute)
            if (mind.past.time[Math.abs(Emotions.Good)][Brain.Tact].getPerception(0).recPower > Mind.Power/2)
            	g.drawString("Obstacle", 350, 350);
            else
                g.drawString("        ", 350, 350);
        g.setColor(colorBefore);
        // SOUND
        if (Liberu.Already)
            if (Remember.NewSense[3])
                g.setColor(Color.BLUE);
        g.drawString("Sound  = ", 65, 390);
        temp = 0;
        for (n=0; n < Brain.NanalogSound; n++)
        	temp += Sound[n];
        temp = (int)(temp / Brain.NanalogSound);
        g.drawString(Integer.toString(temp), 200, 390);
        if (execute) {
            temp = 0;
            for (n=0; n < Brain.NanalogSound; n++)
            	temp += (int)mind.past.time[Math.abs(Emotions.Good)][Brain.Sound].getPerception(n).recPower;
            temp = (int)(temp / Brain.NanalogSound);
            g.drawString(Integer.toString(temp), 350, 390);
        }
        g.setColor(colorBefore);
        // OLFACT
        if (Liberu.Already)
            if (Remember.NewSense[4])
                g.setColor(Color.BLUE);
        g.drawString("Smell  = ", 65, 430);
        for (n=0; n < Brain.NanalogSmell; n++) {
            g.drawString(Integer.toString(Smell[n]), 200+n*40, 430);
            if (execute)
                g.drawString(Integer.toString((int)mind.past.time[Math.abs(Emotions.Good)][Brain.Smell].getPerception(n).recPower), 350+n*40, 430);
        }
        g.setColor(colorBefore);

        if (Liberu.Already && execute)  // good action
        	for (i=0; i<mind.past.time[Math.abs(Emotions.Good)][Brain.ProSelf].perception.size(); i++)
            	if (mind.past.time[Math.abs(Emotions.Good)][Brain.ProSelf].getPerception(i).recPower > Brain.MinSense)
            		switch (i) {
                	case Brain.SPEAK:
                    	g.drawString("Speak", 350, 470);
                    	break;
                	case Brain.ABACK:
                    	g.drawString("A Back", 350, 470);
                    	break;
                	case Brain.AWALK:
                    	g.drawString("A Walk", 350, 470);
                    	break;
                	case Brain.BBACK:
                    	g.drawString("B Back", 350, 470);
                    	break;
                	case Brain.BWALK:
                    	g.drawString("B Walk", 350, 470);
                    	break;
                	default:
                	}
        g.drawString("Energy = ", 650, 110);
        if (Brain.Energy) {
            g.setColor(Color.BLUE);
            g.drawString("Need", 780, 110);
        	g.setColor(colorBefore);
        }
        else
            g.drawString("No need", 780, 110);
        
        g.drawString("Happy = ", 650, 150);
        if (QF >= 0) {
            g.setColor(Color.GREEN);
            g.drawString(Integer.toString(QF), 780, 150);
        	g.setColor(colorBefore);
        }
        else {
            g.setColor(Color.RED);
            g.drawString(Integer.toString(QF), 780, 150);
        	g.setColor(colorBefore);
        }

        g.drawString("Saudade= ", 650, 190);
        if (Mind.Saudade) {
            g.setColor(Color.BLUE);
            g.drawString("Yes", 780, 190);
        	g.setColor(colorBefore);
        }
        else
            g.drawString("No", 780, 190);

        g.drawString("Anxiety= ", 650, 230);
        if (Mind.Anxiety) {
            g.setColor(Color.YELLOW);
            g.drawString("Yes", 780, 230);
        	g.setColor(colorBefore);
        }
        else
            g.drawString("No", 780, 230);

        g.drawString("Action  = ", 65, 520);
        if (Ink == 1)
            g.setColor(Color.RED);
        if (Ink == 2)
            g.setColor(Color.GREEN);
        if (Ink == 3)
            g.setColor(Color.BLUE);
        if (Mind.Action[Brain.SPEAK].active)
            g.drawString("Speak", 200, 520);
        if (Mind.Action[Brain.AWALK].active)
            g.drawString("A walk", 300, 520);
        if (Mind.Action[Brain.ABACK].active)
            g.drawString("A back", 400, 520);
        if (Mind.Action[Brain.BWALK].active)
            g.drawString("B walk", 500, 520);
        if (Mind.Action[Brain.BBACK].active)
            g.drawString("B back", 600, 520);

        g.setColor(colorBefore);
// ##############################################################################
        g.drawString("Emotion= ", 65, 560);
        if (Emotions.ActualPain) {
        	g.setColor(Color.RED);
            g.drawString("Pain", 200, 560);
        	g.setColor(colorBefore);
        }
        if (Emotions.EmotionNew)
            g.drawString("New", 280, 560);

        g.drawString("Lovely =", 360, 560); // Beautiful
        g.drawString(Integer.toString(Lovely), 500, 560);

        if (Liberu.Already)
            if (Emotions.BodyAct[Brain.Happy].active)
                g.drawString("Happy", 560, 560);

        if (Liberu.Already)
            if (Emotions.BodyAct[Brain.Sad].active)
                g.drawString("Sad", 650, 560);

        if (Liberu.Already)
            if (Emotions.BodyAct[Brain.Afraid].active)
                g.drawString("Afraid", 750, 560);
        
        if (execute) {
            g.drawString("Ta", 320 - 250, 570 + 30);
            g.drawString("Vi", 320 - 250, 570 + 70);
            g.drawString("Tc", 320 - 250, 570 + 110);
            g.drawString("So", 320 - 250, 570 + 150);
            g.drawString("Sm", 320 - 250, 570 + 190);
            g.drawString("PS", 320 - 250, 570 + 230);
            g.drawLine(350 - 250, 570 + 30, 350 - 250, 570 + 30 + 40 * Brain.SENSES); // Y axis
            if (mind.past.nNeuronsTime > MaxDisplay)
            	m = MaxDisplay;
            else
            	m = mind.past.nNeuronsTime;
            g.drawLine(350 - 250, 570 + 30 + 40 * Brain.SENSES, 350 + m - 250,
            		 570 + 30 + 40 * Brain.SENSES); // X axis
            n = 0;
            while (n < MaxDisplay) {
                if (n % 10 == 0) g.drawLine(350 + n+1 - 250, 570 + 30 + 40 * Brain.SENSES,
        				350 + n+1 - 250, 570 + 30 + 40 * Brain.SENSES + 3); // X scale 10 fraction
                n += 1;
            }

            g.drawString("Fired neurons, by Past...", 350 - 250, 570 + 30 + 40 * Brain.SENSES + 30);

			if (mind.past.time[0][0].pointer > MaxDisplay) {
				fimJanela = mind.past.time[0][0].pointer;
				pointerJanela = MaxDisplay;
				inicioJanela = mind.past.time[0][0].pointer - MaxDisplay;
			}
			else {
				fimJanela = MaxDisplay;
				pointerJanela = mind.past.time[0][0].pointer;
				inicioJanela = 0;
			}
	        // pointer
			g.drawLine(350 + pointerJanela+1 - 250, 570 + 29,
					   350 + pointerJanela+1 - 250, 570 + 30 + 40 * Brain.SENSES - 1);

			fDefault = g.getFont();
			f = new Font(g.getFont().getFontName(),
					g.getFont().getStyle(),
					16);
			g.setFont(f);
			g.drawString(Integer.toString(inicioJanela), 350 - 250, 570 + 30 + 40 * Brain.SENSES + 15);
			g.drawString(Integer.toString(fimJanela), 650 - 250, 570 + 30 + 40 * Brain.SENSES + 15);

			g.setFont(fDefault);
			// Neuron fires
            m = 0;
            while (m <= fimJanela && inicioJanela + m < mind.past.nNeuronsTime) {
            	for (i=0; i < Brain.SENSES; i++)
            		if (mind.past.time[inicioJanela+m][i].fire)
            			g.drawLine(350 + m+1 - 250, 570 + 30 + 40 * i - 1, 350 + m+1 - 250, 570 + 30 + 40 * i - 1);
            	m += 1;
            }
 			// Right hemisphere - quality
            m = 0;
            while (m <= fimJanela && inicioJanela + m < mind.past.nNeuronsTime) {
            	for (i=0; i < mind.past.time[inicioJanela+m][0].learn.size(); i++) {
            		bom = mind.past.time[inicioJanela+m][0].getLearn(i).emitter;
                    if (bom >= inicioJanela && bom <= fimJanela)
            			g.drawLine(350 + m+1 - 250, 570 + 230 - bom - inicioJanela, 350 + m+1 - 250, 570 + 230 - bom - inicioJanela);
                	}
            	m += 1;
            }
            // recent
            g.setColor(Color.RED);
            rct = Math.abs(Mind.Bom);
            if (rct >= inicioJanela && rct <= fimJanela)
                g.drawString("+", 350 + rct - inicioJanela - 3 - 250, 570 + 30 + 40 * Brain.SENSES + 4);
            g.setFont(f);
			g.drawString(Integer.toString(rct), 350 + rct - inicioJanela - 250, 570 + 30 + 40 * Brain.SENSES - 10);
            g.setFont(fDefault);
 			// Neuron act fires
            g.drawString("Fired neurons, by Act...", 350 - 250, 570 + 50 + 40 * Brain.SENSES + 30);
            n = 0;
            while (n < mind.past.nNeuronsAct && n < MaxDisplay) {
        		if (mind.past.actNode[n].fire)
                    g.drawString("*", 350 + n+1 - 250, 570 + 50 + 40 * (Brain.SENSES-1) - 3);
            	n += 1;
            }
            g.setColor(colorBefore);
        } // end if
    }
}