/*
 * Remember.java
 *
 * Created on 3 of February 2011, 15:07
 */

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

public class Remember implements Runnable {

	public static int			Lovely;
								// N�mero de disparos
	public static boolean       []NewSense;
								// Se novidade
    Neuron          []time; // Rede por sentiso
    CyclicBarrier   bar; // Barreira de passos
    int				i; // Indexe
    public static int 		RecentMost, // Lembrado recente
    						threshold; // Limiar
    int				activeCredit;
    
    /** Creates a new instance of Remember */
    public Remember(CyclicBarrier barr,
    						 Neuron []tneurons,
                             Emotions d) {
        
    	bar         = barr;
        time        = tneurons;
        NewSense    = new boolean[Brain.SENSES];
        for (i=0; i<Brain.SENSES; i++)
        	NewSense[i] = true;
        Lovely      = 0;
    	RecentMost = 0;
		threshold = 0;
    }
    
    public void keepSense(int sense,
    		ConcurrentLinkedQueue<Signal> busReal) {
    	Iterator<Signal> listen; // Ouve o bus
    	Signal			signInput; // Guarda entrada

    	time[sense].clearPerceptions();
    	time[sense].quality = 0;
    	listen = busReal.iterator();
    	while (listen.hasNext()) { // L� todo o bus
        	signInput = listen.next();
        	if (Cortex.Thumb)
        		signInput.pleasure = - signInput.pleasure;
        	time[sense].addPerception(signInput.emitter,
        			signInput.actPower,
        			signInput.pleasure);
        	time[sense].addQuality(signInput.pleasure);
    	}
    	time[Brain.ProSelf].addFinalQuality(
    			time[sense].quality);
	}

    private int remember(int sense,
    		ConcurrentLinkedQueue<Signal> busReal) {
        Iterator<Signal> listen; // Ouve o bus
        Signal			signInput; // L� bus
        int				i, active; // Indexe
        
        time[sense].clearSignals();
    	i=0;
    	listen = busReal.iterator(); // L� o primeiro
		while (listen.hasNext()) { // L� todo o bus
			signInput = listen.next();
    		if (time[sense].perception.size() > i) {
        		if (signInput.actPower > Brain.MinSense)
    				time[sense].getPerception(i).
    				setActive(true);
    			time[sense].getPerception(i).
    			setActPower(signInput.actPower);
    		}
			i += 1;
		}
		active = (int)time[sense].powerOfFire(sense);
		if (time[sense].fire) {
			NewSense[sense] = false;
			Lovely += 1;
	        Interface.Lovely = Lovely;
		}
		return active;
	}
  
    public void run() {
        
        while (!Neuron.end && !bar.isBroken()) {
    		try {
    			bar.await();
    			}
    		catch (InterruptedException ex) { 
    			return;
    			}
    		catch (BrokenBarrierException ex) { 
    			return;
    			}
        	if (time[0].pointer == time[0].who) {
        		// Neur�nio do presente
            	time[Brain.ProSelf].finalQuality = 0;
        		keepSense(Brain.Taste, Brain.BusInTaste);
        		keepSense(Brain.Vision, Brain.BusInVision);
        		keepSense(Brain.Tact, Brain.BusInTact);
        		keepSense(Brain.Sound, Brain.BusInSound);
        		keepSense(Brain.Smell, Brain.BusInSmell);
           		keepSense(Brain.ProSelf,
           				Brain.BusInProSelf);
              	System.out.println(
              			time[Brain.ProSelf].finalQuality);
              	// REMOVER
            	if (Emotions.ActualPain) {
            		// Pr�vio neur�nio se em Dor
                	RecentMost = time[0].who;
            	}
    		} // Fim do If
        	// Todos os neur�nios do passado
        	if ((time[0].pointer-3 != time[0].who &&
        		time[0].pointer-2 != time[0].who && 
        		time[0].pointer-1 != time[0].who &&
        		time[0].pointer   != time[0].who) &&
        			!Emotions.ActualPain) {
        		activeCredit = 0;
        		activeCredit += remember(Brain.Taste,
        				Brain.BusInTaste);
        		activeCredit += remember(Brain.Vision,
        				Brain.BusInVision);
        		activeCredit += remember(Brain.Tact,
        				Brain.BusInTact);
        		activeCredit += remember(Brain.Sound,
        				Brain.BusInSound);
        		activeCredit += remember(Brain.Smell,
        				Brain.BusInSmell);
           		activeCredit += remember(Brain.ProSelf,
           				Brain.BusInProSelf);
                if (activeCredit > threshold) {
                	RecentMost = time[0].who;
                	threshold = activeCredit;
                }
                else
                    if (activeCredit == threshold)
        			    if (time[0].who >= RecentMost &&
    		    		(RecentMost > time[0].pointer ||
    		    				time[0].who <=
    		    				time[0].pointer))
        			    	RecentMost = time[0].who;
        	    		else
        					if (RecentMost >
    		    		time[0].pointer && time[0].who <=
    		    		time[0].pointer)
        						RecentMost = time[0].who;
        	}
    	} // Fim ciclo While
    }
}