package com.example.Maps06;

import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.util.Log;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

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

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Color;
import android.location.Geocoder;
import android.view.Display;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

import com.google.android.gms.identity.intents.Address;
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.MapFragment;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.LatLngBounds;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
import com.google.android.gms.maps.model.Polyline;
import com.google.android.gms.maps.model.PolylineOptions;
import com.google.android.gms.vision.barcode.Barcode.GeoPoint;


import com.google.android.gms.maps.GoogleMap.OnMapLongClickListener;
import com.google.android.gms.maps.GoogleMap.OnMarkerClickListener;
import com.google.android.gms.maps.GoogleMap.OnMarkerDragListener;
import com.google.android.gms.maps.GoogleMap.OnMapClickListener;


import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONArray;
import org.json.JSONObject;

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.Polyline;
import com.google.android.gms.maps.model.PolylineOptions;

import android.app.ProgressDialog;
import android.content.Context;
import android.graphics.Color;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

// http://stackoverflow.com/questions/17425499/how-to-draw-interactive-polyline-on-route-google-maps-v2-android

public class MainActivity extends FragmentActivity
{
	
	private GoogleMap myMap;
    Polyline line;
    Context context;

    // Static LatLng
    LatLng startLatLng = new LatLng(30.707104, 76.690749);
    LatLng endLatLng = new LatLng(30.721419, 76.730017);
	
	
	private static final LatLng AMSTERDAM = new LatLng(52.37518, 4.895439);
	private static final LatLng PARIS = new LatLng(48.856132, 2.352448);
	private static final LatLng FRANKFURT = new LatLng(50.111772, 8.682632);
	private GoogleMap map;
	private SupportMapFragment fragment;
	private LatLngBounds latlngBounds;
	private Button bNavigation;
	private Polyline newPolyline;
	private boolean isTravelingToParis = false;
	private int width, height;
    
	@Override
	public void onCreate(Bundle savedInstanceState) 
	{
			super.onCreate(savedInstanceState);
			setContentView(R.layout.navigation_layout);
	
			 context = MainActivity.this;
			
			
			
			
			// GoogleMap myMap
	        myMap = ((SupportMapFragment) getSupportFragmentManager()
	                .findFragmentById(R.id.map)).getMap();
	        myMap.setMyLocationEnabled(true);
	        myMap.moveCamera(CameraUpdateFactory.newLatLng(startLatLng));
	        myMap.animateCamera(CameraUpdateFactory.zoomTo(12));
		
			bNavigation = (Button) findViewById(R.id.bNavigation);
			bNavigation.setOnClickListener(new View.OnClickListener() 
			{
				
					@Override
					public void onClick(View v) 
					{
						Toast.makeText(getApplicationContext(),"Remind",Toast.LENGTH_SHORT).show();
						
						String urlTopass = makeURL(startLatLng.latitude,
			                    startLatLng.longitude, endLatLng.latitude,
			                    endLatLng.longitude);
			            new connectAsyncTask(urlTopass).execute();
						
					}
			});
		      
			
	}
	
	/*******************************************************************************************/

	
	 private class connectAsyncTask extends AsyncTask<Void, Void, String> {
	        private ProgressDialog progressDialog;
	        String url;

	        connectAsyncTask(String urlPass) {
	            url = urlPass;
	        }

	        @Override
	        protected void onPreExecute() {
	            // TODO Auto-generated method stub
	            super.onPreExecute();
	            progressDialog = new ProgressDialog(context);
	            progressDialog.setMessage("Fetching route, Please wait...");
	            progressDialog.setIndeterminate(true);
	            progressDialog.show();
	        }

	        @Override
	        protected String doInBackground(Void... params) {
	            JSONParser jParser = new JSONParser();
	            String json = jParser.getJSONFromUrl(url);
	            return json;
	        }

	        @Override
	        protected void onPostExecute(String result) {
	            super.onPostExecute(result);
	            progressDialog.hide();
	            if (result != null) {
	                drawPath(result);
	            }
	        }
	    }
	
	
	public String makeURL(double sourcelat, double sourcelog, double destlat,
            double destlog) {
        StringBuilder urlString = new StringBuilder();
        urlString.append("http://maps.googleapis.com/maps/api/directions/json");
        urlString.append("?origin=");// from
        urlString.append(Double.toString(sourcelat));
        urlString.append(",");
        urlString.append(Double.toString(sourcelog));
        urlString.append("&destination=");// to
        urlString.append(Double.toString(destlat));
        urlString.append(",");
        urlString.append(Double.toString(destlog));
        urlString.append("&sensor=false&mode=driving&alternatives=true");
        return urlString.toString();
    }

	
	
	public class JSONParser {

        InputStream is = null;
        JSONObject jObj = null;
        String json = "";

        // constructor
        public JSONParser() {
        }

