/*
 * PlayLiberu.java
 *
 * Created on 1 of February 2006, 2:06
 */

/**
 *
 * @author Eng. Paulo Roque Silva
 */
import icommand.nxt.SensorPort;
import icommand.nxt.TouchSensor;
import icommand.nxt.LightSensor;
import icommand.nxt.UltrasonicSensor;
import icommand.nxt.SoundSensor;

import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.BrokenBarrierException;
import icommand.nxt.comm.NXTCommand;
import javax.swing.*;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.UnsupportedAudioFileException;
import javax.sound.sampled.Port;
import javax.sound.sampled.TargetDataLine;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioFormat.Encoding;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.Clip;
import javax.sound.sampled.AudioInputStream;
import java.awt.Component;
import java.awt.*;
import java.io.*;
//import javax.media.*;
//import javax.media.format.*;
//import javax.media.protocol.*;
//import javax.media.control.*;
import java.util.Vector;
//import javax.media.util.*;
import java.awt.image.*;

public class PlayLiberu extends Thread {
// LIBERU BODY CONSTANTS - in the future will be analog Senses (6 senses) with more signals (Sherin)
	TouchSensor		bt;			          // Button of NXT
	LightSensor		lgt;		          // Light Sensor of NXT
	UltrasonicSensor us;	              // Ultra Sonic Sensor of NXT
	SoundSensor     sd; 	              // Sound Sensor of NXT
	static final int TimeSlize = 2000;    // Time in milliseconds of every step of the robot
    static final int TimeWait  = 64;      // Time in milliseconds to the nodes wait for all listen the bus
    static final int Power = 150;         // intensity of a Standard sense signal - to remove with analog
    final int		SAMPLE_RATE = 16000;  // input sample rate per second
    static final int BANDS = 7;           // # bands frequency
    Liberu          liberu;               // Liberu with a body and a brain
    Signal          []action;             // Action of the robot
    int             senteTaste[];         // Senses of the robot's body Taste [sherin]
    int             senteSmell[];         // Senses of the robot's body Taste [sherin]
    int             senteVision[];        // Senses of the robot's body Taste [sherin]
    int             senteTact[];          // Senses of the robot's body Taste [sherin]
    int             senteSound[];         // Senses of the robot's body Taste [sherin]
    int             senteProSelf[];        // Senses of the robot's body Taste [sherin]

    CyclicBarrier   stepBarrierTaste;     // Establish a barrier to the past steps
    CyclicBarrier   stepBarrier2Taste;    // Establish a barrier to the past steps
    CyclicBarrier   stepBarrierSmell;     // Establish a barrier to the past steps
    CyclicBarrier   stepBarrier2Smell;    // Establish a barrier to the past steps
    CyclicBarrier   stepBarrierVision;    // Establish a barrier to the past steps
    CyclicBarrier   stepBarrier2Vision;   // Establish a barrier to the past steps
    CyclicBarrier   stepBarrierTact;      // Establish a barrier to the past steps
    CyclicBarrier   stepBarrier2Tact;     // Establish a barrier to the past steps
    CyclicBarrier   stepBarrierSound;     // Establish a barrier to the past steps
    CyclicBarrier   stepBarrier2Sound;    // Establish a barrier to the past steps
    CyclicBarrier   stepBarrierProSelf;   // Establish a barrier to the past steps
    CyclicBarrier   stepBarrier2ProSelf;  // Establish a barrier to the past steps
    CyclicBarrier   stepId;               // Establish a barrier to the Ids Modules
    CyclicBarrier   stepId2;              // Establish a barrier to the Ids Modules
    CyclicBarrier   stepBarrierAct;       // Establish a barrier to the act steps
    CyclicBarrier   stepBarrierREU;       // Establish a barrier to the RunEmotionalUnit steps
    CyclicBarrier   stepBarrierTime;      // Establish a barrier to the Time Present
    
// SIMULATED CONSTANTS
    final int       StartLocal  = 7;      // Local where the robot starts (1 to 9)
    World           habitat;              // habitat of the robot
    Interface       screen;
    int             local,                // Actual robot's place (1 to 9 - DON'T CHANGE)
    				orient,               // Orientation of the robot movement
    				wallOrLocal,          // Local or World.WALL (0 to 9)
    				tact,                 // WALL or not
    				nutrition,            // Food or Water in the local
    				vision,               // Local forward
    				nStep,                // Step movement of the robot
    				i;					  // index
    boolean         moreWork,             // false if the simulation ended
    				aStep,         		  // false in continuous running
    				oneStep;		      // true for one step execution
    TargetDataLine  line;                 // microfone
    AudioFormat		format;               // audio In format
    int				numBytesRead;		  // # input bytes
    int				numBytesReadTotal;	  // # total input bytes
    byte[]          data;                 // input bytes
    DataLine.Info   info,
                    info2,
    				info3,
    				info4;
    AudioInputStream stream,			  // clip 1
					stream2,			  // clip 2
					stream3;			  // clip 3
    Clip			clip,                 // som to playback
    				clip2,
    				clip3;
//    CaptureDeviceInfo cam;                // webcam
//    MediaLocator    locator;              // to webcam
//    Player          player;               // webcam
    Component       videoScreen;
//    Vector<CaptureDeviceInfo>  list;
    JFrame          jfrm;
//    FormatControl   formatControl;
//    DataSource      ds;
//    Buffer          buf = null;
    Image           img = null;
//    BufferToImage   btoi = null;
//    FrameGrabbingControl fgc;
    int             pix[];
    BufferedImage   bufferedImage;
    int				clr, red, green, blue;
    PixelGrabber    pg;
    
