<html>
<xmp>
/**
 * Title: iSIM
 * Copyright: Copyright (c) 2002
 * Company:   University of Oregon Computer Science Dept.
 *
 * @author Jason Prideaux
 * @version 1.0
 *
 */

import gps_monitor.gui.*;
import gps_monitor.gps.*;
import gps_monitor.util.*;

import java.awt.*;
import java.awt.event.*;
import java.util.GregorianCalendar;
import java.util.TooManyListenersException;
import java.io.IOException;
import javax.comm.*;


/* ====================================================================== */
/** This class is for running the GpsMonitor iPAQ Application.
 *
 */
public class GpsMonitor{

	/**  */
  	private GpsMonitorUI monitorUI;

	/**  */
  	private GpsGenerator gps;

	/**  */
	private Position chart_pos;	//the current position

	/**  */
  	private ChartData chartdata; // current chart



  	/**
  	 * Constructor that creates an instance of GpsMonitor. This is achieved
  	 * by creating a NmeaSerialGps object to deal with input from the GPS
  	 * receiver, and creating a GUI (GpsMonitorUI) that will display the
  	 * results.
  	 *
  	 * @param user The object/gps device we are monitoring
  	 * @see locationUtils.GpsMonitorUI
  	 * @see NmeaSerialGps
  	 */
  	public GpsMonitor(String user, String inputPort, boolean sim, int port){

    	//Set up the UI for the gps display
		monitorUI = new GpsMonitorUI(user, sim);


		//read in the chart for displaying the gps map location
		chart_pos = new Position();
		readData("files/data/charts.dat");
		monitorUI.changeChart(chartdata.imgFileName,10,-1);


  		try{
			if(sim){
  				gps = new NmeaSocketGps(monitorUI, port);
			}else{
				gps = new NmeaSerialGps(inputPort, 9600, monitorUI);
			}

		//Handle exceptions that can be thrown by creating a NmeaSerialGps
		}catch (PortInUseException e){
			System.out.println("PortInUseException: The chosen input port is already in use.");
		}catch (IOException e){
			System.out.println("IOException: Could not create an InputStream on the input port.");
		}catch (TooManyListenersException e){
			System.out.println("TooManyListenersException: Cannot add another listener to the input port.");
		}catch (UnsupportedCommOperationException e){
			System.out.println("UnsupportedCommOperationException: Could not specify the settings for the input port."+e);
		}




		try{

			//I really only care about coordinates and heading, maybe speed for later
			//Relay the data received to the UI//Relay the data received to the UI
			monitorUI.setLatitude(gps.getLatitude().toStringDDMM());
			monitorUI.setLongitude(gps.getLongitude().toStringDDMM());
			monitorUI.setHeading(gps.getTrueHeading());

			LatOrLongitude lat = gps.getLatitude();
			LatOrLongitude lon = gps.getLongitude();


		}catch (NullPointerException e){
			System.out.println("Initialisation poll failed.");
		}

		//show the UI
		monitorUI.setVisible(true);

		//start the thread to check for gps updates
		runMonitor();

  	} //Constructor




  	/**
  	 * This loop continues polling the widget until the application is shut down.
  	 */
  	private void runMonitor(){

  		while (true){

			try{
				Thread.sleep(3000);

			}catch(Exception e){System.out.println(e);}

			//check for new gps values
			pollGps();

		} //while

  	} //method:



  	/**
  	 * This method updates the GUI with the latest values available from the GPS.
  	 */
  	private void pollGps(){

		try{
			//Relay the data received to the UI//Relay the data received to the UI

			//I really only care about coordinates and heading, maybe speed for later
			//update our gps position on the display chart in the UI
			LatOrLongitude lat = gps.getLatitude();
			LatOrLongitude lon = gps.getLongitude();
			chart_pos.lat = ((int)lat.getDegrees())*60 + lat.getMinutes();
			chart_pos.lng = (((int)lon.getDegrees())*-60) + lon.getMinutes()+60;

			Point p = chartdata.transPos(chart_pos);
			monitorUI.updatePos(p,chartdata.transPos(calcPred(chart_pos)));

			//now set the values in the UI
			monitorUI.setLatitude(lat.toStringDDMM());
			monitorUI.setLongitude(lon.toStringDDMM());
			//monitorUI.setAltitude(new Double(gps.getAltitude()));
			//monitorUI.setLastUpdate(new Long (gps.getTimeLastLocationUpdate()));
			//monitorUI.setStatus(gps.getStatus());
			//monitorUI.setSpeed(new Double(gps.getSpeed()));
			monitorUI.setHeading(gps.getTrueHeading());
			//String osRef = LocationConverter.geospatialToOSGB(lat, lon);
			//monitorUI.setOSReference(osRef);
			//monitorUI.setUTMReference(LocationConverter.geospatialToUTM(lat, lon));
			//monitorUI.setPresentAccuracy(new Double(gps.getPresentHorizontalAccuracy()));


		}catch (NullPointerException e){
			//e.printStackTrace();
			//System.out.println(e);
		}

  	} //method: pollGps






  	/**
  	 * The main method that creates an instance of GpsMontior according to a command-line
  	 * argument.  The argument specifies the name of the object that is being tracked.
  	 */
  	public static void main (String argv[]){

		int port = 2323;
		boolean sim = CommandLine.isArg(argv, 's');

		if(sim){
			port = Integer.parseInt( CommandLine.getArg(argv,"s","2323") );
		}


 		GpsMonitor sa = new GpsMonitor("Easy GPS", "COM5:", sim, port);
  	}




 	/** Read calibration data from file. */
 	 private void readData(String file_name){

    	chartdata = null;

    	FileLineReader in=new FileLineReader(file_name);

    	try{
      		while(true){

        		String str=in.readLine();

				if (str==null) break;

				if (str.length()==0){

				}else if (str.startsWith("name")){

				  	chartdata=ChartData.loadChartData(in,ChartWord.skipWords(str,1));

				}else if (str.startsWith("begin")){

				  	chartdata=ChartData.loadChartData(in,null);

				}
			} //while

			in.close();

    	}catch (IOException e) {}
    	catch (NumberFormatException e) {}

  	} //method:



  	/**
  	 * Calculate where we will be in <predScale> seconds with current
  	 * speed and direction.
  	 */
  	private Position calcPred(Position pos)
  	{
		Position pred=new Position();
		double r=120*pos.speed/3600;
		pred.lng=pos.lng+r*Math.sin(Math.PI*pos.track/180)/Math.cos(Math.PI*pos.lat/(180*60));
		pred.lat=pos.lat+r*Math.cos(Math.PI*pos.track/180);
		return(pred);
  	}


} //class: GpsMonitor
</xmp>
</html>
