/*
 * Sleep.java
 *
 * Created on 27 of July 2015, 15:57
 */
/**
 *
 * @author Paulo Roque Silva
 */
import java.util.Iterator;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;

public class Sleep implements Runnable {

	Signal				signInput; // Read input Signal
    Neuron          	[]time; // Neuron by TRAIL
    Iterator<Signal> 	listen; // Listen id from busIn
    CyclicBarrier 		sleepBarrier; // barrier of sleep


    public Sleep(CyclicBarrier barrSono, Neuron []tneurons) {

    	sleepBarrier = barrSono;
    	time 		 = tneurons;
    	}
    
    public void write(int w, float a, int q) {
    	
		Brain.BusSleepOut.add(new Signal(w, a, q));
    }
    
    public void write2(int w, float a, int q) {
    	
		Brain.BusSleepOut2.add(new Signal(w, a, q));
    }
    
    public void runSono() {
    	int i;
    	float em;
    	
    	try {
            sleepBarrier.await(); // synchronize nodes with the past nodes
        }
        catch(InterruptedException e) {
                e.printStackTrace();
            }
        catch (BrokenBarrierException ex) { 
            return;
        }
    	// ####################################################################
    	listen = Brain.BusSleepPreviews.iterator(); // Listening
    	if (listen.hasNext())
        	while (listen.hasNext()) { // read all the input bus
            	signInput = listen.next();
            	if (!time[0].newLearn(Math.abs(signInput.emitter))) { // "Listening"
                	if (signInput.actPower == Cerebellum.ESCape)
                		em = time[0].who;
                	else
                		em = signInput.actPower;
    				write(time[0].who, em, signInput.pleasure + time[Brain.ProSelf].finalQuality);
            	}
        	}
    	listen = Brain.BusSleepPreviews2.iterator(); // Listening
    	if (listen.hasNext())
        	while (listen.hasNext()) { // read all the input bus
            	signInput = listen.next();
            	if (signInput.emitter == time[0].who) // "Listening"
                	for (i=0; i<time[0].learn.size(); i++)
        				write2(time[0].getLearn(i).emitter, signInput.actPower, signInput.pleasure + time[Brain.ProSelf].finalQuality);
        	}
    	if (time[0].standby2 && Math.abs(Mind.exec) != Cerebellum.ESCape) { // STANDBY
       		time[0].standby2 = false;
        	time[0].addLearn(Math.abs(Mind.exec), 0, 0);
    	}
    }

    public void run() {
        
		while(!sleepBarrier.isBroken() && !Neuron.end) {
    		runSono();
    	}
    }
}