import javax.microedition.lcdui.*;
import javax.microedition.midlet.*;
import javax.microedition.location.*;
import java.util.Enumeration;

public class LandmarkDistance extends MIDlet implements CommandListener {
	
  private Display display;	
  private Form mainForm;
  private Alert positionAlert;
  private LandmarkStore landmarkStore;
  private ChoiceGroup landmarkList;
  
  public LandmarkDistance() {
  	
  	buildMainForm();
  }
  
  private void buildMainForm() {
  	
  	mainForm = new Form("LandmarkDistance");
  	StringItem welcomeMsg = new StringItem("welcome", "Press OK to see list of Landmarks");
    mainForm.append(welcomeMsg);
    
    mainForm.addCommand(new Command("Exit", Command.EXIT, 0));
    mainForm.addCommand(new Command("OK", Command.OK, 1));
    mainForm.setCommandListener(this);
  }
  
  public void startApp() {
  	
  	display = Display.getDisplay(this);
    display.setCurrent(mainForm);
    
  	buildLandmarkDirectory(); 
  }
  
  public void pauseApp() {}
  
  public void destroyApp(boolean unconditional) {}
  
  private void buildLandmarkDirectory() {
  	
  	try {
    	
    	LandmarkStore.createLandmarkStore("landmarks");
		landmarkStore = LandmarkStore.getInstance("landmarks");
		landmarkStore.addCategory("NY");
	    Landmark landmark = new Landmark("liberty",null,new QualifiedCoordinates(40.689, 74.045, 0, Float.NaN, Float.NaN) ,null);
	    landmarkStore.addLandmark(landmark, "NY");
	}
	catch (Exception e) {
		
		Alert alert = new Alert ("Error in landmark creation section");
		alert.setString(e.toString());
		alert.setTimeout(alert.FOREVER);
		display.setCurrent(alert);
		
	}
  }  
  
  public void commandAction(Command c, Displayable s) {
  	
  	String label = c.getLabel();
    if (label.equals("Exit")) {
		
		try {
  		
	  		LandmarkStore.deleteLandmarkStore("landmarks");
	  	}
	  	catch (Exception e) {
	  		
	  		Alert alert = new Alert ("Error");
			alert.setString(e.toString());
			alert.setTimeout(alert.FOREVER);
			display.setCurrent(alert);
	  	}
    	notifyDestroyed();
    }
    else if (label.equals("OK")) {
    	
    	String level = mainForm.get(0).getLabel();
    	if (level.equals("welcome")) {
    		
    		listLandmarks("_top");
    	}
    	else if (level.equals("main")) {
    		
    		listLandmarks(landmarkList.getString(landmarkList.getSelectedIndex()));
    	}
    	else {
    		
    		
			LocationInfo locationInfo = new LocationInfo(level, landmarkList.getString(landmarkList.getSelectedIndex()));
			Thread locationInfoThread = new Thread(locationInfo);
			for (int i=0; i< mainForm.size(); i++) {
						
				mainForm.delete(i);
			}
			mainForm.append("Getting location Provider ...");
			locationInfoThread.start();
		}
    }
  }
  
  private void listLandmarks(String category) {
  	
  	Enumeration landmarkEnumeration = null;
  	landmarkList = new ChoiceGroup (null,ChoiceGroup.EXCLUSIVE);
  	String msgLabel = null;
  	
  	if (category == "_top") {
  		
  		landmarkEnumeration = landmarkStore.getCategories();
	  	while (landmarkEnumeration.hasMoreElements()) {
	  		
	  		landmarkList.append((String)(landmarkEnumeration.nextElement()), null);
	  	}
	  	msgLabel = "main"; 
  	}
  	else {
  		
  		try {
  		
	  		landmarkEnumeration = landmarkStore.getLandmarks(category, null);
	  	}
	  	catch (Exception e) {
	  		
	  		Alert alert = new Alert ("Error in getLandmarks " + e);
			display.setCurrent(alert);
	  	}
	  	while (landmarkEnumeration.hasMoreElements()) {
	  		
	  		Landmark landmark = (Landmark)(landmarkEnumeration.nextElement());
	  		landmarkList.append(landmark.getName(), null);
	  	}
	  	msgLabel = category;
  	}
  	
  	mainForm.set(0,new StringItem(msgLabel,null));
  	if (mainForm.size() == 1) {
  		
  		mainForm.append(landmarkList);
  	}
  	else {
  		
  		mainForm.set(1,landmarkList);
  	}
  }
  
  class LocationInfo implements Runnable {
  	
  	String category, landmarkName;
  	boolean quit;
  	
  	LocationInfo(String category, String landmarkName) {
  		
  		this.category = category;
  		this.landmarkName = landmarkName;
  	}
  	
  	public void run() {
  		
		try {
			Enumeration landmarkEnum = landmarkStore.getLandmarks(category, landmarkName);
			Landmark landmark = (Landmark)landmarkEnum.nextElement();
			
			Coordinates target = landmark.getQualifiedCoordinates();
		
			Criteria cr = new Criteria();
			cr.setHorizontalAccuracy(500);
			
			LocationProvider lp = LocationProvider.getInstance(cr);	
			
			//mainForm.delete(0);		
			
	  		while(!quit) {
	  			
	  			mainForm.append("\nrefreshing distance ...");
	  			Location l = lp.getLocation(60);
				Coordinates present = l.getQualifiedCoordinates();		
				if (present != null && target!= null) {
					
					float distance = target.distance(present);
					for (int i=0; i < mainForm.size(); i++) {
					
						mainForm.delete(i);
					}
					mainForm.set(0,new StringItem(null,"\n" + landmarkName + " distance : " + distance + "m"));
				}
				else {
					
					positionAlert = new Alert("Error");
					positionAlert.setString("Null Coordinate Received");
					positionAlert.setTimeout(Alert.FOREVER);
				}
				Thread.sleep(15000);
	  		}			
		}
		catch (Exception e) {
			
			positionAlert = new Alert("Error");
			positionAlert.setString(e.toString());
			positionAlert.setTimeout(Alert.FOREVER);
		}
		
		
  	}
  	
  	void quit() {
  		
  		this.quit = true;
  	}         
  }
}