    /** Creates a new instance of PlayLiberu */
    public PlayLiberu(Interface panelG, JTextField txt) {
        
        System.out.println("SimLiberu...by Eng. Paulo Roque Silva 2004-2012");
        screen 		= panelG;
        liberu      = new Liberu(screen, txt);
        action      = new Signal[Liberu.MOVES];
        for (int i=0; i<action.length; i++)
            action[i] = new Signal(i, Power);
        senteTaste  = new int[Liberu.NanalogTaste];
        senteSmell  = new int[Liberu.NanalogSmell];
        senteVision = new int[Liberu.NanalogVision];
        senteTact   = new int[Liberu.NanalogTact];
        senteSound  = new int[Liberu.NanalogSound];
        senteProSelf= new int[Liberu.NanalogProSelf];
        habitat     = new World();
        local       = StartLocal;
        orient      = World.NORTH;
        tact        = Liberu.NO_TACT;
        nutrition   = habitat.element(local);
        vision      = habitat.vision(local, orient);
        nStep       = 0;
        moreWork 	= true;
        aStep 		= true;
        oneStep 	= true;
		pix         = new int[160*120];
    }
    
    public void step(boolean stepByStep) {
        
        aStep = stepByStep;
        oneStep = aStep;
    }
    
    public void display(boolean ex) {
    	int i; // index
    	
        screen.saveValue(0, local);				// value 0 Smell
        screen.saveValue(1, tact);              // value 1
        screen.saveValue(2, nutrition);         // value 2 Taste
        screen.saveValue(3, nStep);             // value 3
        screen.saveValue(4, orient);            // value 4
        screen.saveValue(5, vision);            // value 5
        for (i=0; i<Liberu.ACTMOVES; i++)     // CUIDADO deve ser 5
            if (action[i].active)
            	screen.saveValue(8+i, 1);       // values 8-12
            else
            	screen.saveValue(8+i, 0);       // values 8-12
                                                // saveValue limit set to 40
        for (i=Liberu.ACTMOVES; i<action.length; i++)     // CUIDADO deve ser 5
            if (action[i].active)
            	screen.saveValue(23+i, 1);       // values 23-28
            else
            	screen.saveValue(23+i, 0);       // values 23-28
                                                // saveValue limit set to 40
        
        screen.displayRobot(liberu, ex);
        
        screen.repaint();                       //0, 40, 1200, 800);
    }

/*    private void ve() {
    	int n;  // index

    	try {
        	buf = fgc.grabFrame();
        	// Convert it to an image
        	btoi = new BufferToImage((VideoFormat)buf.getFormat());
        	img = btoi.createImage(buf);
        	if (img == null)
        			System.out.println("IMAGEM NULA:::::::::::");
        	
        	pg = new PixelGrabber(img,0,0,160,120,pix,0,160);
        	pg.grabPixels();
        	for (n=0; n<Liberu.NanalogVision/3; n++) {
        		switch (n) {
        		case 0:
            		System.out.println(pix[80*160+60]);
                	clr = pix[80*160+60]; //Get all pixels
                	break;
        		case 1:
            		System.out.println(pix[80*160+59]);
                	clr = pix[80*160+59]; //Get all pixels
                	break;
        		case 2:
            		System.out.println(pix[81*160+60]);
                	clr = pix[81*160+60]; //Get all pixels
                	break;
        		case 3:
            		System.out.println(pix[80*160+61]);
                	clr = pix[80*160+61]; //Get all pixels
                	break;
        		case 4:
            		System.out.println(pix[79*160+60]);
                	clr = pix[79*160+60]; //Get all pixels
                	break;
        		}
            	red = (clr & 0x00ff0000) >> 16;
            	green = (clr & 0x0000ff00) >> 8;
            	blue = clr & 0x000000ff;
//        		System.out.println("Red color value = " + red);
//        		System.out.println("Green color value = " + green);
//        		System.out.println("Blue color value = " + blue);
             	senteVision[n*3+0] = red;	     // Sense of vision
             	senteVision[n*3+1] = green;	     // Sense of vision
             	senteVision[n*3+2] = blue;	     // Sense of vision
    	        screen.saveValue(50+n*3, red);             // value Vision
    	        screen.saveValue(50+n*3+1, green);         // value Vision
    	        screen.saveValue(50+n*3+2, blue);          // value Vision
        	}
    	}
    	catch (Exception e) {
    		e.printStackTrace();
    	}
    }
*/    
    private void ouve() {
    	int n, m, // index
    		derivada,	   // sound difference
    		readBefore,    // sound
    		bandBefore,    // band before
    		totalHits;     // total Hits
    	
    	numBytesReadTotal = 0;
    	line.flush();
    	readBefore = 0;
    	System.out.println("Ouvindo...");
    	while (numBytesReadTotal < SAMPLE_RATE * 2) {
    		numBytesRead = line.read(data, 0, data.length);
    		numBytesReadTotal += numBytesRead;
    		for (n=0; n < numBytesRead; n++) {
    			derivada = Math.abs(data[n] - readBefore);
    			bandBefore = 0;
    			for (m=0; m < BANDS; m++) {
    				if (derivada >= bandBefore && derivada < (int)(32000 / Math.pow(2, BANDS-1-m)/Liberu.MaxInSense)) {
    					senteSound[m] += 1;
    					bandBefore = (int)(32000 / Math.pow(2, BANDS-1-m)/Liberu.MaxInSense);
    				}
    			}
    			readBefore = data[n];
    		}
    	}
		System.out.println("Surdo...");
		totalHits = 0;
		for (m=0; m < BANDS; m++)
			totalHits += senteSound[m];
		if (totalHits == 0) totalHits = 1;
		for (m=0; m < BANDS; m++)
			senteSound[m] = (int)(senteSound[m] * Liberu.MaxInSense / totalHits);
		for (m=0; m < BANDS; m++)
	        screen.saveValue(36+m, senteSound[m]);             // value 36+BANDS
    }
    
