import gnu.io.CommPort;
import gnu.io.CommPortIdentifier;
import gnu.io.SerialPort;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


public class NMEASerialCt extends JavActComponent implements GPSCtI, Runnable {

	private boolean connected=false;
	private String longitude=null, latitude=null;
	private float height, heading, speed;
	private BufferedReader in;

	public void setMyControler(Controler c) {
		super.setMyControler(c);
		connected=connect("COM6");
	}

	public void terminate() {
		super.terminate();
		disconnect();
	}

	public boolean connect(String portName) {
			Thread myThread=null;
			try {
				System.out.println("Connecting to "+portName+"... ");
				CommPortIdentifier portIdentifier = CommPortIdentifier.getPortIdentifier(portName);
				if (portIdentifier.isCurrentlyOwned()) {
					System.out.println("Port is already in use !");
					return false;
				}
				CommPort commPort = portIdentifier.open(this.getClass().getName(),2000);

				if (commPort instanceof SerialPort)	{
					SerialPort serialPort = (SerialPort) commPort;
					serialPort.setSerialPortParams(4800,SerialPort.DATABITS_8,SerialPort.STOPBITS_1,SerialPort.PARITY_NONE);
					in = new BufferedReader(new InputStreamReader(serialPort.getInputStream()));
					connected=true;
					myThread=(new Thread(this));
					myThread.start();
				} else return false;
			} catch (Exception e) {System.out.println(e); if (myThread!=null) myThread.interrupt(); return false;}
			int timeout=0;
			while (latitude==null && timeout<50)
				try{ Thread.sleep(100); System.out.print("."); timeout++;} catch (Exception e) {}
			if (timeout==50) {
				//disconnect();
				myThread.interrupt();
				System.out.println("Unable to detect any NMEA data !");
				connected=false;
				return false;
			}
			System.out.println("OK");
			return true;
	}

	public void disconnect() {
		try {
			in.close();
		} catch (IOException e) {}
		connected=false;
	}

	public void run() {
		Pattern GLLPatern=Pattern.compile("GPGLL,([^,]*),(.),([^,]*),(.),.*");
		Pattern RMCPatern=Pattern.compile("GPRMC,[^,]*,.,[^,]*,.,[^,]*,.,([^,]*),([^,]*),.*");

		String line;
    	Matcher match;

        try {
        	while (connected && (line = in.readLine())!=null) {
        		match=GLLPatern.matcher(line);
        		if (match.find()) {
        			//System.out.println(match.group(1)+match.group(2)+" - "+match.group(3)+match.group(4));
        			longitude=match.group(3)+match.group(4);
        			latitude=match.group(1)+match.group(2);
        		}
        		match=RMCPatern.matcher(line);
        		if (match.find()) {
        			//System.out.println(match.group(1)+"km/h "+match.group(2)+"°");
        			speed=Float.valueOf(match.group(1)).floatValue();
        			heading=Float.valueOf(match.group(2)).floatValue();
        		}
        	}
		} catch (Exception e) { System.out.println("Problème d'acquisition des données !"); e.printStackTrace(); }

	}

	public boolean isConnected() {
		return connected;
	}

	public float getHeading() {
		return heading;
	}

	public float getHeight() {
		return height;
	}

	public String getLatitude() {
		return latitude;
	}

	public String getLongitude() {
		return longitude;
	}

	public float getSpeed() {
		return speed;
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		new NMEASerialCt().connect("COM6");
	}
}
