/*
 * Cerebellum.java
 *
 * Created on 27 of February 2013, 17:45
 */

/**
 *
 * @author Paulo Roque Silva
 */
import java.util.Iterator;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;

public class Cerebellum implements Runnable {

	static final int ESCape = Brain.NEURONS + 100;
	// Mentor ou aleat�rio
	Cortex          past; // Todo o cortex
	Neuron	        []neuroLeft;
	Neuron	        []neuroRigth;
    CyclicBarrier   bar; // Barreira de passos
    Iterator<Signal> listen; // Ouve bus
    Signal			signInput; // Guarda sinal
    int				nNeurons,
    				inv; // inverte a a��o
    
    public Cerebellum(CyclicBarrier barr, Neuron []he,
    		Neuron []hd, Cortex p, int nNTime) {

    	bar       = barr;
    	neuroLeft = he;
    	neuroRigth= hd;
    	past      = p;
    	nNeurons  = nNTime;
	}

    public void writeBus(int time, int pwr) {
    	int i, // indexe
    		absTime;
    	
        // Escreve no bus do Act
    	absTime = Math.abs(time);
    	System.out.print("time Cerebellum= "); // REMOVER
    	System.out.println(time); // REMOVER
    	if (Emotions.IdAct1 == ESCape &&
    			past.time[0][0].step >= Emotions.ActRandom)
        	for (i=0;
        			i<neuroLeft[absTime].perception.size();
        			i++) {
            	Brain.BusInAct.add(new Signal(
            			inv * neuroLeft[absTime].
            			getPerception(i).emitter,
            			(int)neuroLeft[absTime].
            			getPerception(i).actPower,
            			pwr));
            	System.out.println(neuroLeft[absTime].
            			getPerception(i).actPower);
            	// REMOVER
            }
    }
    
    public void run() {
    	int aPwr, temp;
    	
    	while (!Neuron.end && !bar.isBroken()) {
    		try {
                bar.await(); 
            }
            catch (InterruptedException ex) { 
                return;
            }
            catch (BrokenBarrierException ex) { 
                return;
            }
    		aPwr = 0;
            neuroLeft[neuroLeft[0].pointer].
            clearPerceptions();
            listen = Brain.BusInProSelf.iterator();
            while (listen.hasNext()) { // L� todo o bus
               	signInput = listen.next();
               	neuroLeft[neuroLeft[0].pointer].
               	addPerception(signInput.emitter,
               	signInput.actPower, signInput.pleasure);
        	}
            while (!Brain.BusInAct.isEmpty())
        		Brain.BusInAct.poll();

    		if (Remember.RecentMost + 1 <
    				neuroLeft.length)
    			temp = Remember.RecentMost + 1;
    		else
    			temp = 0;
    		if (neuroLeft[neuroLeft[0].pointer].
    				perception.isEmpty())
    			aPwr = 0;
    		else
    			aPwr = (int)neuroLeft[neuroLeft[0].
    			    pointer].getPerception(0).
    				actPower;
    		inv = 1;
			if (Emotions.Good < 0) {
            	inv = -1;
            	writeBus(Emotions.Good, aPwr);
			}
			else
			if (!Brain.BackHome && Emotions.IdAct1 ==
					Cerebellum.ESCape) {
				if (Cortex.Thumb) {
					if (Brain.Saudade) {
						writeBus(Cortex.exec, aPwr);
						Cortex.exec =
								Math.abs(Cortex.exec);
						Mind.veloc = 0.75F; // Menos r�pido
						Interface.Ink = 3;
					}
					else
						if (Brain.Ansiedade) {
							writeBus(Cortex.exec, aPwr);
							Mind.veloc = 1.5F;//Mais r�pido
							Interface.Ink = 4;
						}
						else {
							writeBus(temp, aPwr);
							Cortex.exec = temp;
						}
				}
				else {
					if (Brain.Ansiedade) {
						writeBus(Cortex.exec, aPwr);
						Mind.veloc = 1.5F; // Mais r�pido
						Interface.Ink = 4;
					}
					else
						if (Brain.Saudade) {
							writeBus(Cortex.exec, aPwr);
							Cortex.exec =
									Math.abs(Cortex.exec);
							Mind.veloc = 0.75F;
							Interface.Ink = 3;
						}
						else {
							writeBus(temp, aPwr);
							Cortex.exec = temp;
						}
					}
			}
			else
				if (Emotions.IdAct1 == Cerebellum.ESCape) {
					writeBus(temp, aPwr);
					Cortex.exec = temp;
				}
        } // Fim ciclo While
    }
}