package com.example.geo_api13;

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 org.json.JSONArray;
import org.json.JSONObject;

import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.graphics.Color;
import android.location.Address;
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.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AutoCompleteTextView;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.TextView;
import android.widget.Toast;

import com.google.android.gms.maps.CameraUpdate;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
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.MarkerOptions;
import com.google.android.gms.maps.model.PolylineOptions;


import com.google.android.gms.maps.model.LatLng;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

// [{   "error_message" : "You have exceeded your daily request quota for this API.",   "predictions" : [],   "status" : "OVER_QUERY_LIMIT"}]

public class MainActivity extends FragmentActivity 
{

	AutoCompleteTextView atvPlaces;
	AutoCompleteTextView arrivalPlaces;
	    
	PlacesTask_departure placesTask_departure;
	ParserTask_departure parserTask_departure;
		
	PlacesTask_destination placesTask_destination;
	ParserTask_destination parserTask_destination;

	static GoogleMap map;
	
	AutoCompleteTextView depart;
	AutoCompleteTextView arrive;
	
	String departure = "";
	String arrival = "";

	static String global_departure = "";
	static String global_arrival = "";
	static String global_data = "";
	
	static ArrayList<LatLng> locations = new ArrayList();
	
	private ProgressDialog progressdialog;
	
	static String distance = "";
	static String duration = "";	
	

	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;
	TextView tvDistanceDuration;
	

	ArrayList<String> names;
    JSONObject json;
    String url;
  
    ArrayAdapter<String> adapter;
	
	@Override
	protected void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
	
		SupportMapFragment mapFragment = (SupportMapFragment)getSupportFragmentManager().findFragmentById(R.id.map); 
		
		map = mapFragment.getMap();
		
		map.setMyLocationEnabled(true);		
		map.setIndoorEnabled(true);
		map.getUiSettings().setZoomControlsEnabled(true);
		map.getUiSettings().setMyLocationButtonEnabled(true);
		map.getUiSettings().setCompassEnabled(true);
		map.getUiSettings().setAllGesturesEnabled(true);
		
