package com.zatackcoder.distancecalculator;

import android.content.pm.PackageManager;
import android.location.Location;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;

public class MainActivity extends AppCompatActivity implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener {


    private GoogleApiClient mGoogleApiClient = null;
    public static Double startLat = null;
    public static Double startLong = null;
    public static Double endLat = null;
    public static Double endLong = null;

    TextView msgTV, currentLatLongTV;
    Button startStopB;

    boolean started = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        initializeGoogleApi();

        msgTV = (TextView)findViewById(R.id.msgTV);
        currentLatLongTV = (TextView)findViewById(R.id.currentLatLongTV);
        startStopB = (Button)findViewById(R.id.startStopB);
        startStopB.setOnClickListener(new View.OnClickListener(){

            @Override
            public void onClick(View v) {
                if(startStopB.getText().equals("Start")) {
                    started = true;
                    msgTV.setText("Start Walking..");
                    updateStartLatLong();
                    startStopB.setText("Stop");
                } else if(startStopB.getText().equals("Stop")) {
                    started = false;
                    msgTV.append("\n\nStop Walking..");
                    updateEndLatLong();
                    msgTV.append("\n\nDistance from start location is " + getCalculatedDistance() + " Meters\n\n\n");
                    startStopB.setText("Start");
                }
            }
        });
    }

    private void initializeGoogleApi() {
        /*For Location*/
        if (mGoogleApiClient == null) {
            mGoogleApiClient = new GoogleApiClient.Builder(this)
                    .addConnectionCallbacks(this)
                    .addOnConnectionFailedListener(this)
                    .addApi(LocationServices.API)
                    .build();
        }
    }

    @Override
    protected void onStart() {
        mGoogleApiClient.connect();
        super.onStart();
    }

    @Override
    protected void onStop() {
        mGoogleApiClient.disconnect();
        super.onStop();
    }

    @Override
    public void onConnected(@Nullable Bundle bundle) {
        if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this, new String[] {android.Manifest.permission.ACCESS_FINE_LOCATION, android.Manifest.permission.ACCESS_COARSE_LOCATION}, 1);
            return;
        }

        LocationRequest mLocationRequest = new LocationRequest();
        mLocationRequest.setInterval(1000);
        mLocationRequest.setFastestInterval(500);
        mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
        LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);

        Location mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);

        if (mLastLocation != null) {
            startLat = mLastLocation.getLatitude();
            startLong = mLastLocation.getLongitude();
            currentLatLongTV.setText(startLat + ", " + startLong);
        }

    }


    @Override
    public void onConnectionSuspended(int i) {

    }

    @Override
    public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {

    }

    @Override
    public void onLocationChanged(Location location) {
        endLat = location.getLatitude();
        endLong = location.getLongitude();
        currentLatLongTV.setText(endLat + ", " + endLong);
        if(started) {
            currentLatLongTV.append("\nDistance: " + getCalculatedDistance() + " Meters");
        }
    }

    private void updateStartLatLong() {
        if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this, new String[] {android.Manifest.permission.ACCESS_FINE_LOCATION, android.Manifest.permission.ACCESS_COARSE_LOCATION}, 1);
            return;
        }

        Location mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
        if (mLastLocation != null) {
            startLat = mLastLocation.getLatitude();
            startLong = mLastLocation.getLongitude();
            msgTV.append("\nStarted From Latitude " + startLat);
            msgTV.append("\nStarted From Longitude " + startLong);
        }
    }

    private void updateEndLatLong() {
        if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this, new String[] {android.Manifest.permission.ACCESS_FINE_LOCATION, android.Manifest.permission.ACCESS_COARSE_LOCATION}, 1);
            return;
        }

        Location mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
        if (mLastLocation != null) {
            endLat = mLastLocation.getLatitude();
            endLong = mLastLocation.getLongitude();
            msgTV.append("\nStopped Latitude " + endLat);
            msgTV.append("\nStopped Longitude " + endLong);
        }
    }

    private Float getCalculatedDistance() {
        Location startLocation = new Location("Start Location");
        startLocation.setLongitude(startLong);
        startLocation.setLatitude(startLat);

        Location endLocation = new Location("End Location");
        endLocation.setLongitude(endLong);
        endLocation.setLatitude(endLat);

        Float distance = Math.abs(startLocation.distanceTo(endLocation));
        return distance;
    }

}
