package com.example.accelerometre01;

import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.widget.Toast;

// https://www.youtube.com/watch?v=fE7m1aYw3dk

// http://rdcworld-android.blogspot.fr/2012/05/calculate-device-moving-speed.html

//http://stackoverflow.com/questions/15570542/determining-the-speed-of-a-vehicle-using-gps-in-android

// Haversine formula

public class speed_service extends Service
{
	
	LocationManager location_manager;
	LocationListener location_listener = new myLocationListener();

	double HEARTH_RADIUS = 6371.00; 
	boolean gps_enabled = false;
	boolean network_enabled = false;
	
	Handler handler = new Handler();
	Thread t;
	
	
	@Override
	public IBinder onBind(Intent intent) 
	{
		// TODO Auto-generated method stub
		return null;
	}
	
	@Override
	public void onCreate() 
	{
	}
	
	@Override
	public void onDestroy() 
	{
	}
	
	@Override
	public void onStart(Intent intent, int startId) 
	{
	}
	

	@Override
	public int onStartCommand(Intent intent, int flags,int startId) 
	{
		Toast.makeText(getApplicationContext(), "Service started" , Toast.LENGTH_SHORT).show();
	
		
		final Runnable r = new Runnable()
		{
			public void run()
			{
				location();
				handler.postDelayed(this, 5000);
			}
		};
	
		handler.postDelayed(r, 5000);
		return START_STICKY;

	}		
	
	public void location()
	{
		location_manager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
		
		try
		{
			gps_enabled = location_manager.isProviderEnabled(location_manager.GPS_PROVIDER);
		}
		catch(Exception ex)
		{
			
		}
		
		try
		{
			network_enabled = location_manager.isProviderEnabled(location_manager.NETWORK_PROVIDER);
		}
		catch(Exception ex)
		{
			
		}
		
		if(gps_enabled)
		{
			location_manager.requestLocationUpdates(location_manager.GPS_PROVIDER,0,0, location_listener);
		}
		
		if(network_enabled)
		{
			location_manager.requestLocationUpdates(location_manager.NETWORK_PROVIDER,0,0, location_listener);
		}
		
		
		
	}
	
	private class myLocationListener implements LocationListener
	{

		double lat_old = 0.0;
		double lon_old = 0.0;
		double lat_new = 0.0;
		double lon_new = 0.0;
		double time = 0.0;
		double speed = 0.0;

		// https://www.youtube.com/watch?v=Sn1G_eqMox8
		
		@Override
		public void onLocationChanged(Location location)
		{
			if(location != null)
			{
				location_manager.removeUpdates(location_listener);
				lat_new = location.getLatitude();
				lon_new = location.getLongitude();
				
				speed = location.getSpeed();

				double distance = calc(lat_new, lon_new, lat_old, lon_old );
				speed = distance / time;
				lat_old = lat_new;
				lon_old = lon_new;
				
				//double pipo = location.distanceBetween(lat_new, lon_new, lat_old, lon_old, null);
				
				// example
				float [] dist = new float[1];
			    Location.distanceBetween(lat_new, lon_new, lat_old, lon_old, dist);
			    //dist[0] * 0.000621371192f;
				
			}
			
		}

		@Override
		public void onStatusChanged(String provider, int status, Bundle extras) {
			// TODO Auto-generated method stub
			
		}

		@Override
		public void onProviderEnabled(String provider) {
			// TODO Auto-generated method stub
			
		}

		@Override
		public void onProviderDisabled(String provider) {
			// TODO Auto-generated method stub
			
		}
		
	}
	
	public double calc(double lat1, double lon1, double lat2, double lon2)
	{
		double dLat = Math.toRadians(lat2-lat1);  
		  double dLon = Math.toRadians(lon2-lon1);  
		  double a = Math.sin(dLat/2) * Math.sin(dLat/2) +  
		  Math.cos(Math.toRadians(lat1)) * Math.cos(Math.toRadians(lat2)) *  
		  Math.sin(dLon/2) * Math.sin(dLon/2);  
		  double c = 2 * Math.asin(Math.sqrt(a));  
		  return HEARTH_RADIUS * c;
		
	}
	
	// en KM
	private double distance(double lat1, double lon1, double lat2, double lon2) {
	    double theta = lon1 - lon2;
	    double dist = Math.sin(deg2rad(lat1)) 
	                    * Math.sin(deg2rad(lat2))
	                    + Math.cos(deg2rad(lat1))
	                    * Math.cos(deg2rad(lat2))
	                    * Math.cos(deg2rad(theta));
	    dist = Math.acos(dist);
	    dist = rad2deg(dist);
	    dist = dist * 60 * 1.1515;
	    return (dist);
	}

	private double deg2rad(double deg) {
	    return (deg * Math.PI / 180.0);
	}

	private double rad2deg(double rad) {
	    return (rad * 180.0 / Math.PI);
	}
	
}
