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

/**
 * web site: www.vitaliberu.pt
 * email: sysliberal@gmail.com; paulo@vitaliberu.pt
 * @author Paulo Roque Silva
 */
import java.util.Iterator;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;

public class Act implements Runnable {
    public static boolean	Thumb; // Left Up if true else Right Up
    Neuron	        neuro; // Neuron
    CyclicBarrier   bar; // Step barrier
    Iterator<Signal> listen; // Listen id from busIn
    Signal			signInput; // Read input Signal
    Signal   		[]outSignal; // Output Actions
	boolean			invert;
    
    /** Creates a new instance of RunNeuronAct */
    public Act(CyclicBarrier barr, Neuron ne, Signal []outSig) {

        bar       = barr;
    	neuro     = ne;
        outSignal = outSig;
        Thumb = false;
    }
    
    public int invertAct(int actID) { // use the actPower

    	switch (actID) {  //  Changes action
    	case Brain.SPEAK:
    		return(Brain.SPEAK); 
    	case Brain.ABACK: 
    		return(Brain.AWALK); 
    	case Brain.AWALK: 
    		return(Brain.ABACK); 
    	case Brain.BBACK: 
    		return(Brain.BWALK); 
    	case Brain.BWALK: 
    		return(Brain.BBACK); 
    	default: 
        	System.out.print("ERROR Act (actID)...");
        	return(Brain.AWALK);
    	}
    }
    	
    public void writeBus(int idAct, float apwr) {
        
		if (!Liberu.Sono) {
			outSignal[idAct].setActive(true);
			outSignal[idAct].setActPower(apwr);
	    	System.out.print("ActPower= "); // REMOVE
	    	System.out.println(apwr); // REMOVE
		}
    }
    
    public void run() {
    	int    	signalCount, // Count  Signals in bus
    			signalEmitter, // Saves last emitted
    			credit, // credit
    			actP; // actPower credit
        
        while (!Neuron.end && !bar.isBroken()) {
        	// Cerebellum Cut & Stay Learning - surviving learning 
    		try {
                bar.await(); 
            }
            catch (InterruptedException ex) { 
                return;
            }
            catch (BrokenBarrierException ex) { 
                return;
            }
            // ####################### Surviving Adaption #####################################
            if (neuro.standby && neuro.step < Emotions.ActRandom) {
            	signalCount = 0;
            	listen = Brain.BusInProSelf.iterator();
            	if (neuro.perception.size() == 0)
                    while (listen.hasNext()) {// read all the input bus
                    	signInput = listen.next();
                		neuro.addPerception(signInput.emitter, signInput.actPower, signInput.pleasure);
                        System.out.println(neuro.who); // REMOVE
        	        	System.out.print("Add dendrite Body fired="); // REMOVE
                        System.out.println(signInput.actPower); // REMOVE
                    	signalCount += 1;
                    }
            	else
                    while (listen.hasNext()) { // read all the input bus
                    	signInput = listen.next();
                        if (signInput.actPower >= Brain.MinSense)
                        	if (signalCount != neuro.who)
                        		neuro.getPerception(signalCount).setRecPower(0); // ActPower not used
                    	signalCount += 1;
                    }
            	
            	neuro.standby = false;
            }
            // ####################### Act ####################################################
        	neuro.clearSignals();
        	signalCount = 0;
    		signalEmitter = 0;
    		invert = false;
    		actP = 0;
        	listen = Brain.BusInAct.iterator();
            while (listen.hasNext()) { // read all the input bus
            	signInput = listen.next();
            	signalEmitter = signInput.emitter;
        		if (signInput.emitter < 0)
        			invert = true;
        		if (neuro.perception.size() > 0)
            		if (signInput.actPower > Brain.MinSense) {
        				neuro.getPerception(signalCount).setActive(true); // I'm interested process
                    	if (signalCount == neuro.who)
                    		actP = (int)signInput.actPower;
            		}
        		signalCount += 1;
        	}     // BUS empty
            
            // came from body - motivation
            credit = neuro.powerToAct();
            System.out.println(credit); // REMOVE
            if (neuro.fire) {
	        	System.out.print("NeuroAct Body fired............"); // REMOVE
                System.out.println(neuro.who); // REMOVE
                System.out.println(signalEmitter); // REMOVE
                if (Thumb)
                	credit = actP;
                if (invert)
                	writeBus(invertAct(neuro.who), credit);
                else
                    writeBus(neuro.who, credit);
    		}
        }  // End While
    }
}