/*
 * Emotions.java
 *
 * Created on 21 of January 2010, 16:42
 */

/**
 *
 * @author Paulo Roque Silva
 */

import java.util.Iterator;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import javax.swing.*;
import javax.swing.event.*;

public class Emotions implements Runnable {
	static final int 				ActRandom 	= 30;
	// N�mero de passos aleat�rios
	static final int 				SpeakRandom = 15;
	// N�mero de vogais aleat�rias
	static final int 				NSpeaks = 3;
	// N�mero de Vogais
	static int						Normal = 0;
    public static int				QF, // Qualidade final
    								QP,
    								// Qualidade presente
    								QR,
    								// Qualidade lembrada
    								Good,
    								Good2,
    							// Identifica��o recordado
    								IdAct1, // A��o
    								idSound,
    								PwEm; // Amplitude a��o
    public static boolean			EmotionNew, // 
    								// Se novidade
    								ActualPain,
    								// Se sente Dor
    								WARNING;
    public static Signal 	        []BodyAct;
    							// A��es no corpo do rob�
    private Cortex					past; // Rede do c�rtex
    Iterator<Signal> 				listen; // Ouve bus
    CyclicBarrier 				    stepBarrDecision;
    							// Barreira do Emotions
    CyclicBarrier 				    stepBarrDecision2;
    							// Barreira 2 do Emotions
    public static boolean			emotional,
    								rir,
    								choro;
    							// Se fica emocional
    JTextField      				text; // Texto lido
    DocumentListener				listener; // Ouve bus
    String		  					key; // Tecla primida
    
    public Emotions(CyclicBarrier barrD,
    		CyclicBarrier barrD2, Cortex me,
    		Signal []bodyA, JTextField txt) {

    	stepBarrDecision = barrD;
    	stepBarrDecision2 = barrD2;
    	past 		 = me;
    	BodyAct 	 = bodyA;
	    text		 = txt;
    	PwEm 		 = Mind.Power;
	    emotional 	 = false;
	    rir			 = false;
	    choro		 = false;
    	ActualPain   = false;
    	IdAct1 		 = Cerebellum.ESCape; // Sem a��o
		idSound 	 = Cerebellum.ESCape;
        Liberu.Already = true;
        WARNING = false;
        key = " ";
	    listener     = new LearnListener();
        text.getDocument().addDocumentListener(listener);
    }
    
    public void idAct1Action(int idAction) {
    	
		IdAct1 = idAction;
    }
	
	public void emotionSpeak() {

		idSound = Cerebellum.ESCape;
    	if (IdAct1 == Cerebellum.ESCape) {
    		idSound = Brain.Vogal1 +
           			(int)Math.rint(Math.random() *
           			(Emotions.NSpeaks - 1));
           	BodyAct[idSound].setActive(true);
    		BodyAct[idSound].setActPower(PwEm);
    	}
    	System.out.println("SPEEK...  :-)"); //REMOVER
	}
	
	public void emotionNew(boolean empty) {

		// Emo��o de novidade - Genetica
		if (empty) {
			emotional = true;
			EmotionNew = true;
			System.out.println(
					"Emotion NEW...    :-0"); //REMOVER
			BodyAct[Brain.New].setActive(true);
			WARNING = true;
		}
	}
	
	private void emotionNormal() {

		emotional = false;
    	ActualPain = false;
		EmotionNew = false;
		rir			= false;
		choro		= false;
		System.out.println(
				"Emotion Normal... :-|"); //REMOVER
	}
	
	public void emotionHappy() {

		emotional = true;
    	BodyAct[Brain.Happy].setActive(true);
    	// Expres�o gen�tica de felicidade
    	System.out.println(
    			"Emotion HAPPY...  :-)"); //REMOVER
	}
	
	public void emotionSad() {

		emotional = true;
    	BodyAct[Brain.Sad].setActive(true);
    	// Express�o gen�tica de tristeza
		System.out.println(
				"Emotion Sad...    :-("); //REMOVER
	}
	
	public void emotionPAIN() {

    	ActualPain   = true;
    	emotional = true;
    	BodyAct[Brain.PAIN].setActive(true);
    	// Express�o gen�tica de Dor
		System.out.println(
				"Emotion PAIN...   ;-("); //REMOVER
	}

