package com.example.Maps011;


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;

import org.json.JSONObject;

import android.location.Address;

import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.graphics.Color;
import android.location.Geocoder;
import android.net.ConnectivityManager;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;
import android.widget.Button;
import android.widget.EditText;
import android.widget.SimpleAdapter;
import android.widget.Toast;

//import com.google.android.gms.identity.intents.Address;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.GoogleMap.OnMapClickListener;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
import com.google.android.gms.maps.model.PolylineOptions;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
 
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
 
import com.google.android.gms.maps.model.LatLng;


 
public class Geo03 extends FragmentActivity 
{
 
	GoogleMap map;
	ArrayList markerPoints;
	Dialog dialog;
	AlertDialog.Builder alertDialog;
	EditText et_departure, et_destination;
	Button btn_find, btn_cancel, btn_direction;
	String test_message_address_departure = "";
	String test_message_address_destination = "";
	boolean flag_address_departure = true;
	boolean flag_address_destination = true;
	int test_sequence = 0;
	
	String departure = "";
	String destination = "";
	private ProgressDialog progressdialog;
	
	
	/* autocmpletion */
	AutoCompleteTextView autocomplete_tv;
    ArrayList<String> names;
    JSONObject json;
    String url;
    private static final String TAG_RESULT = "predictions";
    ArrayAdapter<String> adapter;
    String browserKey = "Your API KEY";
    
    autocomplete_PlacesTask autocomplete_PlacesTask;
    autocomplete_ParserTask autocomplete_ParserTask;
	
	@Override
	protected void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		setContentView(R.layout.geo03_layout);
 
		// Initializing
		markerPoints = new ArrayList();
 
		// Getting reference to SupportMapFragment of the activity_main
		SupportMapFragment fm = (SupportMapFragment)getSupportFragmentManager().findFragmentById(R.id.map);
 
		// Getting Map for the SupportMapFragment
		map = fm.getMap();
 
		//
		// zoom sur le centre de la France 
		map.moveCamera( CameraUpdateFactory.newLatLngZoom(new LatLng(46.4606 , 2.2557) , 5.5f) );
		