    private void updateSenses() {     // C.Elegants Commands
    	int n, m; // index
    	
    	for (m=0; m < senteTaste.length; m++)
    		senteTaste[m] = 0;
    	for (m=0; m < senteSmell.length; m++)
    		senteSmell[m] = 0;
    	for (m=0; m < senteVision.length; m++)
    		senteVision[m] = 0;
    	for (m=0; m < senteTact.length; m++)
    		senteTact[m] = 0;
    	for (m=0; m < senteSound.length; m++)
    		senteSound[m] = 0;
    	for (m=0; m < senteProSelf.length; m++)
    		senteProSelf[m] = 0;

//    	ouve();

//    	ve();
    	
    	if (action[Liberu.TURN_RIGHT].active && action[Liberu.TURN_LEFT].active)
    	 	   ;
    	 	else {
    	    	if (action[Liberu.TURN_LEFT].active)
    	            orient = habitat.orientate(orient, Liberu.TURN_LEFT);
    	        if (action[Liberu.TURN_RIGHT].active)
    	            orient = habitat.orientate(orient, Liberu.TURN_RIGHT);
    	 	}
        
        tact = Liberu.NO_TACT;
        if (action[Liberu.WALK].active) {
            wallOrLocal = habitat.move(local, orient);
            if (wallOrLocal != World.WALL)
                local = wallOrLocal;         	 // New local
            else {
                tact = Liberu.TACT;              // Hit the wall
             	senteTact[0] = Power;				// Sense of tact
        		if (liberu.past.time[0][0].step > RunEmotionalUnit.ActRandom)
                    liberu.feelPAIN();
            }
        }
        nutrition = habitat.element(local);
        vision = habitat.vision(local, orient);
        
        senteTaste[nutrition-1] = Power;	// Sense of taste
     	senteSmell[local-1] = Power;		// Sense of smell or sound

     	senteVision[vision-1] = Power;		// Sense of vision
		if (action[Liberu.DRINK].active)
			senteProSelf[Liberu.DRINK] = Power;
		if (action[Liberu.EAT].active)
			senteProSelf[Liberu.EAT] = Power;
		if (action[Liberu.WALK].active)
			senteProSelf[Liberu.WALK] = Power;
		if (action[Liberu.TURN_LEFT].active)
			senteProSelf[Liberu.TURN_LEFT] = Power;
		if (action[Liberu.TURN_RIGHT].active)
			senteProSelf[Liberu.TURN_RIGHT] = Power;
		if (action[Liberu.MDrink].active)
			senteProSelf[Liberu.MDrink] = Power;
		if (action[Liberu.MEat].active)
			senteProSelf[Liberu.MEat] = Power;
    }
    