		fonctions();
		
	}
		
	public void fonctions()
	{

			Toast.makeText(getApplicationContext(), "DEBUG 13...", Toast.LENGTH_LONG).show();
		
		    depart = (AutoCompleteTextView) findViewById(R.id.departure_places);
	        depart.setThreshold(5);
	        
	        arrive = (AutoCompleteTextView) findViewById(R.id.arrival_places);
	        arrive.setThreshold(5);
	        
	        depart.addTextChangedListener(new TextWatcher()
	        {
	        	 
		            @Override
		            public void onTextChanged(CharSequence s, int start, int before, int count)
		            {
		            	placesTask_departure = new PlacesTask_departure();
		            	placesTask_departure.execute(s.toString());
		            }
		 
		            @Override
		            public void beforeTextChanged(CharSequence s, int start, int count, int after)
		            {
		                
		            }
		 
		            @Override
		            public void afterTextChanged(Editable s) 
		            {
		              
		            }
	        });
	        
	        arrive.addTextChangedListener(new TextWatcher()
	        {
	        	 
		            @Override
		            public void onTextChanged(CharSequence s, int start, int before, int count)
		            {
		            	placesTask_destination = new PlacesTask_destination();
		            	placesTask_destination.execute(s.toString());
		            }
		 
		            @Override
		            public void beforeTextChanged(CharSequence s, int start, int count, int after)
		            {
		                
		            }
		 
		            @Override
		            public void afterTextChanged(Editable s) 
		            {
		              
		            }
	        });
	
			
		btn_direction = (Button) findViewById(R.id.btn_calculation);
    	btn_direction.setOnClickListener(new View.OnClickListener() 
        {
                @Override
                public void onClick(View v) 
                {
                	
                	
                		if (depart.getText().toString().isEmpty() || arrive.getText().toString().isEmpty())
                        {
                            Toast.makeText(getApplicationContext(), "Text fields cannot be empty", Toast.LENGTH_SHORT).show();
                        } 
                        else 
                        {
                        	
                      
                        	departure = depart.getText().toString();
                        	arrival = arrive.getText().toString();
                        	
                        	ArrayList<String> list=new ArrayList<String>();  
                        	
                        	departure = departure.replaceAll(",", " ");
                        	arrival = arrival.replaceAll(",", " ");
                        	
                        	
                        	list.add(departure);  
                        	list.add(arrival);  
                        	
                        	map.clear();
                        	
                        	new GeocoderTask().execute(list);
                        	
                        	//new Task().execute(list);
                        }	
                	
                }
        });
		
	}
	
	/************** Asynchron class ******************/
	
	private class GeocoderTask extends AsyncTask< ArrayList<String>, Void, String >
    {
 
		//http://www.androidtrainee.com/driving-distance-and-travel-time-duration-between-two-locations-in-google-map-android-api-v2/
		
		Context mContext;
		String str_departure = "";
	 	String str_destination = "";
		
        @Override
        protected String  doInBackground(ArrayList<String>... passing) 
        {
            	
        		List<Address> addresses_departure = null;
            	List<Address> addresses_destination = null;
            
            	ArrayList<String> tmp_array = passing[0]; 
            	String local_departure = tmp_array.get(0);
            	String local_destination = tmp_array.get(1);
            	
            	find_location_info(local_departure);
            	find_location_info(local_destination);
            	
            	double lat1 = MainActivity.locations.get(0).latitude;
            	double lng1 = MainActivity.locations.get(0).longitude;
            	String str_origin = "origin=" +lat1 + "," + lng1;

    	        double lat2 = MainActivity.locations.get(1).latitude;
            	double lng2 = MainActivity.locations.get(1).longitude;
    	        String str_dest = "destination=" + lat2 + "," + lng2;

    	        String sensor = "sensor=false";

    	        String parameters = str_origin + "&" + str_dest + "&" + sensor;
    	        String output = "json";
    	        String strUrl = "https://maps.googleapis.com/maps/api/directions/" + output + "?" + parameters;
            	
            	
//            	 String strUrl = "https://maps.googleapis.com/maps/api/directions/json?origin=48.856614,2.3522219&destination=48.390394,-4.486076&sensor=false";
            	
    	        String data = "";
    	        InputStream iStream = null;
    	        HttpURLConnection urlConnection = null;
    	        try 
    	        {
    	            URL _url = new URL(strUrl);
    	            urlConnection = (HttpURLConnection) _url.openConnection();
    	            urlConnection.connect();
    	            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();
    	            
    	            MainActivity.global_data = sb.toString();
    	            
    	            Log.d("downloadUrl", data.toString());
    	            br.close();

    	        } 
    	        catch (Exception e) 
    	        {
    	            Log.d("Exception", e.toString());
    	        } 
    	        finally 
    	        {
    	            try
    	            {
						iStream.close();
					} 
    	            catch (IOException e)
    	            {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
    	            urlConnection.disconnect();
    	        }
            	
    	        
    	        /*******************************************/
    	        
/*    	        
    	    	try {
					JSONObject jsonObject = new JSONObject(data);
				} catch (JSONException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
*/    	        
    	        
    	        /******************************************/
    	        
    	        
/*
				JSONObject jsonObject = null;
				try {
					jsonObject = new JSONObject(data);
				} catch (JSONException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				
				JSONArray jsonArray = null;
				try {
					jsonArray = (JSONArray) jsonObject.get("results");
				} catch (JSONException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
*/            
				
				JSONObject jObject;
				List<List<HashMap<String, String>>> routes = null;
	 
				try
				{
					jObject = new JSONObject(data);
					DirectionsJSONParser parser = new DirectionsJSONParser();
				 
					// Starts parsing data
					routes = parser.parse(jObject);
					
					List<HashMap<String, String>> path = routes.get(0);
					HashMap<String,String> point = path.get(0);
					distance = (String)point.get("distance");		
					
					// path = routes.get(0);
					point = path.get(1);
					duration = (String)point.get("duration");	
				}
				catch(Exception e)
				{
					e.printStackTrace();
				}
            	
            	return data;
          
        }
        
        
        @Override
    	protected void onPreExecute() 
        {
        		progressdialog = new ProgressDialog(MainActivity.this);
        		progressdialog.setMessage("Calcul du trajet");
        		progressdialog.setTitle("Please Wait...");
        		progressdialog.show();
    	}
 
        @Override
        protected void onPostExecute(String data)
        {
        		draw_direction(data);
        	    draw_markers();
        	    
        		if(progressdialog.isShowing()) 
        		{
        			progressdialog.dismiss();
        			String str = distance +" " + duration;
                    Toast.makeText(getApplicationContext(), str , Toast.LENGTH_SHORT).show();
        			locations.clear();
                    
        		}
        }
	
        private void find_location_info(String place ) 
        {
		
        		String url = "https://maps.googleapis.com/maps/api/geocode/json?";					
		
        		try 
				{
					place = URLEncoder.encode(place, "utf-8");
				} 
				catch (UnsupportedEncodingException e)
				{
					e.printStackTrace();
				}
		
				String address = "address=" + place;
				String sensor = "sensor=false";
				String strurl = url + address + "&" + sensor;
		
				String data = "";
				InputStream iStream = null;
				HttpURLConnection urlConnection = null;
	        
				try
				{
					URL _url = new URL(strurl);
					urlConnection = (HttpURLConnection) _url.openConnection();
					urlConnection.connect();
					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();
	                
					JSONObject jsonObject = new JSONObject(data);
					JSONArray jsonArray = (JSONArray) jsonObject.get("results");
                    
					if (jsonArray.length() > 0) 
					{
						jsonObject = (JSONObject) jsonArray.get(0);
		                jsonObject = (JSONObject) jsonObject.get("geometry");
		                JSONObject location = (JSONObject) jsonObject.get("location");
		                Double lat = (Double) location.get("lat");
		                Double lng = (Double) location.get("lng");
		                System.out.println("lat - " + lat + " , lon - " + lng);
		                locations.add(new LatLng(lat, lng));
					}
				}
	        
				catch(Exception e)
				{
					Log.d("Exception while downloading url", e.toString());
				}
	        
				finally
				{
					try
				    {
						iStream.close();
					} 
				    catch (IOException e) 
				    {
				    	e.printStackTrace();
					}
				    urlConnection.disconnect();
				}
		
		}
	
		private void draw_direction(String data)
		{
    	 		JSONObject jObject;
         		List<List<HashMap<String, String>>> routes = null;

         		try 
         		{
         			jObject = new JSONObject(data);
         			Log.d("ParserTask",data.toString());
         			DataParser parser = new DataParser();
         			Log.d("ParserTask", parser.toString());
		
         			routes = parser.parse(jObject);
         			Log.d("ParserTask","Executing routes");
         			Log.d("ParserTask",routes.toString());

         		} 
         		catch (Exception e)
         		{
             		Log.d("ParserTask",e.toString());
             		e.printStackTrace();
         		}
         
         		ArrayList<LatLng> points;
         		PolylineOptions lineOptions = null;

			    for (int i = 0; i < routes.size(); i++)
			    {
			    	points = new ArrayList<>();
			        lineOptions = new PolylineOptions();
			
			        List<HashMap<String, String>> path = routes.get(i);
			
			        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);
			         }
			
			         lineOptions.addAll(points);
			         lineOptions.width(2); // 10
			         lineOptions.color(Color.RED);
			
			         Log.d("onPostExecute","onPostExecute lineoptions decoded");
			
			    }
        
			    if(lineOptions != null) 
			    {
			       	MainActivity.map.addPolyline(lineOptions);
			    }
			    else 
			    {
			      	Log.d("onPostExecute","without Polylines drawn");
			    }
       
		}
	
		private void draw_markers()
		{
				
				MarkerOptions options = new MarkerOptions();
				
				LatLng position =  MainActivity.locations.get(0);
				options.position(position);
				Double a = position.latitude;
				Double b = position.longitude;
				String str1 = String.valueOf(a);
				String str2 = String.valueOf(b);
				String title = departure + " (dιpart)";  
				options.title(title);
				String infos = str1 + " " + str2; 
				options.snippet(infos);
				options.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_RED));
				MainActivity.map.addMarker(options);
					
				position =  MainActivity.locations.get(1);
				options.position(position);
				a = position.latitude;
				b = position.longitude;
				str1 = String.valueOf(a);
				str2 = String.valueOf(b);
				title = arrival + " (arrivιe)";
				options.title(title);
				infos = str1 + " " + str2; 
				options.snippet(infos);
				options.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_BLUE));
				MainActivity.map.addMarker(options);
					
		}
    
    }
	
	private class Task extends AsyncTask< ArrayList<String>, Void, String >
    {
 
		
		Context mContext;
		String str_departure = "";
	 	String str_destination = "";
		
        @Override
        protected String  doInBackground(ArrayList<String>... passing) 
        {
            	
            	String strUrl = "https://maps.googleapis.com/maps/api/directions/json?origin=48.856614,2.3522219&destination=48.390394,-4.486076&sensor=false";
            	
    	        String data = "";
    	        InputStream iStream = null;
    	        HttpURLConnection urlConnection = null;
    	        
    	        try 
    	        {
    	            URL _url = new URL(strUrl);
    	            urlConnection = (HttpURLConnection) _url.openConnection();
    	            urlConnection.connect();
    	            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();
    	            
    	            MainActivity.global_data = sb.toString();
    	            
    	            Log.d("downloadUrl", data.toString());
    	            br.close();

    	        } 
    	        catch (Exception e) 
    	        {
    	            Log.d("Exception", e.toString());
    	        } 
    	        finally 
    	        {
    	            try
    	            {
						iStream.close();
					} 
    	            catch (IOException e)
    	            {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
    	            urlConnection.disconnect();
    	        }
            	
				
				JSONObject jObject;
				List<List<HashMap<String, String>>> routes = null;
	 
				try
				{
					jObject = new JSONObject(data);
					JSONParser parser = new JSONParser();
					routes = parser.parse(jObject);
				}
				catch(Exception e)
				{
					e.printStackTrace();
				}
            	
            	return data;
          
        }
        
        
        @Override
    	protected void onPreExecute() 
        {
        		progressdialog = new ProgressDialog(MainActivity.this);
        		progressdialog.setMessage("Calcul du trajet");
        		progressdialog.setTitle("Please Wait...");
        		progressdialog.show();
    	}
 
        @Override
        protected void onPostExecute(String data)
        {
        	
        	    
        		if(progressdialog.isShowing()) 
        		{
        			progressdialog.dismiss();
        			String str = distance +" " + duration;
                    Toast.makeText(getApplicationContext(), str , Toast.LENGTH_SHORT).show();
        			locations.clear();
                    
        		}
        		
        		
        		
        		
        		
        }
	
        
	
		
	
		
		
		// http://www.androidhive.info/2012/01/android-json-parsing-tutorial/
/*		
		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");

		      
		        for(int i=0;i<jRoutes.length();i++){            
		            jLegs = ( (JSONArray)jRoutes.get(i)).getJSONArray("legs");
		            List path = new ArrayList<HashMap<String, String>>();

		            
		            for(int j=0;j<jLegs.length();j++){
		                jSteps = ( (JSONArray)jLegs.get(j)).getJSONArray("steps");

		                for(int k=0;k<jSteps.length();k++){

		                    String html_instructions = jSteps.get(k).getString("html_instructions");
		                    String travel_mode = jSteps.get(k).getString("travel_mode");
		                    String maneuver = jSteps.get(k).getString("maneuver");

		                    String distance_text = jSteps.get(k).getJSONObject("distance").getString("text");
		                    String distance_value = jSteps.get(k).getJSONObject("distance").getString("value");

		                    String duration_text = jSteps.get(k).getJSONObject("duration").getString("text");
		                    String duration_value = jSteps.get(k).getJSONObject("duration").getString("value");

		                    String start_lat = jSteps.get(k).getJSONObject("start_location").getString("lat");
		                    String start_lon = jSteps.get(k).getJSONObject("start_location").getString("lng");

		                    String end_lat = jSteps.get(k).getJSONObject("end_location").getString("lat");
		                    String end_lon = jSteps.get(k).getJSONObject("end_location").getString("lng");

		                    String polyline = "";
		                    polyline = (String)((JSONObject)((JSONObject)jSteps.get(k)).get("polyline")).get("points");
		                    List<LatLng> list = decodePoly(polyline);


		                  
		                    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;
		} 
		
*/		
		
    
    }
	
	
	
	

	/************** autocomplete departure ******************/
	
	private String downloadUrl_departure(String strUrl) throws IOException
	{
        String data = "";
        InputStream iStream = null;
        HttpURLConnection urlConnection = null;
        
        try
        {
        	URL url = new URL(strUrl);                

            urlConnection = (HttpURLConnection) url.openConnection();
            urlConnection.connect();

            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;
     }	
	
	 private class PlacesTask_departure extends AsyncTask<String, Void, String>
	 {
		@Override
		protected String doInBackground(String... place)
		{
				// For storing data from web service
				String data = "";
				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";			
				
				String parameters = input+"&"+types+"&"+sensor+"&key="+key;
				parameters = input+"&"+types+"&"+sensor+"&key="+key+"&components=country:FR";

				//Change input+&+types+&+sensor+&+key; ==> input+&+types+&+sensor+&key=+key;
				
				String output = "json";
				String url = "https://maps.googleapis.com/maps/api/place/autocomplete/"+output+"?"+parameters;
				
				//url = "https://maps.googleapis.com/maps/api/place/autocomplete/json?input=Vict&types=geocode&language=fr&key=AIzaSyBXw9vydHGGjBOYSeM9i-Xh8f9Mk0xzg1k";
		
				try
				{
					data = downloadUrl_departure(url);
				}
				catch(Exception e)
				{
	                Log.d("Background Task",e.toString());
				}
				
				return data;		
				
				//  "error_message" : "This API project is not authorized to use this API. Please ensure this API is activated in the Google Developers Console: https://console.developers.google.com/apis/api/places_backend?project=_",   "predictions" : [],   "status" : "REQUEST_DENIED"}
		}
			
		@Override
		protected void onPostExecute(String result) 
		{			
				super.onPostExecute(result);
				
				// Creating ParserTask
				parserTask_departure = new ParserTask_departure();
				
				// Starting Parsing the JSON string returned by Web Service
				parserTask_departure.execute(result);
		}		
	}
	
	
	private class ParserTask_departure 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
					depart.setAdapter(adapter);
			}			
	}    
	
		/************** autocomplete destination ******************/
	
	
	    private String downloadUrl_destination(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;
	    }	
	
		private class PlacesTask_destination extends AsyncTask<String, Void, String>
		{

			@Override
			protected String doInBackground(String... place) 
			{
				String data = "";
				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="+key;
				parameters = input+"&"+types+"&"+sensor+"&key="+key+"&components=country:FR";

				//Change input+&+types+&+sensor+&+key; ==> input+&+types+&+sensor+&key=+key;
				
				// Output format
				String output = "json";
				
				// Building the url to the web service
				String url = "https://maps.googleapis.com/maps/api/place/autocomplete/"+output+"?"+parameters;
				
				//url = "https://maps.googleapis.com/maps/api/place/autocomplete/json?input=Vict&types=geocode&language=fr&key=AIzaSyBXw9vydHGGjBOYSeM9i-Xh8f9Mk0xzg1k";
		
				try
				{
					// Fetching the data from web service in background
					data = downloadUrl_destination(url);
				}
				catch(Exception e)
				{
	                Log.d("Background Task",e.toString());
				}
				return data;		
				
				//  "error_message" : "This API project is not authorized to use this API. Please ensure this API is activated in the Google Developers Console: https://console.developers.google.com/apis/api/places_backend?project=_",   "predictions" : [],   "status" : "REQUEST_DENIED"}
			}
			
			@Override
			protected void onPostExecute(String result) 
			{			
				super.onPostExecute(result);
				
				// Creating ParserTask
				parserTask_destination = new ParserTask_destination();
				
				// Starting Parsing the JSON string returned by Web Service
				parserTask_destination.execute(result);
			}		
		}
		
	
		/** A class to parse the Google Places in JSON format */
	    private class ParserTask_destination 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
					arrive.setAdapter(adapter);
			}			
	    }    
	
	
}

