/*
 * 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; // level of beautiful
	public static boolean       []NewSense; // true if a new perception for a sense
    Neuron          []time; // Neuron by TRAIL
    CyclicBarrier   bar; // Step barrier
    int				i; // Indexes to For cycles
    public static int 		QualityMax, // higher pleasure
    						QualityWho, // who of the best quality
    						RecentMost, // most recent in time
    						threshold;
    int				activeCredit;
    
    /** Creates a new instance of RunNeuronPast */
    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;
    	QualityMax = 0;
    	RecentMost = 0;
		threshold = 0;
    }
    
    public void keepSense(int sense, ConcurrentLinkedQueue<Signal> busReal) {
    	Iterator<Signal> listen; // Listen Signal from bus
    	Signal			signInput; // Read input Signal

    	time[sense].clearPerceptions();
    	time[0].clearLearn();
    	time[sense].quality = 0;
    	time[sense].setHome(false);
    	listen = busReal.iterator();
    	while (listen.hasNext()) { // read all the input bus
        	signInput = listen.next();
        	time[sense].addPerception(signInput.emitter, signInput.actPower, signInput.pleasure);
        	time[sense].addQuality(signInput.pleasure);
    	}
    	time[Brain.ProSelf].addFinalQuality(time[sense].quality);
	}

    public void keepProSelf(int sense, ConcurrentLinkedQueue<Signal> busReal) {
    	Iterator<Signal> listen; // Listen Signal from bus
    	Signal			signInput; // Read input Signal

    	listen = busReal.iterator();
    	while (listen.hasNext()) { // read all the input bus
        	signInput = listen.next();
        	time[sense].addPerception(signInput.emitter, signInput.actPower, signInput.pleasure);
    	}
	}

    private int remember(int sense, ConcurrentLinkedQueue<Signal> busReal) {
        Iterator<Signal> listen; // Listen Signal from bus
        Signal			signInput; // Read input Signal
        int				i, active; // Indexes to For cycles
        
        time[sense].clearSignals();
    	i=0;
    	listen = busReal.iterator(); // READ BUS
		while (listen.hasNext()) { // read all the input bus
			signInput = listen.next();
    		if (time[sense].perception.size() > i) {
        		if (signInput.actPower > Brain.MinSense)
    				time[sense].getPerception(i).setActive(true); // I'm interested process
    			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].standby) { // Present neuron - see different process - Attention
           		time[0].standby = false;
           		keepProSelf(Brain.ProSelf, Brain.BusInProSelf); // 5 added
              	System.out.println(time[Brain.ProSelf].finalQuality); // REMOVE
        		} // End IF
        	if (time[0].pointer == time[0].who) { // Present neuron - see different process - Attention
           		time[0].standby = true;
            	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); // 5 is added later
        		} // End IF
        	// All neurons (-Present-Future) - remembering process - OR function
        	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) {
        		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 &&
              		  (time[0].who >= RecentMost &&
              		  		(RecentMost > time[0].pointer ||
              		  			time[0].who <= time[0].pointer) ||
              		  	time[0].who < RecentMost &&
              		  RecentMost > time[0].pointer &&
              		  time[0].who <= time[0].pointer))
                	RecentMost = time[0].who;
          		if (time[Brain.ProSelf].finalQuality >= QualityMax) {
                  	QualityMax = time[Brain.ProSelf].finalQuality;
                  	QualityWho = time[0].who;
          		}
        	}
    	} // End While
    }
}