    private void updateSensesNXT() {     // NXT Commands
    	int n, m; // index
    	
    	for (m=0; m < senteTaste.length; m++)
    		senteTaste[m] = 0;
    	for (m=0; m < senteSmell.length; m++)
    		senteSmell[m] = 0;
    	for (m=0; m < senteVision.length; m++)
    		senteVision[m] = 0;
    	for (m=0; m < senteTact.length; m++)
    		senteTact[m] = 0;
    	for (m=0; m < senteSound.length; m++)
    		senteSound[m] = 0;
    	for (m=0; m < senteProSelf.length; m++)
    		senteProSelf[m] = 0;

    	ouve();
    	
//    	ve();
    	
    	tact = Liberu.NO_TACT;               // BUTTON - TACT - PAIN
    	if (bt.isPressed()) {
            tact = Liberu.TACT;
         	senteTact[0] = Power;			 // Sense of tact
    		if (liberu.past.time[0][0].step > RunEmotionalUnit.ActRandom)
            	liberu.feelPAIN();
    	}
    	
    	nutrition = lgt.getLightPercent();
//    	local = sd.getdB();
    	vision = us.getDistance();
    	local = vision;
        senteTaste[0] = nutrition;	 // Sense light
     	senteSmell[0] = vision;         // Sense distance
//     	senteVision[0] = vision;	     // Sense of vision
		if (action[Liberu.DRINK].active)
			senteProSelf[Liberu.DRINK] = Power;
		if (action[Liberu.EAT].active)
			senteProSelf[Liberu.EAT] = Power;
		if (action[Liberu.WALK].active)
			senteProSelf[Liberu.WALK] = Power;
		if (action[Liberu.TURN_LEFT].active)
			senteProSelf[Liberu.TURN_LEFT] = Power;
		if (action[Liberu.TURN_RIGHT].active)
			senteProSelf[Liberu.TURN_RIGHT] = Power;
		if (action[Liberu.MDrink].active)
			senteProSelf[Liberu.MDrink] = Power;
		if (action[Liberu.MEat].active)
			senteProSelf[Liberu.MEat] = Power;
    }
    