	public void emotionRIR() {

    	emotional = true;
    	rir		  = true;
		Mind.clip4.setMicrosecondPosition(0);
   		Mind.clip4.start();
		System.out.println(
				"Emotion RIR...   ;-)"); //REMOVER
	}

	public void emotionCHORAR() {

    	emotional = true;
    	choro	  = true;
		Mind.clip5.setMicrosecondPosition(0);
   		Mind.clip5.start();
		System.out.println(
				"Emotion CHORAR...   :-#"); //REMOVER
	}

	public void emotionAfraid() {

    	emotional = true;
    	BodyAct[Brain.Afraid].setActive(true);
		System.out.println(
				"Emotion Afraid...   ,-("); //REMOVER
	}
			
	public void runEmotions() {
		int i, j; // indexes
		
    	try {
            stepBarrDecision.await(); // Sincroniza
        }
        catch(InterruptedException e) {
                e.printStackTrace();
            }
        catch (BrokenBarrierException ex) { 
            return;
        }
    	// ################################# DECIDE #######
    	Interface.Ink = 0;
        for (i=0; i<Brain.SENSES; i++) {
        	if (past.time[0][0].step > ActRandom) {
            	emotionNew(Remember.NewSense[i]);
        		if (i == Brain.Taste &&
        				Remember.NewSense[Brain.Taste] &&
        				!ActualPain)
        			IdAct1 = past.time[Good][i].
        			attentionOfFire(i);
        		if (i == Brain.Vision &&
        				Remember.NewSense[Brain.Vision] &&
        				!ActualPain)
        			IdAct1 = past.time[Good][i].
        			attentionOfFire(i);
        	}
		}
    	
    	QP = past.
    			time[past.time[0][0].
    			     pointer][Brain.ProSelf].finalQuality;
    	QR = past.
    			time[Math.abs(Good)][Brain.ProSelf].
    			finalQuality;
		System.out.println(QP);    // RETIRAR
		System.out.println(QR);    // RETIRAR
    	QF = QP + QR;
    	Interface.QF = QF;
        Normal = 0;
        for (i=0; i < past.nNeuronsTime; i++)
        	Normal += past.time[i]
        			[Brain.ProSelf].finalQuality;
        if (past.time[0][0].step <
        		past.nNeuronsTime &&
        		past.time[0][0].step != 0)
        	Normal = (int)(Normal /
        			past.time[0][0].step);
        else
        	Normal = (int)(Normal /
        			past.nNeuronsTime);
    	if (Normal >= 0)
        	if (QF < 0 && past.time[0][0].step > ActRandom)
            	emotionSad();
        	else {
            	if (QF > 2 * Normal &&
            			past.time[0][0].step > ActRandom)
                	emotionHappy();
        	}
    	else
        	if (QF < 2 * Normal &&
        			past.time[0][0].step > ActRandom)
            	emotionSad();
        	else {
            	if (QF > 0 &&
            			past.time[0][0].step > ActRandom)
                	emotionHappy();
        	}
    	if (QP < Cortex.lastQuality &&
    			past.time[0][0].step > ActRandom) {
    		emotionAfraid();
    		if (BodyAct[Brain.Happy].active)
    			emotionRIR();
    		else
    			if (BodyAct[Brain.Sad].active)
        			emotionCHORAR();
        		else
            		emotionSpeak();
    	}
		Cortex.lastQuality = QP;
        // ######  Recente decis�o ######
    	if (ActualPain && past.time[0][0].step > ActRandom)
    		// 
    		Good = -Good; // Ato oposto de reflexo de Dor 
		// ###############################
    	for (i=0; i<past.nNeuronsTime; i++)
        	for (j=0; j<past.time[i][0].learn.size();
        			j++) {
        		if (Math.abs(past.time[i][0].getLearn(j).
        				emitter) == past.time[i][0].
        				pointer)
        			past.time[i][0].removeLearn(j);
        	}
    	// ################################# ACT ##########
		System.out.print("Key****= "); // RETIRAR
		System.out.println(key); // RETIRAR
    	
    	while (!Brain.BusInAct.isEmpty())
    		Brain.BusInAct.poll();
        
        // ################## ALEAT�RIO - MENTOR ##########
    	try {
            stepBarrDecision2.await(); // sincroniza
        }
        catch(InterruptedException e) {
                e.printStackTrace();
            }
        catch (BrokenBarrierException ex) { 
            return; 
        }
        if (IdAct1 != Cerebellum.ESCape ||
        		past.time[0][0].step < ActRandom) {
        	if (IdAct1 != Cerebellum.ESCape) {
        		BodyAct[IdAct1].setActive(true);
        		BodyAct[IdAct1].setActPower(PwEm);
        		System.out.print("MentorA= "); //REMOVER
        		System.out.println(IdAct1); //REMOVER
        		Interface.Ink = 2; // Verde
        	}
        	else {
               	IdAct1 = (int)Math.rint(Math.random() *
               			(Brain.ACTS-1));
                if (past.time[0][0].step == 0) {
                	IdAct1 = Brain.WALK; // Primeira a��o
                }
        		BodyAct[IdAct1].setActive(true);
        		BodyAct[IdAct1].setActPower(PwEm);
        		System.out.print("Random1= "); //REMOVER
        		System.out.println(IdAct1); //REMOVER
        		Interface.Ink = 1; // Vermelho
        	}
    		past.actNode[IdAct1].standby = true;
        	IdAct1 = Cerebellum.ESCape; // Sem a��o
        }
        if (idSound != Cerebellum.ESCape) {
    		past.actNode[idSound].standby = true;
        	idSound = Cerebellum.ESCape; // Sem a��o
        }

       	// ##################### R E L � G I O ############
        System.out.print("step= "); // REMOVER
       	System.out.println(past.time[0][0].pointer);
       								// REMOVER
    	if (!ActualPain) { // Incremento do passo sem Dor
           	for (j=0; j<Cortex.Senses; j++)
            	for (i=0; i<past.nNeuronsTime; i++) {
            		past.time[i][j].addStep();
            		// Rel�gio de vida do rob�
            		past.time[i][j].addPointer();
            		// Rel�gio da janela temporal do rob�
                	if ( past.time[i][j].pointer >
                	past.nNeuronsTime - 1)
                		past.time[i][j].setPointer(0);
            	}
        	for (i=0; i<past.nNeuronsTime; i++) {
        		past.hemisphereLeft[i].addStep();
        		// Rel�gio de vida do rob�
        		past.hemisphereLeft[i].addPointer();
        		// Rel�gio da janela temporal do rob�
            	if ( past.hemisphereLeft[i].pointer >
            	past.nNeuronsTime - 1)
            		past.hemisphereLeft[i].setPointer(0);
        		past.hemisphereRigth[i].addStep();
        		// Rel�gio de vida do rob�
        		past.hemisphereRigth[i].addPointer();
        		// Rel�gio da janela temporal do rob�
            	if ( past.hemisphereRigth[i].pointer >
            	past.nNeuronsTime - 1)
            		past.hemisphereRigth[i].setPointer(0);
        	}
    	}
    	// ############ Fim rel�gio #######################
        
        if (emotional) // Regresso ao estado normal
        	emotionNormal();
	}

    public void setLearn() {
    	int temp;
    	
		key = (String)text.getText().trim();
		Liberu.InterFace.repaint();
		System.out.print("Key= "); // RETIRAR
		System.out.println(key); // RETIRAR
		temp = Integer.parseInt(key);
		if (temp > 0 && temp < 65)
			if (key != "")
				Mind.local = temp;
		Liberu.InterFace.repaint();
		System.out.print("Local= "); // RETIRAR
		System.out.println(Mind.local); // RETIRAR
    }
	
    private class LearnListener implements
    DocumentListener {
    	
    	public void insertUpdate(DocumentEvent e)
    	{ setLearn(); }
    	public void removeUpdate(DocumentEvent e)
    	{ setLearn(); }
    	public void changedUpdate(DocumentEvent e) {}
    }
    
    public void run() {
        
		while(!stepBarrDecision.isBroken() &&
				!stepBarrDecision2.isBroken() &&
				!Neuron.end) {
    		runEmotions();
    	}
        System.out.println("End of Emotions Thread...");
    }
}