        public String getJSONFromUrl(String url) {

            // Making HTTP request
            try {
                // defaultHttpClient
                DefaultHttpClient httpClient = new DefaultHttpClient();
                HttpPost httpPost = new HttpPost(url);

                HttpResponse httpResponse = httpClient.execute(httpPost);
                HttpEntity httpEntity = httpResponse.getEntity();
                is = httpEntity.getContent();

            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            } catch (ClientProtocolException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                BufferedReader reader = new BufferedReader(
                        new InputStreamReader(is, "iso-8859-1"), 8);
                StringBuilder sb = new StringBuilder();
                String line = null;
                while ((line = reader.readLine()) != null) {
                    sb.append(line + "\n");
                }

                json = sb.toString();
                is.close();
            } catch (Exception e) {
                Log.e("Buffer Error", "Error converting result " + e.toString());
            }
            return json;

        }
    }

	
	public void drawPath(String result) {
        if (line != null) {
            myMap.clear();
        }
        myMap.addMarker(new MarkerOptions().position(endLatLng).icon(
                BitmapDescriptorFactory.fromResource(R.drawable.pin_red)));
        myMap.addMarker(new MarkerOptions().position(startLatLng).icon(
                BitmapDescriptorFactory.fromResource(R.drawable.pin_red)));
        try {
            // Tranform the string into a json object
            final JSONObject json = new JSONObject(result);
            JSONArray routeArray = json.getJSONArray("routes");
            JSONObject routes = routeArray.getJSONObject(0);
            JSONObject overviewPolylines = routes
                    .getJSONObject("overview_polyline");
            String encodedString = overviewPolylines.getString("points");
            List<LatLng> list = decodePoly(encodedString);

/*       
            for (int z = 0; z < list.size() - 1; z++) {
                LatLng src = list.get(z);
                LatLng dest = list.get(z + 1);
                line = myMap.addPolyline(new PolylineOptions()
                        .add(new LatLng(src.latitude, src.longitude),
                                new LatLng(dest.latitude, dest.longitude))
                        .width(5).color(Color.BLUE).geodesic(true));
            }

            
            PolylineOptions options = new PolylineOptions().width(5).color(Color.BLUE).geodesic(true);
            for (int z = 0; z < list.size(); z++) {
                LatLng point = list.get(z);
                options.add(point);
            }
            line = myMap.addPolyline(options);
 */           
            
            drawPolyLineOnMap(list);
            
          
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

	
	 public void drawPolyLineOnMap(List<LatLng> list) {
	        PolylineOptions polyOptions = new PolylineOptions();
	        polyOptions.color(Color.RED);
	        polyOptions.width(5);
	        polyOptions.addAll(list);
	        myMap.clear();
	        myMap.addPolyline(polyOptions);
	        LatLngBounds.Builder builder = new LatLngBounds.Builder();
	        for (LatLng latLng : list) {
	            builder.include(latLng);
	        }
	        final LatLngBounds bounds = builder.build();
	        //BOUND_PADDING is an int to specify padding of bound.. try 100.
	        CameraUpdate cu = CameraUpdateFactory.newLatLngBounds(bounds, 100);
	        myMap.animateCamera(cu);
	    }
	
	
	private List<LatLng> decodePoly(String encoded) {

        List<LatLng> poly = new ArrayList<LatLng>();
        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;
    }
	
	/*******************************************************************************************/

	@Override
	public boolean onCreateOptionsMenu(Menu menu) 
	{
			getMenuInflater().inflate(R.menu.activity_main, menu);
			return true;
	}
	
	@Override
    public boolean onOptionsItemSelected(MenuItem item) 
	{
       
		//googleMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
		//googleMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
		//googleMap.setMapType(GoogleMap.MAP_TYPE_SATELLITE);
		//googleMap.setMapType(GoogleMap.MAP_TYPE_TERRAIN);
		//googleMap.setMapType(GoogleMap.MAP_TYPE_NONE);
		
	        switch (item.getItemId())
	        {
		        case R.id.menu_remind:
		  			Toast.makeText(getApplicationContext(),"Remind",Toast.LENGTH_SHORT).show();
		  			
		  		 
		  			
		  			//map.setMapType(GoogleMap.MAP_TYPE_NORMAL);
		  		
		  			//Intent Intent04 = new Intent(MainActivity.this, NewActivity.class);
		  			//startActivity(Intent04);
			        return true;
		        
		  		case R.id.menu_repeat:
		  			Toast.makeText(getApplicationContext(),"Repeat",Toast.LENGTH_SHORT).show();
		  			
		  			//map.setMapType(GoogleMap.MAP_TYPE_SATELLITE);
		  			//Intent Intent05 = new Intent(MainActivity.this, Control_Service.class);
		  			//startActivity(Intent05);
			        return true;
			        
		  		case R.id.menu_about:
		  			Toast.makeText(getApplicationContext(),"CAbout",Toast.LENGTH_SHORT).show();
		  			//map.setMapType(GoogleMap.MAP_TYPE_TERRAIN);
			        return true;
		
		  		case R.id.menu_quit:
		  			Toast.makeText(getApplicationContext(),"Salut on ferme la boutique...",Toast.LENGTH_SHORT).show();
		  			finish();
			        return true;    
		          
		  		default:
		          return super.onOptionsItemSelected(item);
             }
    }
	
	/*******************************************************************************************/

	
}