		initAddressDialog();
		ListenerDirectionButton();
		
	}
	
		
	 public void initAddressDialog()
	 {
	        dialog = new Dialog(this);
	        dialog.setTitle("Address:");
	        dialog.setContentView(R.layout.direction_dialog_layout);
	        et_departure = (EditText)dialog.findViewById(R.id.et_address_departure);
	        et_destination = (EditText)dialog.findViewById(R.id.et_address_destination);
	        btn_find = (Button)dialog.findViewById(R.id.btn_find);
	        btn_cancel = (Button)dialog.findViewById(R.id.btn_cancel);
	        
	        autocomplete_tv = (AutoCompleteTextView) findViewById(R.id.autoCompleteTextView);
	       
	/*        
	        autocomplete_tv.addTextChangedListener(new TextWatcher()
	        {
	        	 
	            @Override
	            public void onTextChanged(CharSequence s, int start, int before, int count)
	            {
	            	autocomplete_PlacesTask = new autocomplete_PlacesTask();
	            	autocomplete_PlacesTask.execute(s.toString());
	            }
	 
	            @Override
	            public void beforeTextChanged(CharSequence s, int start, int count,
	            int after) {
	                
	            }
	 
	            @Override
	            public void afterTextChanged(Editable s) {
	              
	            }
	        });
	*/        
	        
     }
     
	 
	 
	 /** A method to download json data from url */
	    private String autocomplet_downloadUrl(String strUrl) throws IOException
	    {
	        String data = "";
	        InputStream iStream = null;
	        HttpURLConnection urlConnection = null;
	        try{
	                URL url = new URL(strUrl);                

	                // Creating an http connection to communicate with url 
	                urlConnection = (HttpURLConnection) url.openConnection();

	                // Connecting to url 
	                urlConnection.connect();

	                // Reading data from url 
	                iStream = urlConnection.getInputStream();

	                BufferedReader br = new BufferedReader(new InputStreamReader(iStream));

	                StringBuffer sb  = new StringBuffer();

	                String line = "";
	                while( ( line = br.readLine())  != null){
	                        sb.append(line);
	                }
	                
	                data = sb.toString();

	                br.close();

	        }catch(Exception e){
	                Log.d("Exception while downloading url", e.toString());
	        }finally{
	                iStream.close();
	                urlConnection.disconnect();
	        }
	        return data;
	 }	
	
	    
	 // Fetches all places from GooglePlaces AutoComplete Web Service
		private class autocomplete_PlacesTask extends AsyncTask<String, Void, String>{

			@Override
			protected String doInBackground(String... place) {
				// For storing data from web service
				String data = "";
				
				// Obtain browser key from https://code.google.com/apis/console
				String key = "AIzaSyBXw9vydHGGjBOYSeM9i-Xh8f9Mk0xzg1k";
				
				String input="";
				
				try {
					input = "input=" + URLEncoder.encode(place[0], "utf-8");
				} catch (UnsupportedEncodingException e1) {
					e1.printStackTrace();
				}		
				
				
				// place type to be searched
				String types = "types=geocode";
				
				// Sensor enabled
				String sensor = "sensor=false";			
				
				// Building the parameters to the web service
				String parameters = input+"&"+types+"&"+sensor+"&"+key;
				//String parameters = input+"&"+types+"&"+sensor+"&"+key+"&components=country:fr";
				
				
				//&components=country
				
				// Output format
				String output = "json";
				
				// Building the url to the web service
				String url = "https://maps.googleapis.com/maps/api/place/autocomplete/"+output+"?"+parameters;
		
				try{
					// Fetching the data from web service in background
					data = downloadUrl(url);
				}catch(Exception e){
	                Log.d("Background Task",e.toString());
				}
				return data;		
			}
			
			@Override
			protected void onPostExecute(String result) {			
				super.onPostExecute(result);
				
				// Creating ParserTask
				autocomplete_ParserTask = new autocomplete_ParserTask();
				
				// Starting Parsing the JSON string returned by Web Service
				autocomplete_ParserTask.execute(result);
			}		
		}
		

		
		/** A class to parse the Google Places in JSON format */
	    private class autocomplete_ParserTask extends AsyncTask<String, Integer, List<HashMap<String,String>>>
	    {

	    	JSONObject jObject;
	    	
			@Override
			protected List<HashMap<String, String>> doInBackground(String... jsonData)
			{			
				
				List<HashMap<String, String>> places = null;
				
	            PlaceJSONParser placeJsonParser = new PlaceJSONParser();
	            
	            try{
	            	jObject = new JSONObject(jsonData[0]);
	            	
	            	// Getting the parsed data as a List construct
	            	places = placeJsonParser.parse(jObject);

	            }catch(Exception e){
	            	Log.d("Exception",e.toString());
	            }
	            return places;
			}
			
			@Override
			protected void onPostExecute(List<HashMap<String, String>> result) 
			{			
				
					String[] from = new String[] { "description"};
					int[] to = new int[] { android.R.id.text1 };
					
					// Creating a SimpleAdapter for the AutoCompleteTextView			
					SimpleAdapter adapter = new SimpleAdapter(getBaseContext(), result, android.R.layout.simple_list_item_1, from, to);				
					
					// Setting the adapter
					autocomplete_tv.setAdapter(adapter);
			}			
	    }    

		/*************************/
	    
	    
	 public void ListenerDirectionButton()
	 {
	    	
	    	btn_direction = (Button) findViewById(R.id.btn_direction);
	    	btn_direction.setOnClickListener(new OnClickListener() 
	    	{
				@Override
				public void onClick(View v)
				{
						
					et_departure.setText("");
			        et_destination.setText("");
	                dialog.show();
	                btn_find.setOnClickListener(new View.OnClickListener() 
	                {
		                    @Override
		                    public void onClick(View v) 
		                    {
		                    	
		                    	if (et_departure.getText().toString().isEmpty() || et_destination.getText().toString().isEmpty())
		                        {
		                            Toast.makeText(getApplicationContext(), "Text fields cannot be empty", Toast.LENGTH_SHORT).show();
		                        } 
		                        else 
		                        {

		                        	map.clear();
		                        	
		                        	departure = et_departure.getText().toString();
		                        	destination = et_destination.getText().toString();
		                        	
		                        	
		                        	test_message_address_departure = "";
		                        	test_message_address_destination = "";
		                        	test_sequence = 1;
		                        	//new GeocoderTask().execute(departure);
		                        	test_sequence = 2;
		                        	//new GeocoderTask().execute(destination);
		                        	
		                        	ArrayList<String> list=new ArrayList<String>();//Creating arraylist  
		                        	list.add(departure);//Adding object in arraylist  
		                        	list.add(destination);  
		                        	
		                        	dialog.dismiss();
		                        	
		                        	new GeocoderTask().execute(list);
		                        	
		                        	
/*
		                        	if(test_message_address_departure.equals("") && test_message_address_destination.equals("") )
		                        	{
		                        		String url = getDirectionsUrl(departure, destination);
		                        		DownloadTask downloadTask = new DownloadTask();
		                        		downloadTask.execute(url);
		                        		Toast.makeText(getBaseContext(), "Bingo", Toast.LENGTH_SHORT).show();
		                        		dialog.dismiss();
		                        	}
		                        	else
		                        	{
		                        		String mess_error = "";
		                        		
		                        		if(!test_message_address_departure.equals("") && test_message_address_destination.equals(""))
		                        		{
		                        			mess_error = "Address departure not found";
		                        		}
		                        		if(test_message_address_departure.equals("") && !test_message_address_destination.equals(""))
		                        		{
		                        			mess_error = "Address destination not found";
		                        		}
		                        		if(!test_message_address_departure.equals("") && !test_message_address_destination.equals(""))
		                        		{
		                        			mess_error = "Address departure and destination not found";
		                        		}
		                        		
		                        		 Toast.makeText(getBaseContext(), mess_error, Toast.LENGTH_SHORT).show();
		                        		
		                        	}
*/		                        	
		                        	
		                        }
		                    	
		                     
		                    }
	                });
	                btn_cancel.setOnClickListener(new View.OnClickListener() 
	                {
		                    @Override
		                    public void onClick(View v) 
		                    {
		                        dialog.dismiss();
		                    }
	                });
	                
	              /*  
	                autocomplete_tv.addTextChangedListener(new TextWatcher()
	    	        {
	    	        	 
	    	            @Override
	    	            public void onTextChanged(CharSequence s, int start, int before, int count)
	    	            {
	    	            	//autocomplete_PlacesTask = new autocomplete_PlacesTask();
	    	            	//autocomplete_PlacesTask.execute(s.toString());
	    	            }
	    	 
	    	            @Override
	    	            public void beforeTextChanged(CharSequence s, int start, int count,
	    	            int after) {
	    	                
	    	            }
	    	 
	    	            @Override
	    	            public void afterTextChanged(Editable s) {
	    	              
	    	            }
	    	        });
					
					*/
					
				}

			});

	}

	    
	    
	private String getDirectionsUrl(String departure, String destination)
	{
		
//		https://www.google.fr/maps/place/47+Chemin+du+Chapitre,+31100+Toulouse/@43.5592555,1.4104784,18.5z/
//			data=!4m19!1m13!4m12!1m6!1m2!1s0x12ade1d1de291969:0x406f69c2f3be360!2sR%C3%A9almont,+France!2m2!1d2.18884!2d43.776621!1m3!2m2!1d1.
//			4105353!2d43.5590191!3e0!3m4!1s0x12aebbd160c93441:0xf7aa4d53c02c4ec9!8m2!3d43.5590204!4d1.4105316
		
	
		
		// Origin of route
		String str_origin = "origin=" + departure; 
				 
		// Destination of route
		String str_dest = "destination=" + destination;
		
		// Sensor enabled
		String sensor = "sensor=false";
				 
		// Building the parameters to the web service
		//String parameters = str_origin+"&"+str_dest+"&"+sensor;
		String parameters = str_origin+"&"+str_dest+"&"+sensor+"&region=fr" ;
		
		
		parameters = parameters.replaceAll(" ", "+");
		
		/*
		try {
			parameters = URLEncoder.encode(parameters, "utf-8");
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}*/
				 
		// Output format
		String output = "json";
				 
		//&components=country:gr
		
		//&region=es
		
		// Building the url to the web service
		String url = "https://maps.googleapis.com/maps/api/directions/"+output+"?"+parameters;
		
		//url = "https://maps.googleapis.com/maps/api/directions/json?origin=Disneyland&destination=Universal+Studios+Hollywood";
		
		//url = "https://maps.googleapis.com/maps/api/directions/json?origin=Toulouse&destination=albi";
		
		//url = "https://maps.googleapis.com/maps/api/directions/json?origin=1+rue+du+stade+realmont&destination=55+chemin+du+chapitre+toulouse";
		
		
		///// pour faire un test sur le service web de google 
		//http://maps.googleapis.com/maps/api/directions/json?origin=(MY
		
		return url;
		
	}
	
	private String getDirectionsUrl(LatLng origin,LatLng dest)
	{
 
		// Origin of route
		String str_origin = "origin="+origin.latitude+","+origin.longitude;
		 
		// Destination of route
		String str_dest = "destination="+dest.latitude+","+dest.longitude;
		 
		// Sensor enabled
		String sensor = "sensor=false";
		 
		// Building the parameters to the web service
		String parameters = str_origin+"&"+str_dest+"&"+sensor;
		 
		// Output format
		String output = "json";
		 
		// Building the url to the web service
		String url = "https://maps.googleapis.com/maps/api/directions/"+output+"?"+parameters;
		 
		return url;
	}
	
	
	// An AsyncTask class for accessing the GeoCoding Web Service
	// http://wptrafficanalyzer.in/blog/android-geocoding-showing-user-input-location-on-google-map-android-api-v2/
	//private class GeocoderTask extends AsyncTask<String, Void, List<Address>>
	private class GeocoderTask extends AsyncTask< ArrayList<String>, Void, String >
    {
 
		Context mContext;
		
        @Override
        //protected List<Address> doInBackground(String... locationName) 
        //protected String  doInBackground(String... locationName) 
        protected String  doInBackground(ArrayList<String>... passing) 
        {
            	// Creating an instance of Geocoder class
            	Geocoder geocoder = new Geocoder(getBaseContext(), Locale.FRANCE);
            	//Geocoder geocoder = new Geocoder(getBaseContext());
            	
            	
            	//List<Address> addresses = null;
            	List<Address> addresses_departure = null;
            	List<Address> addresses_destination = null;
            
            	String msg1 = "";
            	String msg2 = "";
            	String msg_content = "";
            
            	ArrayList<String> tmp_array = passing[0]; 
            	String local_departure = tmp_array.get(0);
            	String local_destination = tmp_array.get(1);

            
            	try {
                	                	
            				addresses_departure = geocoder.getFromLocationName(local_departure, 1); //
            		
		            		if(addresses_departure==null || addresses_departure.size()==0)
		            		{
		            			msg1 = "none1";
		            		}
		            		else
		            		{
		            			msg1 = "valide1";
		            		}
            		
		            		addresses_destination = geocoder.getFromLocationName(local_destination, 1); //

		            		if(addresses_destination==null || addresses_destination.size()==0)
		            		{
		            			msg2 = "none2";
		            		}
		            		else
		            		{
		            			msg2 = "valide2";
		            		}
            		
            		
		            		String global_msg = msg1 + msg2;
		            		
		            		if(global_msg.equals("none1none2"))
		            		{
		            			msg_content = "Departure and destination addresses are not found !";
		            		}
		            		
		            		if(global_msg.equals("valide1none2"))
		            		{
		            			msg_content = "Destination address not found !";
		            		}
		            		
		            		if(global_msg.equals("none1valide2"))
		            		{
		            			msg_content = "Departure address not found !";
		            		}
            		
		            		if(global_msg.equals("valide1valide2"))
		            		{
		            			msg_content = "OK";
		            		}
            		
            	
		                	//addresses = geocoder.getFromLocationName(departure, 1); //
		                	//addresses = geocoder.getFromLocationName(destination, 1); //
		                	
		                
		                	// https://github.com/ryanprater/Routy/blob/a31acc7cff366eda75869e828bcdedb31ccdf372/Routy/src/test/org/routy/service/RouteServiceTest.java
		                	//List<Address> destinations = new ArrayList<Address>();
		                	
		                	//List<Address> destBuffer = geocoder.getFromLocationName("300 West Martin Luther King Junior Boulevard, Austin, TX", 1);
		                	
		                	//Address  dest5 = destBuffer.get(0);
		                	//destinations.add(dest5);
		                	
		                	//destBuffer = geocoder.getFromLocationName("2902 Medical Arts Street, Austin, TX", 1);
		                	//dest5 = destBuffer.get(0);
		                	//destinations.add(dest5);
		                	
		                	 // Toast.makeText(getBaseContext(), "s" , Toast.LENGTH_SHORT).show();
                	
            	} 

            	catch (IOException e)
            	{
            		e.printStackTrace();
            	}
            
            	//return addresses;
            	return msg_content;
          
        }
        
        
        @Override
    	protected void onPreExecute() 
        {
    		
        		progressdialog = new ProgressDialog(Geo03.this);
    			progressdialog.setMessage("Downloading directions...");
    			progressdialog.setTitle("Please Wait...");
    			//progressdialog.setIndeterminate(false);
    			progressdialog.show();
    		
    	}
 
        @Override
        //protected void onPostExecute(List<Address> addresses)
        protected void onPostExecute(String info)
        {
 
        		// arret
        		//if (progressdialog.isShowing()) 
        		//{
        		//	progressdialog.dismiss();
        		//}
        	
	        	String msg = "";
	        	
	            //if(addresses==null || addresses.size()==0)
	        	
	        	
	        	if(info.equals("OK"))
	            {
	                //Toast.makeText(getBaseContext(), "Process running ..." , Toast.LENGTH_SHORT).show();
	        		String url = getDirectionsUrl(departure, destination);
	        		DownloadTask downloadTask = new DownloadTask();
	        		downloadTask.execute(url);
	
	            }
	            ///// affiche le message d'erreurs
	            else
	            {	
	            	  Toast.makeText(getBaseContext(), info, Toast.LENGTH_SHORT).show();
	            }	
            
        }
    }
	
	
	
 
	/** A method to download json data from url */
	private String downloadUrl(String strUrl) throws IOException
	{
		String data = "";
		InputStream iStream = null;
		HttpURLConnection urlConnection = null;
		try{
		URL url = new URL(strUrl);
		 
		// Creating an http connection to communicate with url
		urlConnection = (HttpURLConnection) url.openConnection();
		 
		// Connecting to url
		urlConnection.connect();
		 
		// Reading data from url
		iStream = urlConnection.getInputStream();
		 
		BufferedReader br = new BufferedReader(new InputStreamReader(iStream));
		 
		StringBuffer sb = new StringBuffer();
		 
		String line = "";
		while( ( line = br.readLine()) != null){
		sb.append(line);
		}
		 
		data = sb.toString();
		 
		br.close();
		 
		}catch(Exception e){
		Log.d("Exception while downloading url", e.toString());
		}finally{
		iStream.close();
		urlConnection.disconnect();
		}
		return data;
	}
 
	// Fetches data from url passed
	private class DownloadTask extends AsyncTask<String, Void, String>
	{
 
		// Downloading data in non-ui thread
		@Override
		protected String doInBackground(String... url) 
		{
		 
			// For storing data from web service
			String data = "";
			 
			try{
			// Fetching the data from web service
			data = downloadUrl(url[0]);
			}catch(Exception e){
			Log.d("Background Task",e.toString());
			}
			return data;
		}
 
		// Executes in UI thread, after the execution of // doInBackground()

		@Override protected void onPostExecute(String result) 
		{
			super.onPostExecute(result);
 
			if(!result.equals(""))
			{
				ParserTask parserTask = new ParserTask();
				// Invokes the thread for parsing the JSON data
				parserTask.execute(result);
			}	
			else
			{
				  Toast.makeText(getBaseContext(), "Impossible de tracer le chemin !", Toast.LENGTH_SHORT).show();
			}
		}
	}
 
	/** A class to parse the Google Places in JSON format */
	private class ParserTask extends AsyncTask<String, Integer, List<List<HashMap<String,String>>> >
	{
 
		// Parsing the data in non-ui thread
		@Override
		protected List<List<HashMap<String, String>>> doInBackground(String... jsonData)
		{
 
			JSONObject jObject;
			List<List<HashMap<String, String>>> routes = null;
 
			try{
			jObject = new JSONObject(jsonData[0]);
			DirectionsJSONParser_bis2 parser = new DirectionsJSONParser_bis2();
			 
			// Starts parsing data
			routes = parser.parse(jObject);
			}catch(Exception e){
			e.printStackTrace();
			}
			return routes;
		}
 
		// Executes in UI thread, after the parsing process
		@Override
		protected void onPostExecute(List<List<HashMap<String, String>>> result) 
		{

			ArrayList points = null;
			PolylineOptions lineOptions = null;
			MarkerOptions markerOptions = new MarkerOptions();
 
			// Traversing through all the routes
			for(int i=0;i<result.size();i++)
			{

				points = new ArrayList();
				lineOptions = new PolylineOptions();
 
				// Fetching i-th route
				List<HashMap<String, String>> path = result.get(i);
 
				// Fetching all the points in i-th route
				for(int j=0;j <path.size();j++)
				{
					HashMap<String,String> point = path.get(j);
					 
					double lat = Double.parseDouble(point.get("lat"));
					double lng = Double.parseDouble(point.get("lng"));
					LatLng position = new LatLng(lat, lng);
					 
					points.add(position);
					
					MarkerOptions options = new MarkerOptions();
					
					if(j == 0)
					{
						// Creating MarkerOptions
					
						
						// Setting the position of the marker
						options.position(position);
						options.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_RED));
						map.addMarker(options);
						
		                //map.animateCamera(CameraUpdateFactory.newLatLng(position));
						
					}
					
					if(j == path.size()-1 )
					{
						// Creating MarkerOptions
					
						
						// Setting the position of the marker
						options.position(position);
						options.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_BLUE));
						map.addMarker(options);
						
						//bounds  = new google.maps.LatLngBounds();
						//map.getBounds();
						
						map.moveCamera(CameraUpdateFactory.newLatLngZoom(position, 7));
					}
					
					
					
				}
 
				// Adding all the points in the route to LineOptions
				lineOptions.addAll(points);
				lineOptions.width(2);
				lineOptions.color(Color.RED);
 
			}
 
			// Drawing polyline in the Google Map for the i-th route
			map.addPolyline(lineOptions);
			
    		// arret
    		if (progressdialog.isShowing()) 
    		{
    			progressdialog.dismiss();
    		}

			
			//http://www.svennerberg.com/2008/11/bounding-box-in-google-maps/
			
			
		}


	}
 

}


