package com.eegeo.location;

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;

import android.Manifest;
import android.app.Activity;
import android.content.pm.PackageManager;
import android.location.Location;
import android.os.Bundle;
import android.support.v4.content.ContextCompat;
import android.util.Log;

public class CombinedLocationApiService
        implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener
{

    private Activity m_activity;
    private static final String TAG = "CombinedLocationApiService";

    private static final long UPDATE_INTERVAL_IN_MILLISECONDS = 1000 * 5;
    private static final long FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS = 1000 * 1;
    
    private GoogleApiClient m_googleApiClient;
    private LocationRequest m_locationRequest;
    private Location m_currentLocation;
    private FusedLocationUpdateListener m_fusedLocationUpdateListener;

    public CombinedLocationApiService(Activity activity, FusedLocationUpdateListener fusedLocationUpdateListener)
    {
        this.m_activity = activity;
        this.m_fusedLocationUpdateListener = fusedLocationUpdateListener;
        startListeningToUpdates();
    }

    public void startListeningToUpdates()
    {
        buildGoogleApiClient();
    }

    private synchronized void buildGoogleApiClient()
    {
        if(ContextCompat.checkSelfPermission(m_activity,
                Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED)
        {
            return;
        }
        if(m_googleApiClient == null)
        {
            m_googleApiClient = new GoogleApiClient.Builder(m_activity).addConnectionCallbacks(this)
                    .addOnConnectionFailedListener(this).addApi(LocationServices.API).build();
        }
        createLocationRequest();
    }

    private void createLocationRequest()
    {
        if(m_locationRequest == null)
        {
            m_locationRequest = new LocationRequest();
            m_locationRequest.setInterval(UPDATE_INTERVAL_IN_MILLISECONDS);
            m_locationRequest.setFastestInterval(FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS);
            m_locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
        }
        if(!m_googleApiClient.isConnected() && !m_googleApiClient.isConnecting())
            m_googleApiClient.connect();
    }

    private void startLocationUpdates()
    {
        if(m_googleApiClient.isConnected()) {
            LocationServices.FusedLocationApi.requestLocationUpdates(m_googleApiClient, m_locationRequest, this);
        }
    }

    protected void stopLocationUpdates()
    {
        if(m_googleApiClient != null)
        {
            if(m_googleApiClient.isConnected()) {
                LocationServices.FusedLocationApi.removeLocationUpdates(m_googleApiClient, this);
                m_googleApiClient.disconnect();
            }
            m_googleApiClient = null;
            m_locationRequest = null;
            m_currentLocation = null;
        }
    }

    @Override
    public void onConnected(Bundle connectionHint)
    {
        if(m_googleApiClient == null)
        {
            buildGoogleApiClient();
        }

        Log.v(TAG, "Connected to GoogleApiClient");
        if(m_currentLocation == null)
        {
            m_currentLocation = LocationServices.FusedLocationApi.getLastLocation(m_googleApiClient);
            if(this.m_fusedLocationUpdateListener != null && m_currentLocation != null)
            {
                this.m_fusedLocationUpdateListener.onFusedLocationChanged(m_currentLocation);
            }
        }
        startLocationUpdates();
    }

    @Override
    public void onLocationChanged(Location location)
    {
        Log.v(TAG, "onLocationChanged , " + location.getLatitude() + " : " + location.getLongitude());
        m_currentLocation = location;
        if(this.m_fusedLocationUpdateListener != null)
        {
            this.m_fusedLocationUpdateListener.onFusedLocationChanged(m_currentLocation);
        }
    }

    @Override
    public void onConnectionSuspended(int cause)
    {
        Log.v(TAG, "Connection suspended");
        m_googleApiClient.connect();
    }

    @Override
    public void onConnectionFailed(ConnectionResult result)
    {
        Log.v(TAG, "Connection failed: ConnectionResult.getErrorCode() = " + result.getErrorCode());
    }

    public interface FusedLocationUpdateListener
    {
        public void onFusedLocationChanged(Location location);
    }
}

@@ -2491,16 +2491,61 @@
       if
+(m_googleApiClient != null) %7B%0A            if 
 (!m_goog
@@ -2612,32 +2612,36 @@
 ())%0A            
+ 
+   
 m_googleApiClien
@@ -2645,32 +2645,42 @@
 ient.connect();%0A
+        %7D%0A
     %7D%0A%0A    priva
@@ -2736,32 +2736,77 @@
 _googleApiClient
+ != null) %7B%0A            if (m_googleApiClient
 .isConnected()) 
@@ -2799,32 +2799,36 @@
 sConnected()) %7B%0A
+    
             Loca
@@ -2917,32 +2917,46 @@
 Request, this);%0A
+            %7D%0A
         %7D%0A    %7D%0A
@@ -3554,24 +3554,68 @@
 %0A        %7D%0A%0A
+        if(m_googleApiClient != null) %7B%0A    
         Log.
@@ -3650,24 +3650,28 @@
 piClient%22);%0A
+    
         if(m
@@ -3668,16 +3668,17 @@
       if
+ 
 (m_curre
@@ -3692,35 +3692,31 @@
 ion == null)
-%0A    
+ %7B%0A
     
-%7B%0A
             
@@ -3809,34 +3809,39 @@
 t);%0A            
+   
+ 
 if
+ 
 (this.m_fusedLoc
@@ -3901,23 +3901,17 @@
 ull)
-%0A      
+ %7B%0A
       
-%7B%0A
     
@@ -3912,34 +3912,32 @@
                 
-  
 this.m_fusedLoca
@@ -4006,34 +4006,40 @@
             
-%7D%0A
+    %7D%0A  
         
 %7D%0A        st
@@ -4026,26 +4026,31 @@
         
-%7D%0A
+  %7D%0A   
         
 startLoc
@@ -4037,24 +4037,25 @@
 %0A           
+ 
 startLocatio
@@ -4058,32 +4058,42 @@
 ationUpdates();%0A
+        %7D%0A
     %7D%0A%0A    @Over
@@ -4578,24 +4578,69 @@
 uspended%22);%0A
+%0A        if(m_googleApiClient != null) %7B%0A    
         m_go
@@ -4660,24 +4660,34 @@
 .connect();%0A
+        %7D%0A
     %7D%0A%0A    @

Fix for [MPLY-8735] - several places where m_googleApiClient was being accessed without checking its existence, and its existence is not guaranteed by the buildGoogleApiClient() function.