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

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

public class Act implements Runnable {
    Neuron	        neuro; // Neur�nio
    CyclicBarrier   bar; // Barreira de passos
    Iterator<Signal> listen; // L� do bus
    Signal			signInput; // L� sinal
    Signal   		[]outSignal; // Sa�da de a��es
	boolean			invert;
    
    /** Creates a new instance of Act */
    public Act(CyclicBarrier barr, Neuron ne,
    		Signal []outSig) {

        bar       = barr;
    	neuro     = ne;
        outSignal = outSig;
    }
    
    public int invertActDor(int actID) {

    	switch (actID) { // Muda a a��o
    	case Brain.DRINK:
    		return(Brain.TURN_LEFT + 
    				(int)Math.rint(Math.random()));
    	case Brain.WALK: {
    		return(Brain.TURN_LEFT + 
    				(int)Math.rint(Math.random()));
    	}
    	case Brain.TURN_LEFT: 
    		return(Brain.TURN_RIGHT); 
    	case Brain.TURN_RIGHT: 
    		return(Brain.TURN_LEFT); 
    	case Brain.EAT: 
    		return(Brain.TURN_LEFT + 
    				(int)Math.rint(Math.random()));
    	default: 
        	System.out.print("ERROR Act (actID)...");
        	return(Brain.WALK);
    	}
    }
    	
    public void writeBus(int idAct, float apwr) {
        
		outSignal[idAct].setActive(true);
		outSignal[idAct].setActPower(apwr);
    	System.out.print("ActPower= "); // REMOVER
    	System.out.println(apwr); // REMOVER
    }
    
    public void run() {
    	int    	signalCount, // Conta os sinais do bus
    			signalEmitter, // Guarda o emissor
    			credit, // Cr�dito
    			actE, // Cr�dito
    			actR; // cr�dito actPower
        
        while (!Neuron.end && !bar.isBroken()) {
    		try {
                bar.await(); 
            }
            catch (InterruptedException ex) { 
                return;
            }
            catch (BrokenBarrierException ex) { 
                return;
            }
            if (neuro.standby && (neuro.step <
            		Emotions.ActRandom || Cortex.nSpeaks
            		< Emotions.SpeakRandom)) {
            	// Aprendisagem por subreviv�ncia
            	signalCount = 0;
            	listen = Brain.BusInProSelf.iterator();
            	if (neuro.perception.size() == 0)
                    while (listen.hasNext()) {
                    	signInput = listen.next();
                		neuro.addPerception(
                				signInput.emitter,
                				signInput.actPower,
                				signInput.pleasure);
                        System.out.println(
                        		neuro.who); // REMOVER
        	        	System.out.print(
        	        		"Add dendrite Body fired=");
        	        	// REMOVER
                        System.out.println(
                        		signInput.actPower);
                        // REMOVER
                    	signalCount += 1;
                    }
            	else
                    while (listen.hasNext()) {
                    	signInput = listen.next();
                        if (signInput.actPower >=
                        		Brain.MinSense)
                        	if (signalCount != neuro.who)
                        		neuro.getPerception(
                          		  signalCount).setRecPower(
                              				  0);
                    	signalCount += 1;
                    }
            	
            	neuro.standby = false;
            }
            // ####################### Act ################
        	neuro.clearSignals();
        	signalCount = 0;
    		signalEmitter = 0;
    		invert = false;
    		actE = 0;
    		actR = 0;
        	listen = Brain.BusInAct.iterator();
            while (listen.hasNext()) {
            	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);
                    	if (signalCount == neuro.who) {
                    		actR = (int)signInput.actPower;
                    		actE = (int)signInput.pleasure;
                    	}
            		}
        		signalCount += 1;
        	} // Bus vazio
            
            neuro.powerToAct();
            if (neuro.fire) {
	        	System.out.print(
	        			"NeuroAct Body fired............");
	        	// REMOVER
                System.out.println(neuro.who);
                // REMOVER
                System.out.println(signalEmitter);
                // REMOVER
                if (Cortex.Thumb)
                	credit = actE;
                else
                	credit = actR;
                System.out.println(credit); // REMOVER
                if (invert)
                	writeBus(invertActDor(neuro.who), credit);
                else
                    writeBus(neuro.who, credit);
    		}
        } // Fim ciclo While
    }
}