package community.peers.internetradio.storage;

import android.app.Activity;
import android.content.SharedPreferences;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

import java.util.ArrayList;
import java.util.HashMap;

/**
 * Manage list of last played radios.
 * Store and retrieve from SharedStorage.
 */
public class Settings
{
    // Name of the property used for storing the list of radios.
    protected static final String SETTINGS_LAST_PLAYED = "last_played";

    // Name of the property used for storing the notification settings.
    protected static final String SETTINGS_PLAYER = "player_settings";

    // How many items should the "last played" list remember max.
    protected static final int MAX_ITEMS = 32;

    /**
     * Retrieve the list of "last played" radios.
     *
     * @param context
     * @return
     */
    public static ArrayList<HashMap<String, String>>
    retrieveLastPlayed (Activity context)
    {
        // Used to serialize Java objects to Json
        Gson gson = new Gson();

        // Get the app preferences
        SharedPreferences appPreferences = context.getPreferences(context.MODE_PRIVATE);

        ArrayList<HashMap<String, String>> lastStations =
                new ArrayList<HashMap<String, String>>();

        // Retrieve list of last played stations
        String lastStationsGson = appPreferences.getString(Settings.SETTINGS_LAST_PLAYED, null);

        // Convert Json to Java object
        if (lastStationsGson != null)
            lastStations = gson.fromJson(
                    lastStationsGson,
                    new TypeToken<ArrayList<HashMap<String, String>>>(){}.getType());

        return lastStations;
    }

    /**
     * Retrieve list of settings used to configure the player.
     *
     * @param context
     * @return
     */
    public static HashMap<String, Object>
    retrievePlayerSettings (Activity context)
    {
        // Used to serialize Java objects to Json
        Gson gson = new Gson();

        // Get the settings
        SharedPreferences appPreferences = context.getPreferences (context.MODE_PRIVATE);

        HashMap<String, Object> settings = new HashMap<String, Object> ();

        String settingsPreferences = appPreferences.getString (Settings.SETTINGS_PLAYER, null);

        // Convert Json to Java object
        if (settingsPreferences != null)
            settings = gson.fromJson (
                    settingsPreferences,
                    new TypeToken<HashMap<String, Object>> (){}.getType ());

        return settings;
    }

    /**
     * Retrieve list of settings used to configure the player.
     *
     * @param context
     * @return
     */
    public static void
    setPlayerOption (Activity context, String key, Object value)
    {
        // Used to serialize Java objects to Json
        Gson gson = new Gson();

        // Get the settings
        SharedPreferences appPreferences =
            context.getPreferences (context.MODE_PRIVATE);

        String settingsPreferences =
            appPreferences.getString (Settings.SETTINGS_PLAYER, null);

        // Object containing all player settings
        HashMap<String, Object> settings =
            new HashMap<String, Object> ();

        // Convert stored Json to Java object
        if (settingsPreferences != null)
            settings = gson.fromJson (
                settingsPreferences,
                new TypeToken<HashMap<String, Object>> (){}.getType ());

        // Add new setting
        settings.put (key, value);

        // Re-serialize settings and save preference
        appPreferences
            .edit ()
            .putString (Settings.SETTINGS_PLAYER, gson.toJson (settings))
            .apply ();
    }

    /**
     * Add a new station to the list of "last played" radios.
     * If the station is already stored, it will be brought to the top of
     * the list.
     *
     * @param context
     * @param aRadio
     */
    public static void
    addNewPlayedRadio(Activity context, HashMap<String, String> aRadio)
    {
        // Used to serialize Java objects to Json
        Gson gson = new Gson();

        // Get the app preferences
        SharedPreferences appPreferences = context.getPreferences(context.MODE_PRIVATE);

        // Get stations
        ArrayList<HashMap<String, String>> lastStations = Settings.retrieveLastPlayed(context);

        /**
         * Remove all previous instances of this radio.
         * NOTE: Looping the list like this is probably inefficient,
         * but should not be a problem since the list is not supposed to
         * be more than a few 10s of items.
         */
        while (lastStations.remove(aRadio));

        // Add radio at the top of list
        lastStations.add(0, aRadio);

        // Cut off list to prevent it from growing too much
        if (lastStations.size() > Settings.MAX_ITEMS)
            lastStations.subList(Settings.MAX_ITEMS, lastStations.size()).clear();

        // Re-serialize list of radios and save preference
        appPreferences
            .edit ()
            .putString (Settings.SETTINGS_LAST_PLAYED, gson.toJson(lastStations))
            .apply ();
    }

    /**
     * Delete the entire list of "last played" radios.
     *
     * @param context
     */
    public static void
    emptyLastPlayedList(Activity context)
    {
        // Get the app preferences
        SharedPreferences appPreferences = context.getPreferences(context.MODE_PRIVATE);

        // Re-serialize list of radios and save preference
        appPreferences
                .edit()
                .remove(Settings.SETTINGS_LAST_PLAYED)
                .commit();
    }

    /**
     * Is the player notification compact?
     * Compact means only the notification is shown.
     * Not compact means that there is more stuff, such as additional
     * "play/stop" buttons.
     */
    public static boolean
    isPlayerCompact(Activity context)
    {
        // Get settings
        HashMap<String, Object> settings =
                Settings.retrievePlayerSettings(context);

        if (!settings.containsKey("compact"))
            return false;

        return (boolean) settings.get("compact");
    }

    /**
     * Does the user want the player to play automatically?
     */
    public static boolean
    autoplay (Activity context)
    {
        // Get settings
        HashMap<String, Object> settings =
                Settings.retrievePlayerSettings (context);

        if (!settings.containsKey ("autoplay"))
            return false;

        return (boolean) settings.get ("autoplay");
    }

    /**
     * Store that the user wants a compact or full player.
     *
     * @param context
     * @param compact
     */
    public static void
    setPlayerCompact(Activity context, boolean compact)
    {
        // Used to serialize Java objects to Json
        Gson gson = new Gson ();

        // Get the player settings
        SharedPreferences playerPreferences =
                context.getPreferences (context.MODE_PRIVATE);

        // Get stations
        HashMap<String, Object> settings =
                Settings.retrievePlayerSettings (context);

        // Set new option
        settings.put ("compact", compact);

        // Re-serialize list of radios and save preference
        playerPreferences
            .edit()
            .putString(Settings.SETTINGS_PLAYER, gson.toJson(settings))
            .commit();
    }

    /**
     * Toggle between compact/full player.
     *
     * @param context
     */
    public static void
    togglePlayerCompact(Activity context)
    {
        Settings.setPlayerCompact(context, !Settings.isPlayerCompact(context));
    }

    /**
     * Store that the user wants to autoplay radio on app start.
     *
     * @param context
     * @param autoplay
     */
    public static void
    setAutoplay (Activity context, boolean autoplay)
    {
        Settings.setPlayerOption (context, "autoplay", autoplay);
    }

    /**
     * Toggle between autoplay on/off.
     *
     * @param context
     */
    public static void
    toggleAutoplay (Activity context)
    {
        Settings.setAutoplay (
            context, !Settings.autoplay (context));
    }
}