/*
 * Copyright 2012 - 2014 Anton Tananaev (anton.tananaev@gmail.com)
 *
 * 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 org.traccar.client;

import android.annotation.TargetApi;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.location.Location;
import android.os.BatteryManager;
import android.os.Build;
import android.os.IBinder;
import android.os.PowerManager;
import android.os.PowerManager.WakeLock;
import android.preference.PreferenceManager;
import android.util.Log;

/**
 * Background service
 */
public class TrackingService extends Service {

    public static final String LOG_TAG = "Traccar.TrackingService";

    private String id;
    private String address;
    private int port;
    private int interval;
    private String provider;
    private boolean extended;

    private SharedPreferences sharedPreferences;
    private ClientController clientController;
    private PositionProvider positionProvider;
    
    private WakeLock wakeLock;

    @Override
    public void onCreate() {
        StatusActivity.addMessage(getString(R.string.status_service_create));

        PowerManager powerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);
        wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, getClass().getName());
        wakeLock.acquire();

        sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);

        try {
            id = sharedPreferences.getString(MainActivity.KEY_ID, null);
            address = sharedPreferences.getString(MainActivity.KEY_ADDRESS, null);
            provider = sharedPreferences.getString(MainActivity.KEY_PROVIDER, null);
            port = Integer.valueOf(sharedPreferences.getString(MainActivity.KEY_PORT, null));
            interval = Integer.valueOf(sharedPreferences.getString(MainActivity.KEY_INTERVAL, null));
            extended = sharedPreferences.getBoolean(MainActivity.KEY_EXTENDED, false);
        } catch (Exception error) {
            Log.w(LOG_TAG, error);
        }

        clientController = new ClientController(this, address, port, ProtocolFormatter.createLoginMessage(id));
        clientController.start();

        positionProvider = new PositionProvider(this, provider, interval * 1000, positionListener);
        positionProvider.startUpdates();

        sharedPreferences.registerOnSharedPreferenceChangeListener(preferenceChangeListener);
    }

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onDestroy() {
        StatusActivity.addMessage(getString(R.string.status_service_destroy));

        if (sharedPreferences != null) {
        	sharedPreferences.unregisterOnSharedPreferenceChangeListener(preferenceChangeListener);
        }

        if (positionProvider != null) {
        	positionProvider.stopUpdates();
        }

        if (clientController != null) {
        	clientController.stop();
        }

        wakeLock.release();
    }

    @TargetApi(Build.VERSION_CODES.ECLAIR)
    public double getBatteryLevel() {
        if (android.os.Build.VERSION.SDK_INT > Build.VERSION_CODES.ECLAIR) {
            Intent batteryIntent = registerReceiver(null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
            int level = batteryIntent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0);
            int scale = batteryIntent.getIntExtra(BatteryManager.EXTRA_SCALE, 1);
            return (level * 100.0) / scale;
        } else {
            return 0;
        }
    }

    private PositionProvider.PositionListener positionListener = new PositionProvider.PositionListener() {

        @Override
        public void onPositionUpdate(Location location) {
            if (location != null) {
                StatusActivity.addMessage(getString(R.string.status_location_update));
                clientController.setNewLocation(ProtocolFormatter.createLocationMessage(extended, location, getBatteryLevel()));
            }
        }

    };

    OnSharedPreferenceChangeListener preferenceChangeListener = new OnSharedPreferenceChangeListener() {

        @Override
        public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
            StatusActivity.addMessage(getString(R.string.status_preference_update));
            try {
                if (key.equals(MainActivity.KEY_ADDRESS)) {

                    address = sharedPreferences.getString(MainActivity.KEY_ADDRESS, null);
                    clientController.setNewServer(address, port);

                } else if (key.equals(MainActivity.KEY_PORT)) {

                    port = Integer.valueOf(sharedPreferences.getString(MainActivity.KEY_PORT, null));
                    clientController.setNewServer(address, port);

                } else if (key.equals(MainActivity.KEY_INTERVAL)) {

                    interval = Integer.valueOf(sharedPreferences.getString(MainActivity.KEY_INTERVAL, null));
                    positionProvider.stopUpdates();
                    positionProvider = new PositionProvider(TrackingService.this, provider, interval * 1000, positionListener);
                    positionProvider.startUpdates();

                } else if (key.equals(MainActivity.KEY_ID)) {

                    id = sharedPreferences.getString(MainActivity.KEY_ID, null);
                    clientController.setNewLogin(ProtocolFormatter.createLoginMessage(id));

                } else if (key.equals(MainActivity.KEY_PROVIDER)) {

                    provider = sharedPreferences.getString(MainActivity.KEY_PROVIDER, null);
                    positionProvider.stopUpdates();
                    positionProvider = new PositionProvider(TrackingService.this, provider, interval * 1000, positionListener);
                    positionProvider.startUpdates();

                } else if (key.equals(MainActivity.KEY_EXTENDED)) {

                    extended = sharedPreferences.getBoolean(MainActivity.KEY_EXTENDED, false);

                }
            } catch (Exception error) {
                Log.w(LOG_TAG, error);
            }
        }

    };

}

