/*
 * Copyright (C) 2009 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.webkit;

import android.app.ActivityThread;
import android.content.Context;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.location.LocationProvider;
import android.os.Bundle;
import android.util.Log;
import android.webkit.WebView;
import android.webkit.WebViewCore;


/**
 * Implements the Java side of GeolocationServiceAndroid.
 */
final class GeolocationService implements LocationListener {

    // Log tag
    private static final String TAG = "geolocationService";

    private long mNativeObject;
    private LocationManager mLocationManager;
    private boolean mIsGpsEnabled;
    private boolean mIsRunning;
    private boolean mIsNetworkProviderAvailable;
    private boolean mIsGpsProviderAvailable;

    /**
     * Constructor
     * @param context The context from which we obtain the system service.
     * @param nativeObject The native object to which this object will report position updates and
     *     errors.
     */
    public GeolocationService(Context context, long nativeObject) {
        mNativeObject = nativeObject;
        // Register newLocationAvailable with platform service.
        mLocationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
        if (mLocationManager == null) {
            Log.e(TAG, "Could not get location manager.");
        }
     }

    /**
     * Start listening for location updates.
     */
    public boolean start() {
        registerForLocationUpdates();
        mIsRunning = true;
        return mIsNetworkProviderAvailable || mIsGpsProviderAvailable;
    }

    /**
     * Stop listening for location updates.
     */
    public void stop() {
        unregisterFromLocationUpdates();
        mIsRunning = false;
    }

    /**
     * Sets whether to use the GPS.
     * @param enable Whether to use the GPS.
     */
    public void setEnableGps(boolean enable) {
        if (mIsGpsEnabled != enable) {
            mIsGpsEnabled = enable;
            if (mIsRunning) {
                // There's no way to unregister from a single provider, so we can
                // only unregister from all, then reregister with all but the GPS.
                unregisterFromLocationUpdates();
                registerForLocationUpdates();
                // Check that the providers are still available after we re-register.
                maybeReportError("The last location provider is no longer available");
            }
        }
    }

    /**
     * LocationListener implementation.
     * Called when the location has changed.
     * @param location The new location, as a Location object.
     */
    public void onLocationChanged(Location location) {
        // Callbacks from the system location sevice are queued to this thread, so it's possible
        // that we receive callbacks after unregistering. At this point, the native object will no
        // longer exist.
        if (mIsRunning) {
            nativeNewLocationAvailable(mNativeObject, location);
        }
    }

    /**
     * LocationListener implementation.
     * Called when the provider status changes.
     * @param provider The name of the provider.
     * @param status The new status of the provider.
     * @param extras an optional Bundle with provider specific data.
     */
    public void onStatusChanged(String providerName, int status, Bundle extras) {
        boolean isAvailable = (status == LocationProvider.AVAILABLE);
        if (LocationManager.NETWORK_PROVIDER.equals(providerName)) {
            mIsNetworkProviderAvailable = isAvailable;
        } else if (LocationManager.GPS_PROVIDER.equals(providerName)) {
            mIsGpsProviderAvailable = isAvailable;
        }
        maybeReportError("The last location provider is no longer available");
    }

    /**
     * LocationListener implementation.
     * Called when the provider is enabled.
     * @param provider The name of the location provider that is now enabled.
     */
    public void onProviderEnabled(String providerName) {
        // No need to notify the native side. It's enough to start sending
        // valid position fixes again.
        if (LocationManager.NETWORK_PROVIDER.equals(providerName)) {
            mIsNetworkProviderAvailable = true;
        } else if (LocationManager.GPS_PROVIDER.equals(providerName)) {
            mIsGpsProviderAvailable = true;
        }
    }

    /**
     * LocationListener implementation.
     * Called when the provider is disabled.
     * @param provider The name of the location provider that is now disabled.
     */
    public void onProviderDisabled(String providerName) {
        if (LocationManager.NETWORK_PROVIDER.equals(providerName)) {
            mIsNetworkProviderAvailable = false;
        } else if (LocationManager.GPS_PROVIDER.equals(providerName)) {
            mIsGpsProviderAvailable = false;
        }
        maybeReportError("The last location provider was disabled");
    }

    /**
     * Registers this object with the location service.
     */
    private void registerForLocationUpdates() {
        try {
            // Registration may fail if providers are not present on the device.
            try {
                mLocationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, this);
                mIsNetworkProviderAvailable = true;
            } catch(IllegalArgumentException e) { }
            if (mIsGpsEnabled) {
                try {
                    mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);
                    mIsGpsProviderAvailable = true;
                } catch(IllegalArgumentException e) { }
            }
        } catch(SecurityException e) {
            Log.e(TAG, "Caught security exception registering for location updates from system. " +
                "This should only happen in DumpRenderTree.");
        }
    }

    /**
     * Unregisters this object from the location service.
     */
    private void unregisterFromLocationUpdates() {
        mLocationManager.removeUpdates(this);
        mIsNetworkProviderAvailable = false;
        mIsGpsProviderAvailable = false;
    }

    /**
     * Reports an error if neither the network nor the GPS provider is available.
     */
    private void maybeReportError(String message) {
        // Callbacks from the system location sevice are queued to this thread, so it's possible
        // that we receive callbacks after unregistering. At this point, the native object will no
        // longer exist.
        if (mIsRunning && !mIsNetworkProviderAvailable && !mIsGpsProviderAvailable) {
            nativeNewErrorAvailable(mNativeObject, message);
        }
    }

    // Native functions
    private static native void nativeNewLocationAvailable(long nativeObject, Location location);
    private static native void nativeNewErrorAvailable(long nativeObject, String message);
}
