/**
 * Copyright 2009 Joe LaPenna
 */

package com.joelapenna.foursquared;

import com.joelapenna.foursquare.Foursquare;
import com.joelapenna.foursquare.error.FoursquareError;
import com.joelapenna.foursquare.error.FoursquareParseException;
import com.joelapenna.foursquare.types.Auth;
import com.joelapenna.foursquared.error.FoursquaredCredentialsError;
import com.joelapenna.foursquared.maps.BestLocationListener;

import android.app.Application;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.location.Location;
import android.location.LocationManager;
import android.preference.PreferenceManager;
import android.text.TextUtils;
import android.util.Log;
import android.view.Menu;

import java.io.IOException;
import java.util.List;

/**
 * @author Joe LaPenna (joe@joelapenna.com)
 */
public class Foursquared extends Application {
    public static final String TAG = "Foursquared";
    public static final boolean DEBUG = true;
    public static final boolean API_DEBUG = false;

    public static final int LAST_LOCATION_UPDATE_THRESHOLD = 1000 * 60 * 60;

    public static final String EXTRAS_VENUE_KEY = "venue";

    public static final String PREFERENCE_PHONE = "phone";
    public static final String PREFERENCE_PASSWORD = "password";
    public static final String PREFERENCE_TWITTER_CHECKIN = "twitter_checkin";
    public static final String PREFERENCE_SILENT_CHECKIN = "silent_checkin";

    // Hidden preferences
    public static final String PREFERENCE_EMAIL = "email";
    public static final String PREFERENCE_FIRST = "first_name";
    public static final String PREFERENCE_LAST = "last_name";
    public static final String PREFERENCE_PHOTO = "photo";

    // Common menu items
    private static final int MENU_PREFERENCES = -1;

    private LocationListener mLocationListener = new LocationListener();

    private SharedPreferences mSharedPrefs;
    private OnSharedPreferenceChangeListener mOnSharedPreferenceChangeListener;

    private Foursquare mFoursquare = new Foursquare();

    public void onCreate() {
        mSharedPrefs = PreferenceManager.getDefaultSharedPreferences(this);
        mOnSharedPreferenceChangeListener = new SharedPreferences.OnSharedPreferenceChangeListener() {
            @Override
            public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
                if (key.equals(PREFERENCE_PHONE) || key.equals(PREFERENCE_PASSWORD)) {
                    Log.d(TAG, key + " preference was changed");
                    try {
                        loadCredentials();
                    } catch (FoursquaredCredentialsError e) {
                        if (DEBUG) Log.d(TAG, "Clearing credentials", e);
                        mFoursquare.setCredentials(null, null);
                    }
                }
            }
        };
        mSharedPrefs.registerOnSharedPreferenceChangeListener(mOnSharedPreferenceChangeListener);

        try {
            loadCredentials();
        } catch (FoursquaredCredentialsError e) {
            // We're not doing anything because hopefully our related activities
            // will handle the failure. This is simply convenience.
        }
    }

    public Foursquare getFoursquare() {
        return mFoursquare;
    }

    public Location getLastKnownLocation() {
        return mLocationListener.getLastKnownLocation();
    }

    public LocationListener getLocationListener() {
        primeLocationListner();
        return mLocationListener;
    }

    private void loadCredentials() throws FoursquaredCredentialsError {
        if (DEBUG) Log.d(TAG, "loadCredentials()");
        String phoneNumber = mSharedPrefs.getString(Foursquared.PREFERENCE_PHONE, null);
        String password = mSharedPrefs.getString(Foursquared.PREFERENCE_PASSWORD, null);

        if (TextUtils.isEmpty(phoneNumber) || TextUtils.isEmpty(password)) {
            throw new FoursquaredCredentialsError(
                    "Phone number or password not set in preferences.");
        }
        mFoursquare.setCredentials(phoneNumber, password);
        try {
            if (DEBUG) Log.d(TAG, "Trying to log in.");
            Auth auth = mFoursquare.login();
            if (auth != null && auth.status()) {
                Editor editor = mSharedPrefs.edit();
                editor.putString(PREFERENCE_EMAIL, auth.getEmail());
                editor.putString(PREFERENCE_FIRST, auth.getFirstname());
                editor.putString(PREFERENCE_LAST, auth.getLastname());
                editor.putString(PREFERENCE_PHOTO, auth.getPhoto());
                editor.commit();
            }
        } catch (FoursquareError e) {
            throw new FoursquaredCredentialsError(e.getMessage());
        } catch (FoursquareParseException e) {
            throw new FoursquaredCredentialsError(e.getMessage());
        } catch (IOException e) {
            throw new FoursquaredCredentialsError(e.getMessage());
        }
    }

    private void primeLocationListner() {
        LocationManager manager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);

        Location location = null;
        List<String> providers = manager.getProviders(true);
        int providersCount = providers.size();
        for (int i = 0; i < providersCount; i++) {
            location = manager.getLastKnownLocation(providers.get(i));
            mLocationListener.getBetterLocation(location);
        }
    }

    public static void addPreferencesToMenu(Context context, Menu menu) {
        Intent intent = new Intent(context, PreferenceActivity.class);
        menu.add(Menu.NONE, MENU_PREFERENCES, Menu.NONE, R.string.preferences_label) //
                .setIcon(android.R.drawable.ic_menu_preferences).setIntent(intent);
    }

    /**
     * Used for the accuracy algorithm getBetterLocation.
     */
    public static class LocationListener extends BestLocationListener {
        @Override
        public void onLocationChanged(Location location) {
            if (DEBUG) Log.d(TAG, "onLocationChanged: " + location);
            getBetterLocation(location);
        }
    }
}

@@ -3633,24 +3633,25 @@
 LocationList
+e
 ner();%0A     
@@ -5176,16 +5176,17 @@
 tionList
+e
 ner() %7B%0A

Fix mis-spelling.