@@ -1510,57 +1510,8 @@
 d;%0A%0A
-    private SharedPreferences sharedPreferences;%0A
     
@@ -1549,24 +1549,24 @@
 Controller;%0A
+
     private 
@@ -1979,32 +1979,50 @@
 ire();%0A%0A        
+SharedPreferences 
 sharedPreference
@@ -2990,103 +2990,8 @@
 s();
-%0A%0A        sharedPreferences.registerOnSharedPreferenceChangeListener(preferenceChangeListener);
 %0A   
@@ -3207,157 +3207,8 @@
 );%0A%0A
-        if (sharedPreferences != null) %7B%0A        %09sharedPreferences.unregisterOnSharedPreferenceChangeListener(preferenceChangeListener);%0A        %7D%0A%0A
     
@@ -4244,32 +4244,32 @@
 ation_update));%0A
+
                 
@@ -4418,2124 +4418,6 @@
 %7D;%0A%0A
-    OnSharedPreferenceChangeListener preferenceChangeListener = new OnSharedPreferenceChangeListener() %7B%0A%0A        @Override%0A        public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) %7B%0A            StatusActivity.addMessage(getString(R.string.status_preference_update));%0A            try %7B%0A                if (key.equals(MainActivity.KEY_ADDRESS)) %7B%0A%0A                    address = sharedPreferences.getString(MainActivity.KEY_ADDRESS, null);%0A                    clientController.setNewServer(address, port);%0A%0A                %7D else if (key.equals(MainActivity.KEY_PORT)) %7B%0A%0A                    port = Integer.valueOf(sharedPreferences.getString(MainActivity.KEY_PORT, null));%0A                    clientController.setNewServer(address, port);%0A%0A                %7D else if (key.equals(MainActivity.KEY_INTERVAL)) %7B%0A%0A                    interval = Integer.valueOf(sharedPreferences.getString(MainActivity.KEY_INTERVAL, null));%0A                    positionProvider.stopUpdates();%0A                    positionProvider = new PositionProvider(TrackingService.this, provider, interval * 1000, positionListener);%0A                    positionProvider.startUpdates();%0A%0A                %7D else if (key.equals(MainActivity.KEY_ID)) %7B%0A%0A                    id = sharedPreferences.getString(MainActivity.KEY_ID, null);%0A                    clientController.setNewLogin(ProtocolFormatter.createLoginMessage(id));%0A%0A                %7D else if (key.equals(MainActivity.KEY_PROVIDER)) %7B%0A%0A                    provider = sharedPreferences.getString(MainActivity.KEY_PROVIDER, null);%0A                    positionProvider.stopUpdates();%0A                    positionProvider = new PositionProvider(TrackingService.this, provider, interval * 1000, positionListener);%0A                    positionProvider.startUpdates();%0A%0A                %7D else if (key.equals(MainActivity.KEY_EXTENDED)) %7B%0A%0A                    extended = sharedPreferences.getBoolean(MainActivity.KEY_EXTENDED, false);%0A%0A                %7D%0A            %7D catch (Exception error) %7B%0A                Log.w(LOG_TAG, error);%0A            %7D%0A        %7D%0A%0A    %7D;%0A%0A
 %7D%0A

Remove preferences listener from service