class DirectionsJSONParser_bis2 
{
	 
	/** Receives a JSONObject and returns a list of lists containing latitude and longitude */
	public List<List<HashMap<String,String>>> parse(JSONObject jObject)
	{
 
		List<List<HashMap<String, String>>> routes = new ArrayList<List<HashMap<String,String>>>() ;
		JSONArray jRoutes = null;
		JSONArray jLegs = null;
		JSONArray jSteps = null;
 
		try {
 
				jRoutes = jObject.getJSONArray("routes");
 
				/** Traversing all routes */
				for(int i=0;i<jRoutes.length();i++)
				{
					jLegs = ( (JSONObject)jRoutes.get(i)).getJSONArray("legs");
					List path = new ArrayList<HashMap<String, String>>();
 
					/** Traversing all legs */
					for(int j=0;j<jLegs.length();j++)
					{
						jSteps = ( (JSONObject)jLegs.get(j)).getJSONArray("steps");
 
						/** Traversing all steps */
						for(int k=0;k<jSteps.length();k++)
						{
							String polyline = "";
							polyline = (String)((JSONObject)((JSONObject)jSteps.get(k)).get("polyline")).get("points");
							List list = decodePoly(polyline);
 
							/** Traversing all points */
							for(int l=0;l <list.size();l++)
							{
								HashMap<String, String> hm = new HashMap<String, String>();
								hm.put("lat", Double.toString(((LatLng)list.get(l)).latitude) );
								hm.put("lng", Double.toString(((LatLng)list.get(l)).longitude) );
								path.add(hm);
							}
						}
						
						routes.add(path);
					}
				}
 
		} 
		catch (JSONException e) 
		{
			e.printStackTrace();
		}catch (Exception e)
		{
		}
 
		return routes;
	}
 
	/**
	* Method to decode polyline points
	* Courtesy : http://jeffreysambells.com/2010/05/27/decoding-polylines-from-google-maps-direction-api-with-java
	* */
	private List decodePoly(String encoded) 
	{
 
			List poly = new ArrayList();
			int index = 0, len = encoded.length();
			int lat = 0, lng = 0;
			 
			while (index < len) {
			int b, shift = 0, result = 0;
			do {
			b = encoded.charAt(index++) - 63;
			result |= (b & 0x1f) << shift;
			shift += 5;
			} while (b >= 0x20);
			int dlat = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
			lat += dlat;
			 
			shift = 0;
			result = 0;
			do {
			b = encoded.charAt(index++) - 63;
			result |= (b & 0x1f) << shift;
			shift += 5;
			} while (b >= 0x20);
			int dlng = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
			lng += dlng;
			 
			LatLng p = new LatLng((((double) lat / 1E5)),
			(((double) lng / 1E5)));
			poly.add(p);
			}
			 
			return poly;
	}
}