    public void runStepLiberu() {
    	int i;    // index
        
        // starts the cycle
        nStep = liberu.addStep();
        System.out.print("nPasso = ");       // a retirar
        System.out.println(nStep);           // a retirar
        
// BEGINING Slide LIVING
        liberu.clearBuses();
        
        liberu.proSelf(senteProSelf, senteTaste, Power);// Liberu Elegans update proprioception
//        liberu.proSelfNXT(senteProSelf, lgt, Power);	  // Liberu NXT update proprioception
        liberu.motivation(senteProSelf, Power);	          // Liberu motivation
//        liberu.motivationNXT(senteProSelf, lgt, Power);          // Liberu NXT motivation
        display(true);									  // shows in screen
        liberu.feelTaste(senteTaste);		     		  // Liberu feels
        liberu.feelSmell(senteSmell);		     		  // Liberu feels
        liberu.feelVision(senteVision);		     		  // Liberu feels
        liberu.feelTact(senteTact); 		     		  // Liberu feels
        liberu.feelSound(senteSound);		     		  // Liberu feels
        liberu.feelProSelf(senteProSelf);	     		  // Liberu feels
        // End Real Time

        for (i=0; i<action.length; i++)		  // reset actions
            action[i].setActive(false);

        // Past Nodes in action - STEP 1 ************************************************
        try {
            stepBarrierTaste.await();              // synchronize nodes with the user - Start Past nodes 
            while (stepBarrier2Taste.getNumberWaiting() < stepBarrier2Taste.getParties() - 1)
                sleep(TimeWait);
            stepBarrierSmell.await();              // synchronize nodes with the user - Start Past nodes 
            while (stepBarrier2Smell.getNumberWaiting() < stepBarrier2Smell.getParties() - 1)
                sleep(TimeWait);
            stepBarrierVision.await();              // synchronize nodes with the user - Start Past nodes 
            while (stepBarrier2Vision.getNumberWaiting() < stepBarrier2Vision.getParties() - 1)
                sleep(TimeWait);
            stepBarrierTact.await();              // synchronize nodes with the user - Start Past nodes 
            while (stepBarrier2Tact.getNumberWaiting() < stepBarrier2Tact.getParties() - 1)
                sleep(TimeWait);
            stepBarrierSound.await();              // synchronize nodes with the user - Start Past nodes 
            while (stepBarrier2Sound.getNumberWaiting() < stepBarrier2Sound.getParties() - 1)
                sleep(TimeWait);
            stepBarrierProSelf.await();              // synchronize nodes with the user - Start Past nodes 
            while (stepBarrier2ProSelf.getNumberWaiting() < stepBarrier2ProSelf.getParties() - 1)
                sleep(TimeWait);
        }
        catch (InterruptedException ex) { 
            return;
        }
        catch (BrokenBarrierException ex) { 
            return;
            }
		System.out.println("Past Nodes STEP 1...");           // a retirar
        // ID in action - STEP 1 ********************************************************
        try {
            stepId.await();              // synchronize nodes with the user - Start Id step 1 
            while (stepId2.getNumberWaiting() < stepId2.getParties() - 1)
                sleep(TimeWait);
        }
        catch (InterruptedException ex) { 
            return;
        }
        catch (BrokenBarrierException ex) { 
            return;
            }
		System.out.println("ID STEP 1...");           // a retirar
        // Past Nodes in action - STEP 2 ************************************************
        try {
            stepBarrier2Taste.await();              // synchronize nodes with the user - Start Past nodes 
            while (stepBarrierTaste.getNumberWaiting() < stepBarrierTaste.getParties() - 1)
                sleep(TimeWait);
            stepBarrier2Smell.await();              // synchronize nodes with the user - Start Past nodes 
            while (stepBarrierSmell.getNumberWaiting() < stepBarrierSmell.getParties() - 1)
                sleep(TimeWait);
            stepBarrier2Vision.await();              // synchronize nodes with the user - Start Past nodes 
            while (stepBarrierVision.getNumberWaiting() < stepBarrierVision.getParties() - 1)
                sleep(TimeWait);
            stepBarrier2Tact.await();              // synchronize nodes with the user - Start Past nodes 
            while (stepBarrierTact.getNumberWaiting() < stepBarrierTact.getParties() - 1)
                sleep(TimeWait);
            stepBarrier2Sound.await();              // synchronize nodes with the user - Start Past nodes 
            while (stepBarrierSound.getNumberWaiting() < stepBarrierSound.getParties() - 1)
                sleep(TimeWait);
            stepBarrier2ProSelf.await();              // synchronize nodes with the user - Start Past nodes 
            while (stepBarrierProSelf.getNumberWaiting() < stepBarrierProSelf.getParties() - 1)
                sleep(TimeWait);
        }
        catch (InterruptedException ex) { 
            return;
        }
        catch (BrokenBarrierException ex) { 
            return;
            }
		System.out.println("Past Nodes STEP 2...");           // a retirar
        // ID in action - STEP 2 ********************************************************
        try {
            stepId2.await();              // synchronize nodes with the user - Start PastTime nodes 
            while (stepId.getNumberWaiting() < stepId.getParties() - 1)
                sleep(TimeWait);
        }
        catch (InterruptedException ex) { 
            return;
        }
        catch (BrokenBarrierException ex) { 
            return;
            }
		System.out.println("ID STEP 2...");           // a retirar

		liberu.clearBusTimeOut();

        // Past TIME Nodes in action         *******************************************
        try {
            stepBarrierTime.await();              // synchronize nodes with the user - Start PastTime nodes 
            while (stepBarrierTime.getNumberWaiting() < stepBarrierTime.getParties() - 1)
                sleep(TimeWait);
        }
        catch (InterruptedException ex) { 
            return;
        }
        catch (BrokenBarrierException ex) { 
            return;
            }
		System.out.println("Past TIME...");           // a retirar
        // REU in action ****************************************************************
        try {
            stepBarrierREU.await();           // Start REU Thread 
            while (stepBarrierREU.getNumberWaiting() < stepBarrierREU.getParties() - 1)
                sleep(TimeWait);
        }
        catch (InterruptedException ex) { 
            return;
        }
        catch (BrokenBarrierException ex) { 
            return;
            }
		System.out.println("REU acting...");           // a retirar
        // Acting Nodes in action *******************************************************
        try {
            stepBarrierAct.await();           // Start Act Nodes 
            while (stepBarrierAct.getNumberWaiting() < stepBarrierAct.getParties() - 1)
                sleep(TimeWait);
        }
        catch (InterruptedException ex) { 
            return;
        }
        catch (BrokenBarrierException ex) { 
            return;
            }
		System.out.println("Acting Nodes...");           // a retirar
        
        // Real Time
        liberu.act(action);				  // Liberu act
        display(true);					  // shows in screen
        updateSenses();					  // Liberu interact with world - Elegans Body
//        updateSensesNXT();			  // Liberu interact with world - NXT MindStorms LEGO Body
// ENDING OF Slice LIVING
    }