/**********  fin de la classe principale *************/

	class DataParser 
	{

		/** 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<>() ;
			JSONArray jRoutes;
			JSONArray jLegs;
			JSONArray jSteps;

			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<>();

					/** 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<LatLng> list = decodePoly(polyline);

							/** Traversing all points */
							for(int l=0;l<list.size();l++)
							{
								HashMap<String, String> hm = new HashMap<>();
								hm.put("lat", Double.toString((list.get(l)).latitude) );
								hm.put("lng", Double.toString((list.get(l)).longitude) );
								path.add(hm);
							}
						}
						
						routes.add(path);
					}
				}

			} 
			catch (JSONException e) 
			{
				e.printStackTrace();
			}
			catch (Exception e)
			{
			}

			return routes;
		}

  
		private List<LatLng> decodePoly(String encoded) 
		{

			List<LatLng> 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;
		}

	}


	/************ traitement *********************/
	
	class DirectionsJSONParser 
	{
		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;	
			JSONObject jDistance = null;
			JSONObject jDuration = null;
			
			try 
			{			
				
				jRoutes = jObject.getJSONArray("routes");
				
				for(int i=0;i<jRoutes.length();i++)
				{			
					jLegs = ( (JSONObject)jRoutes.get(i)).getJSONArray("legs");				
					
					List<HashMap<String, String>> path = new ArrayList<HashMap<String, String>>();				
					
					/** Traversing all legs */
					for(int j=0;j<jLegs.length();j++)
					{
						/** Getting distance from the json data */
						jDistance = ((JSONObject) jLegs.get(j)).getJSONObject("distance");
						HashMap<String, String> hmDistance = new HashMap<String, String>();
						hmDistance.put("distance", jDistance.getString("text"));
						
						/** Getting duration from the json data */
						jDuration = ((JSONObject) jLegs.get(j)).getJSONObject("duration");
						HashMap<String, String> hmDuration = new HashMap<String, String>();
						hmDuration.put("duration", jDuration.getString("text"));
						
						/** Adding distance object to the path */
						path.add(hmDistance);
						
						/** Adding duration object to the path */
						path.add(hmDuration);					
						
						jSteps = ( (JSONObject)jLegs.get(j)).getJSONArray("steps");
						
					}
					routes.add(path);
				}
				
			} 
			catch (JSONException e) 
			{			
				e.printStackTrace();
			}
			catch (Exception e)
			{			
			}
			
			return routes;
		}
		
	}
	
	
	
	// https://tutel.me/c/codereview/questions/167657/google+maps+directions+api
	
	// https://www.javaworld.com.tw/jute/post/view?bid=26&id=316739
	
	class JSONParser 
	{
		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;	
			JSONObject jDistance = null;
			JSONObject jDuration = null;
			
			try 
			{			
				
				jRoutes = jObject.getJSONArray("routes");
				
				for(int i=0;i<jRoutes.length();i++)
				{			
					jLegs = ( (JSONObject)jRoutes.get(i)).getJSONArray("legs");				
					
					List<HashMap<String, String>> path = new ArrayList<HashMap<String, String>>();				
					
					 List xxxpath = new ArrayList<HashMap<String, String>>();
					 
					/** Traversing all legs */
					for(int j=0;j<jLegs.length();j++)
					{
						
						 jSteps = ( (JSONObject)jLegs.get(j)).getJSONArray("steps");		
						
						 for(int k=0;k<jSteps.length();k++)
						 {
							 
							 jDistance = ((JSONObject) jSteps.get(j)).getJSONObject("html_instructions");
							 
							 jDistance.getString("travel_mode");
			                   // String travel_mode = jSteps.get(k).getString("travel_mode");
			                   // String maneuver = jSteps.get(k).getString("maneuver");
						 }
						 
						
						
					}
					
				}
				
			} 
			catch (JSONException e) 
			{			
				e.printStackTrace();
			}
			catch (Exception e)
			{			
			}
			
			return routes;
		}
		
	}
	
	
	
	