/*
 * RunNeuronPast.java
 *
 * Created on 24 of June 2007, 0:07
 */

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

public class RunNeuronPast implements Runnable {
    Neuron          neuro;                   // Neuron
    ConcurrentLinkedQueue<Signal> busIn;     // Queue in
    ConcurrentLinkedQueue<Signal> busOut;    // Queue out
    CyclicBarrier   bar;                     // Step barrier
    CyclicBarrier   bar2;                    // Step barrier
    Iterator<Signal> listen;                 // Listen id from busIn
    Signal			signInput;	 			 // Read input Signal
    int				count1, count2;          // To check if is old
    int				i, j,                    // Indexes to For cycles
    				neuronCount,             // to calculate the index
    				nneurons;				 // # Neurons
    
    /** Creates a new instance of RunNeuronPast */
    public RunNeuronPast(CyclicBarrier barr, CyclicBarrier barr2, Neuron ne,
                             ConcurrentLinkedQueue<Signal> queueIn,
                             ConcurrentLinkedQueue<Signal> queueOut,
                             int nnodes) {
        
        bar      = barr;
        bar2	 = barr2;
        neuro    = ne;
        busIn    = queueIn;
        busOut   = queueOut;
        nneurons = nnodes;
    }
    
    public void writeBus() {
        Signal		newSignal;
    	
        newSignal = new Signal(neuro.id, PlayLiberu.Power);     // Power used to group Ids - neuro.id
        newSignal.setValue(neuro.value);                        // this value isn't used
        busOut.add(newSignal);
    }
    
    public void run() {
        
        while (!neuro.end && !bar.isBroken() && !bar2.isBroken() && neuro.step < nneurons) {
            try {
                bar.await(); 
            }
            catch (InterruptedException ex) { 
                return;
            }
            catch (BrokenBarrierException ex) { 
                return;
                }
            if (neuro.step == 0 && neuro.id == 0)
            	neuro.setStandby(true);
            
    		neuro.clearSignals();   // TUNNING - Absolute - move to *
        	if (neuro.standby)
         		 // renew dendrites
          		neuro.clearDendrite();
    		neuronCount = 0;
        	listen = busIn.iterator();
            while (listen.hasNext()) {        // read all the input bus
                signInput = listen.next();
                if (neuro.standby) {
            		 // Present neuron - recording process
        			neuro.addDendriteCredit(signInput.emitter, signInput.actPower);
        			System.out.println(neuro.id);                     // a retirar
//        			System.out.print("NeuroPast addDentrine...");           // a retirar
//        			System.out.println(signInput.actPower);                     // a retirar
                }
                else {
            		if (signInput.actPower > Liberu.MinSense && neuro.dendrites.size() > 0)
            			if (neuro.getDendrite(neuronCount).recPower > Liberu.MinSense) {
            				neuro.getDendrite(neuronCount).setActive(true);
            				neuro.getDendrite(neuronCount).setActPower(signInput.actPower);
            			}
                }
                neuronCount += 1;
            	} // all the input bus was read

        	if (neuro.powerOfFire()) {
                System.out.print("NeuroPast fired...");           // a retirar
                System.out.println(neuro.id);                     // a retirar
        		writeBus();
        	}
        	// STEP 2 *****************************************************************
            try {
                bar2.await(); 
            }
            catch (InterruptedException ex) { 
                return;
            }
            catch (BrokenBarrierException ex) { 
                return;
                }
        	if (neuro.standby && neuro.keep) {
         		 // Present neuron - recording process
          		neuro.setStandby(false);
          		neuro.setFire(true);
          		writeBus();
    			System.out.println(neuro.id);                     // a retirar
      		}
    	} // End While
    }
}