    public void continueRun() {
        
        System.out.println("Continue...");
        aStep = false;
    }
    
    public void pause() {
        
        System.out.println("Pause...");
        aStep = true;
    }
    
    public void oneStep() {
        
        System.out.println("One Step...");
        // aStep = true;   If we wish no o press <Pause> to be step by step
        oneStep = true;
    }
    
    public void setToEnd() {
        
    	stepBarrierTaste.reset();
    	stepBarrier2Taste.reset();
    	stepBarrierSmell.reset();
    	stepBarrier2Smell.reset();
    	stepBarrierVision.reset();
    	stepBarrier2Vision.reset();
    	stepBarrierTact.reset();
    	stepBarrier2Tact.reset();
    	stepBarrierSound.reset();
    	stepBarrier2Sound.reset();
    	stepBarrierProSelf.reset();
    	stepBarrier2ProSelf.reset();
    	stepId.reset();
    	stepId2.reset();
    	stepBarrierAct.reset();
    	stepBarrierREU.reset();
    	stepBarrierTime.reset();
    }
    
    public void run() {
        
/*    	try {
//    		cam = CaptureDeviceManager.getDevice("vfw://0");
    		list = CaptureDeviceManager.getDeviceList(null);
    		System.out.println(list);
    		for (CaptureDeviceInfo temp : list) {
    			if (temp.getName().startsWith("vfw:")) {
    				System.out.println("Found : " + temp.getName().substring(4));
    				cam = temp;
    				System.out.println("Selected : " + cam.getName().substring(4));
    				break;
    			}
    		}
//    		locator =  new MediaLocator("vfw://0");  cam.getLocator();				// NXT command
    		if (locator != null) {
    			player = Manager.createRealizedPlayer(locator);
    			if (player != null) {
    				player.start();
    				Thread.sleep(2500);
    				
    				fgc = (FrameGrabbingControl)player.getControl("javax.media.control.FrameGrabbingControl");
    				ve();
    				jfrm = new JFrame();
    				jfrm.setTitle("Liberu vision...");
    				jfrm.setLayout(new BorderLayout());
    				jfrm.add(player.getVisualComponent(), BorderLayout.SOUTH);
    				jfrm.pack();
    				jfrm.setVisible(true);
    			}
    		}
*///    		deviceList = CaptureDeviceManager.getDeviceList(new YUVFormat());
//    		device = (CaptureDeviceInfo) deviceList.firstElement();

//    		ml = new MediaLocator("vfw://0"); /* device.getLocator(); */
//    		ds = Manager.createDataSource(ml);
//            /* Create & start my player */ 
//            p = Manager.createRealizedPlayer(ds);  
//            p.start();  
//	        Thread.currentThread().sleep(1000);  
//	         /* code for creating a JFrame and adding the visual component to it */ 
//	        jfrm = new JFrame("Testing Webcam");  
//            jfrm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);  
//            if(p.getVisualComponent()!=null)jfrm.getContentPane().add(p.getVisualComponent());  
//            if(p.getControlPanelComponent()!=null)jfrm.getContentPane().add(p.getControlPanelComponent(),
//           		                                                                   BorderLayout.SOUTH);  
//            jfrm.pack();  
//            jfrm.setLocationRelativeTo(null);  
//            jfrm.setVisible(true);  
//            jfrm.setSize(320,240);  

/*       	}
    	catch (Exception e) {
    		e.printStackTrace();
    	}
//	catch (CannotRealizeException e) {
//		System.out.println(e);
//	}
//    	catch (NoPlayerException e) {
//    		System.out.println(e);
//    	}
//    	catch (IOException e) {
//    		System.out.println(e);
//    	}
//    	catch (NoDataSourceException e) {
//    		System.out.println(e);
//    	}
*/    	format = new AudioFormat(Encoding.PCM_SIGNED, SAMPLE_RATE, 8, 1, 1, SAMPLE_RATE, true);
    	info = new DataLine.Info(TargetDataLine.class, format);
    	if (AudioSystem.isLineSupported(Port.Info.MICROPHONE)) {
    		try {
    			line = (TargetDataLine)AudioSystem.getLine(info);
    	    	line.open(format);
    	    	data = new byte[line.getBufferSize()/5];
    	    	line.start();
    			System.out.print("microfone...");
    			System.out.println(line.getBufferSize());
    		}
    		catch (LineUnavailableException ex) {
    			System.out.println("Sem microfone...");
    		}
    	}
    	else
			System.out.println("Sem microfone......");
    	if (AudioSystem.isLineSupported(Port.Info.SPEAKER)) {
        	try {
            	stream = AudioSystem.getAudioInputStream(new File("audiofile1nxt.wav"));
            	stream2 = AudioSystem.getAudioInputStream(new File("audiofile2nxt.wav"));
            	stream3 = AudioSystem.getAudioInputStream(new File("audiofile3nxt.wav"));
        	}
        	catch (IOException e) {
                e.printStackTrace();
            }
           	catch (UnsupportedAudioFileException e) {
                e.printStackTrace();
            }
            AudioFormat format = stream.getFormat();
            info2 = new DataLine.Info(Clip.class, stream.getFormat(),
                    ((int) stream.getFrameLength() * format.getFrameSize()));
            info3 = new DataLine.Info(Clip.class, stream2.getFormat(),
                    ((int) stream.getFrameLength() * format.getFrameSize()));
            info4 = new DataLine.Info(Clip.class, stream3.getFormat(),
                    ((int) stream.getFrameLength() * format.getFrameSize()));
    		try {
                clip = (Clip) AudioSystem.getLine(info2);
                clip.open(stream);
                clip2 = (Clip) AudioSystem.getLine(info3);
                clip2.open(stream2);
                clip3 = (Clip) AudioSystem.getLine(info4);
                clip3.open(stream3);
    		}
    		catch (LineUnavailableException ex) {
    		}
        	catch (IOException e) {
            }

            clip.start();
            clip2.start();
            clip3.start();
    	}
    	else
			System.out.println("Sem Som......");
//		NXTCommand.open();    															// NXT command
//		bt = new TouchSensor(SensorPort.S1);											// NXT command
//		lgt = new LightSensor(SensorPort.S3);											// NXT command
//		us = new UltrasonicSensor(SensorPort.S4);										// NXT command
//		sd = new SoundSensor(SensorPort.S2);											// NXT command
        stepId           = liberu.initiateIds();
        stepId2          = liberu.initiateIds2();
        stepBarrierTaste = liberu.initiateTaste();
        stepBarrier2Taste= liberu.initiate2Taste();
        stepBarrierSmell = liberu.initiateSmell();
        stepBarrier2Smell= liberu.initiate2Smell();
        stepBarrierVision= liberu.initiateVision();
        stepBarrier2Vision= liberu.initiate2Vision();
        stepBarrierTact  = liberu.initiateTact();
        stepBarrier2Tact = liberu.initiate2Tact();
        stepBarrierSound = liberu.initiateSound();
        stepBarrier2Sound= liberu.initiate2Sound();
        stepBarrierProSelf= liberu.initiateProSelf();
        stepBarrier2ProSelf= liberu.initiate2ProSelf();
        stepBarrierAct   = liberu.initiateAct(clip, clip2, clip3);
        stepBarrierREU   = liberu.initiateREU();
        stepBarrierTime  = liberu.initiatePastTime();
        try {
            while(!interrupted() && moreWork) {
                moreWork = true;
//                if (liberu.past.time[0][0].step >= Liberu.NNEURONT)
//                    moreWork = false;
                if (liberu.past.nodeTaste[0].step >= liberu.past.nNeuronsPTaste-1)
                    moreWork = false;
                if (liberu.past.nodeSmell[0].step >= liberu.past.nNeuronsPSmell-1)
                    moreWork = false;
                if (liberu.past.nodeVision[0].step >= liberu.past.nNeuronsPVision-1)
                    moreWork = false;
                if (liberu.past.nodeTact[0].step >= liberu.past.nNeuronsPTact-1)
                    moreWork = false;
                if (liberu.past.nodeSound[0].step >= liberu.past.nNeuronsPSound-1)
                    moreWork = false;
                if (liberu.past.nodeProSelf[0].step >= liberu.past.nNeuronsPProSelf-1)
                    moreWork = false;
                if (!moreWork) {
                    liberu.endLiberu(true);
                    stepBarrierTaste.await();      // Free nodes to ended
                    stepBarrierSmell.await();      // Free nodes to ended
                    stepBarrierVision.await();      // Free nodes to ended
                    stepBarrierTact.await();      // Free nodes to ended
                    stepBarrierSound.await();      // Free nodes to ended
                    stepBarrierProSelf.await();      // Free nodes to ended
                    setToEnd();
                }
                else {
                    if (aStep) {
                        if (oneStep) {
                            oneStep = false;
                            runStepLiberu();
                            System.out.println("oneStep...");
                        }
                        else
                            sleep(200);       // Waits 200ms by 200ms for the key <Step> pressed
                    }
                    else {
                        runStepLiberu();
                        sleep(TimeSlize);     // or yield(); without the <else>
                    }
                }
            }
        }
        catch(InterruptedException e) {
//            e.printStackTrace();
        }
        catch (BrokenBarrierException ex) { 
        }
//		NXTCommand.close();    														// NXT command
//        line.close();																// NXT
        System.out.println("End of PlayLiberu Thread...");
    }
}
