/*
 * RunNeuronAct.java
 *
 * Created on 24 of June 2007, 1:15
 */

/**
 *
 * @author Eng. Paulo Roque Silva
 */
import java.util.Iterator;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.CyclicBarrier;
import javax.sound.sampled.Clip;

public class RunNeuronAct implements Runnable {
    NeuronAct       neuro;                   // Neuron
    ConcurrentLinkedQueue<Signal> busIn;     // Queue in
    ConcurrentLinkedQueue<Signal> busId;     // Queue in Id
    ConcurrentLinkedQueue<Signal> busStand;  // Queue in standby
    CyclicBarrier   bar;                     // Step barrier
    Iterator<Signal> listen;                 // Listen id from busIn
    Signal			signInput;	 			 // Read input Signal
    Signal   		[]outSignal;			 // Output Actions
    boolean			first;					 // first standbay
    int				i, j;                    // Indexes to For cycles
    short[]         nil = {0};				 // for initialization
    Clip			clip1,
    				clip2,
    				clip3;
    
    /** Creates a new instance of RunNeuronAct */
    public RunNeuronAct(CyclicBarrier barr, NeuronAct ne,
    					ConcurrentLinkedQueue<Signal> queueIn,
       					ConcurrentLinkedQueue<Signal> queueStand,
       					ConcurrentLinkedQueue<Signal> queueId, Signal []outSig,
       					Clip cp1, Clip cp2, Clip cp3) {

        bar       = barr;
    	neuro     = ne;
        busIn     = queueIn;
        busId     = queueId;
        busStand  = queueStand;
        outSignal = outSig;
        first	  = true;
        clip1     = cp1;
        clip2     = cp2;
        clip3     = cp3;
    }
    
    public void writeBus() {        // usar o actPower
        
    	for (i=0; i<neuro.dendrites.size(); i++) {
    		if (neuro.getDendrite(i).emitter < Liberu.MOVES)   // REVER ACTRND not moves
    			outSignal[neuro.getDendrite(i).emitter].setActive(true); // falta a NOROADRENALINA#
/*    		if (neuro.getDendrite(i).emitter == Liberu.WALK) {						// NXT
    			clip1.stop();
    			clip1.flush();
    			clip1.setFramePosition(0);
    			clip1.start();
    		}
    		if (neuro.getDendrite(i).emitter == Liberu.TURN_LEFT) {					// NXT
    			clip2.stop();
    			clip2.flush();
    			clip2.setFramePosition(0);
    			clip2.start();
    		}
    		if (neuro.getDendrite(i).emitter == Liberu.TURN_RIGHT) {				// NXT
    			clip3.stop();
    			clip3.flush();
    			clip3.setFramePosition(0);
    			clip3.start();
    		}
*/    	}
    }
    
    public void run() {
    	int    neuroCount;        // Count  Sherings
        
        while (!neuro.end && !bar.isBroken()) {
        	// Cerebellum Cut & Stay Learning - surviving learning 
    		try {
                bar.await(); 
            }
            catch (InterruptedException ex) { 
                return;
            }
            catch (BrokenBarrierException ex) { 
                return;
                }
            if (neuro.standby) {
            	neuroCount = 0;
            	neuro.clearDendrite();          // REVER PARA SINTONIA FINA - retirar e dar creditos...
            	listen = busStand.iterator();
                while (listen.hasNext()) {        			     // read all the input bus
                	signInput = listen.next();
                    if (signInput.actPower > Liberu.MinSense) {
                		neuro.addDendrite(neuroCount, signInput.actPower);
                        System.out.println(neuro.id);           		 // a retirar
        	        	System.out.print("Add dendrite Body fired=");      // a retirar
                        System.out.println(neuroCount);           		 // a retirar
                        }
                	neuroCount += 1;
                }
            	listen = busId.iterator();
                while (listen.hasNext()) {        			     // read all the input bus
                	signInput = listen.next();
            		neuro.addDendriteID(signInput.emitter, signInput.actPower);
                    System.out.println(neuro.id);           		 // a retirar
    	        	System.out.print("Add dendriteID Body fired=");      // a retirar
                    System.out.println(signInput.emitter);           		 // a retirar
                    }
        		neuro.setStandby(false);
            } // End If
            else {											// retirar se com Tonus muscular - PARA ACTIVAR
            	neuro.clearSignalsAct();
            	listen = busIn.iterator();
                while (listen.hasNext()) {        			     // read all the input bus
                	signInput = listen.next();

            		for (j=0; j<neuro.dendritesID.size(); j++)	// listening process - came from body
            			if (signInput.emitter == neuro.getDendriteID(j).emitter) // I'm interested process
            				neuro.getDendriteID(j).setActive(true);
                	}     // BUS empty
                
                neuro.powerToAct();	 // came from body - motivation
                if (neuro.fire) {
    	        	System.out.print("NeuroAct Body fired............");      // a retirar
                    System.out.println(neuro.id);           		 // a retirar
    	        	writeBus();
            		}
            }
        }  // End While
    }
}
