import java.awt.BorderLayout;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;

import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

import lejos.pc.comm.NXTComm;
import lejos.pc.comm.NXTCommException;
import lejos.pc.comm.NXTCommFactory;
import lejos.pc.comm.NXTInfo;

public class Map extends JPanel implements KeyListener {

	private ImageMap map;
	
	private DataOutputStream output;
	private DataInputStream input;
	private int before;

	public static final byte FORWARD = 0;
	public static final byte STOP = 1;
	public static final byte EXIT = 2;
	public static final byte LEFT = 3;
	public static final byte RIGHT = 4;
	public static final byte BACKWARD = 5;
	
	private class Receiver extends Thread {
		@Override
		public void run() {
			int bytes_valiable = -1;
			
			while(true) {
				try {
					bytes_valiable = input.available();
				} catch (IOException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
				if (bytes_valiable >= 0) {
					try {
						if (input.readByte() != '@') continue;
						int angle = input.readByte();
						float alpha = input.readFloat();
						float x = input.readFloat();
						int distance = input.readByte();
						float y = input.readFloat();
					} catch (IOException e1) {
						continue;
					}
					map.
					System.out.println(x+" "+y);
				}
			}
		}
	}
	
	public Map (DataInputStream in, DataOutputStream out) {
		JFrame frame = new JFrame("Mapa MAC0318");
		Receiver r = new Receiver();
		output = out;
		input = in;
		before = -1;
		
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLayout(new BorderLayout());
        map = new ImageMap();
		frame.add(this.map);
		frame.setSize(800, 800);
		frame.setVisible(true);
		
		frame.setFocusable(true);
		frame.requestFocusInWindow();
		frame.addKeyListener(this);
		
		r.start();
		
		String text = "1,2,3 - Change view mode.\n";
		text += "s - Save image.\n";
		text += "l - Show trace.\n";
		JOptionPane.showMessageDialog(null, text);
	}
	
    public void addPoint(Point3D p) {
    		map.addPoint(p);
	}

	@Override
	public void keyPressed(KeyEvent e) {
		char input = e.getKeyChar();
		if (input == '1') map.setVisual(0);
		else if (input == '2') map.setVisual(1);
		else if (input == '3') map.setVisual(2);
		else if (input == 'l') map.showLine();
		else if (input == 's') map.save();
		
		 switch(e.getKeyCode()) { 
	        case KeyEvent.VK_UP:
	        		sendCmd(FORWARD);
	            break;
	        case KeyEvent.VK_DOWN:
	        		sendCmd(BACKWARD);
	            break;
	        case KeyEvent.VK_LEFT:
	        		sendCmd(LEFT);
	            break;
	        case KeyEvent.VK_RIGHT :
	        		sendCmd(RIGHT);
	            break;
	    }			 
	}

	@Override
	public void keyReleased(KeyEvent arg0) {
		sendCmd(STOP);
	}

	@Override
	public void keyTyped(KeyEvent arg0) {
		// TODO Auto-generated method stub
		
	}
	
	private void sendCmd (int cmd) {
		if (before != cmd) {
			try {
				output.write(cmd);
				output.flush();
				System.out.println("Send cmd");
			} catch (IOException e1) {
				System.out.println("Erro send cmd");
				before = -1;
				sendCmd (cmd);
			}
			before = cmd;
		}
	}
	

	public static void main(String[] args) throws NXTCommException, IOException {
		NXTComm nxtComm = NXTCommFactory.createNXTComm(NXTCommFactory.BLUETOOTH); 
		NXTInfo[] nxtInfo = nxtComm.search("NXT8"); //find brick with NXT_ID by doing a Bluetooth inquiry
		if (nxtInfo.length == 0) { // failed to find a brick with the ID
			System.err.println("NO NXT found");
			System.exit(1);
		}
		if (!nxtComm.open(nxtInfo[0])) { // the brick was found but a connection could not be establish
			System.err.println("Failed to open NXT");
			System.exit(1);
		}
		
		final DataInputStream input = new DataInputStream(nxtComm.getInputStream()); // open data input stream 
		final DataOutputStream output = new DataOutputStream(nxtComm.getOutputStream()); // open data output stream
		
		SwingUtilities.invokeLater(new Runnable() {
            public void run() {
            	new Map(input, output);
            }
        });
		
	}
}
