/*
 * Copyright (C) 2010 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 com.android.calendar;

import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.text.TextUtils;
import android.text.format.DateUtils;
import android.util.Log;
import android.widget.ArrayAdapter;

import com.android.calendar.TimezoneAdapter.TimezoneRow;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Locale;
import java.util.TimeZone;

/**
 * {@link TimezoneAdapter} is a custom adapter implementation that allows you to
 * easily display a list of timezones for users to choose from. In addition, it
 * provides a two-stage behavior that initially only loads a small set of
 * timezones (one user-provided, the device timezone, and two recent timezones),
 * which can later be expanded into the full list with a call to
 * {@link #showAllTimezones()}.
 */
public class TimezoneAdapter extends ArrayAdapter<TimezoneRow> {
    private static final String TAG = "TimezoneAdapter";

    /**
     * {@link TimezoneRow} is an immutable class for representing a timezone. We
     * don't use {@link TimeZone} directly, in order to provide a reasonable
     * implementation of toString() and to control which display names we use.
     */
    public class TimezoneRow implements Comparable<TimezoneRow> {

        /** The ID of this timezone, e.g. "America/Los_Angeles" */
        public final String mId;

        /** The display name of this timezone, e.g. "Pacific Time" */
        private final String mDisplayName;

        /** The actual offset of this timezone from GMT in milliseconds */
        private final int mOffset;

        /** Whether the TZ observes daylight saving time */
        private final boolean mUseDaylightTime;

        /**
         * A one-line representation of this timezone, including both GMT offset
         * and display name, e.g. "(GMT-7:00) Pacific Time"
         */
        private String mGmtDisplayName;

        public TimezoneRow(String id, String displayName) {
            mId = id;
            mDisplayName = displayName;
            TimeZone tz = TimeZone.getTimeZone(id);
            mUseDaylightTime = tz.useDaylightTime();
            mOffset = tz.getOffset(TimezoneAdapter.this.mTime);
        }

        @Override
        public String toString() {
            if (mGmtDisplayName == null) {
                buildGmtDisplayName();
            }

            return mGmtDisplayName;
        }

        /**
         *
         */
        public void buildGmtDisplayName() {
            if (mGmtDisplayName != null) {
                return;
            }

            int p = Math.abs(mOffset);
            StringBuilder name = new StringBuilder();
            name.append("GMT");

            if (mOffset < 0) {
                name.append('-');
            } else {
                name.append('+');
            }

            name.append(p / (DateUtils.HOUR_IN_MILLIS));
            name.append(':');

            int min = p / 60000;
            min %= 60;

            if (min < 10) {
                name.append('0');
            }
            name.append(min);
            name.insert(0, "(");
            name.append(") ");
            name.append(mDisplayName);
            if (mUseDaylightTime) {
                name.append(" \u2600"); // Sun symbol
            }
            mGmtDisplayName = name.toString();
        }

        @Override
        public int hashCode() {
            final int prime = 31;
            int result = 1;
            result = prime * result + ((mDisplayName == null) ? 0 : mDisplayName.hashCode());
            result = prime * result + ((mId == null) ? 0 : mId.hashCode());
            result = prime * result + mOffset;
            return result;
        }

        @Override
        public boolean equals(Object obj) {
            if (this == obj) {
                return true;
            }
            if (obj == null) {
                return false;
            }
            if (getClass() != obj.getClass()) {
                return false;
            }
            TimezoneRow other = (TimezoneRow) obj;
            if (mDisplayName == null) {
                if (other.mDisplayName != null) {
                    return false;
                }
            } else if (!mDisplayName.equals(other.mDisplayName)) {
                return false;
            }
            if (mId == null) {
                if (other.mId != null) {
                    return false;
                }
            } else if (!mId.equals(other.mId)) {
                return false;
            }
            if (mOffset != other.mOffset) {
                return false;
            }
            return true;
        }

        @Override
        public int compareTo(TimezoneRow another) {
            if (mOffset == another.mOffset) {
                return 0;
            } else {
                return mOffset < another.mOffset ? -1 : 1;
            }
        }

    }

    private static final String KEY_RECENT_TIMEZONES = "preferences_recent_timezones";

    /** The delimiter we use when serializing recent timezones to shared preferences */
    private static final String RECENT_TIMEZONES_DELIMITER = ",";

    /** The maximum number of recent timezones to save */
    private static final int MAX_RECENT_TIMEZONES = 3;

    /**
     * Static cache of all known timezones, mapped to their string IDs. This is
     * lazily-loaded on the first call to {@link #loadFromResources(Resources)}.
     * Loading is called in a synchronized block during initialization of this
     * class and is based off the resources available to the calling context.
     * This class should not be used outside of the initial context.
     * LinkedHashMap is used to preserve ordering.
     */
    private static LinkedHashMap<String, TimezoneRow> sTimezones;

    private Context mContext;

    private String mCurrentTimezone;

    private boolean mShowingAll = false;

    private long mTime;

    private Date mDateTime;

    /**
     * Constructs a timezone adapter that contains an initial set of entries
     * including the current timezone, the device timezone, and two recently
     * used timezones.
     *
     * @param context
     * @param currentTimezone
     * @param time - needed to determine whether DLS is in effect
     */
    public TimezoneAdapter(Context context, String currentTimezone, long time) {
        super(context, android.R.layout.simple_spinner_dropdown_item, android.R.id.text1);
        mContext = context;
        mCurrentTimezone = currentTimezone;
        mTime = time;
        mDateTime = new Date(mTime);
        mShowingAll = false;
        showInitialTimezones();
    }

    /**
     * Given the ID of a timezone, returns the position of the timezone in this
     * adapter, or -1 if not found.
     *
     * @param id the ID of the timezone to find
     * @return the row position of the timezone, or -1 if not found
     */
    public int getRowById(String id) {
        TimezoneRow timezone = sTimezones.get(id);
        if (timezone == null) {
            return -1;
        } else {
            return getPosition(timezone);
        }
    }

    /**
     * Populates the adapter with an initial list of timezones (one
     * user-provided, the device timezone, and two recent timezones), which can
     * later be expanded into the full list with a call to
     * {@link #showAllTimezones()}.
     *
     * @param currentTimezone
     */
    public void showInitialTimezones() {

        // we use a linked hash set to guarantee only unique IDs are added, and
        // also to maintain the insertion order of the timezones
        LinkedHashSet<String> ids = new LinkedHashSet<String>();

        // add in the provided (event) timezone
        if (!TextUtils.isEmpty(mCurrentTimezone)) {
            ids.add(mCurrentTimezone);
        }

        // add in the device timezone if it is different
        ids.add(TimeZone.getDefault().getID());

        // add in recent timezone selections
        SharedPreferences prefs = GeneralPreferences.getSharedPreferences(mContext);
        String recentsString = prefs.getString(KEY_RECENT_TIMEZONES, null);
        if (recentsString != null) {
            String[] recents = recentsString.split(RECENT_TIMEZONES_DELIMITER);
            for (String recent : recents) {
                if (!TextUtils.isEmpty(recent)) {
                    ids.add(recent);
                }
            }
        }

        clear();

        synchronized (TimezoneAdapter.class) {
            loadFromResources(mContext.getResources());
            TimeZone gmt = TimeZone.getTimeZone("GMT");
            for (String id : ids) {
                if (!sTimezones.containsKey(id)) {
                    // a timezone we don't know about, so try to add it...
                    TimeZone newTz = TimeZone.getTimeZone(id);
                    // since TimeZone.getTimeZone actually returns a clone of GMT
                    // when it doesn't recognize the ID, this appears to be the only
                    // reliable way to check to see if the ID is a valid timezone
                    if (!newTz.equals(gmt)) {
                        final String tzDisplayName = newTz.getDisplayName(
                                newTz.inDaylightTime(mDateTime), TimeZone.LONG,
                                Locale.getDefault());
                        sTimezones.put(id, new TimezoneRow(id, tzDisplayName));
                    } else {
                        continue;
                    }
                }
                add(sTimezones.get(id));
            }
        }
        mShowingAll = false;
    }

    /**
     * Populates this adapter with all known timezones.
     */
    public void showAllTimezones() {
        List<TimezoneRow> timezones = new ArrayList<TimezoneRow>(sTimezones.values());
        Collections.sort(timezones);
        clear();
        for (TimezoneRow timezone : timezones) {
            timezone.buildGmtDisplayName();
            add(timezone);
        }
        mShowingAll = true;
    }

    /**
     * Sets the current timezone. If the adapter is currently displaying only a
     * subset of views, reload that view since it may have changed.
     *
     * @param currentTimezone the current timezone
     */
    public void setCurrentTimezone(String currentTimezone) {
        if (currentTimezone != null && !currentTimezone.equals(mCurrentTimezone)) {
            mCurrentTimezone = currentTimezone;
            if (!mShowingAll) {
                showInitialTimezones();
            }
        }
    }

    /**
     * Set the time for the adapter and update the display string appropriate
     * for the time of the year e.g. standard time vs daylight time
     *
     * @param time
     */
    public void setTime(long time) {
        if (time != mTime) {
            mTime = time;
            mDateTime.setTime(mTime);
            sTimezones = null;
            showInitialTimezones();
        }
    }

    /**
     * Saves the given timezone ID as a recent timezone under shared
     * preferences. If there are already the maximum number of recent timezones
     * saved, it will remove the oldest and append this one.
     *
     * @param id the ID of the timezone to save
     * @see {@link #MAX_RECENT_TIMEZONES}
     */
    public void saveRecentTimezone(String id) {
        SharedPreferences prefs = GeneralPreferences.getSharedPreferences(mContext);
        String recentsString = prefs.getString(KEY_RECENT_TIMEZONES, null);
        List<String> recents;
        if (recentsString == null) {
            recents = new ArrayList<String>(MAX_RECENT_TIMEZONES);
        } else {
            recents = new ArrayList<String>(
                Arrays.asList(recentsString.split(RECENT_TIMEZONES_DELIMITER)));
        }

        while (recents.size() >= MAX_RECENT_TIMEZONES) {
            recents.remove(0);
        }
        recents.add(id);
        recentsString = Utils.join(recents, RECENT_TIMEZONES_DELIMITER);
        Utils.setSharedPreference(mContext, KEY_RECENT_TIMEZONES, recentsString);
    }

    /**
     * Returns an array of ids/time zones. This returns a double indexed array
     * of ids and time zones for Calendar. It is an inefficient method and
     * shouldn't be called often, but can be used for one time generation of
     * this list.
     *
     * @return double array of tz ids and tz names
     */
    public CharSequence[][] getAllTimezones() {
        CharSequence[][] timeZones = new CharSequence[2][sTimezones.size()];
        List<String> ids = new ArrayList<String>(sTimezones.keySet());
        List<TimezoneRow> timezones = new ArrayList<TimezoneRow>(sTimezones.values());
        int i = 0;
        for (TimezoneRow row : timezones) {
            timeZones[0][i] = ids.get(i);
            timeZones[1][i++] = row.toString();
        }
        return timeZones;
    }

    private void loadFromResources(Resources resources) {
        if (sTimezones == null) {
            String[] ids = resources.getStringArray(R.array.timezone_values);
            String[] labels = resources.getStringArray(R.array.timezone_labels);

            int length = ids.length;
            sTimezones = new LinkedHashMap<String, TimezoneRow>(length);

            if (ids.length != labels.length) {
                Log.wtf(TAG, "ids length (" + ids.length + ") and labels length(" + labels.length +
                        ") should be equal but aren't.");
            }
            for (int i = 0; i < length; i++) {
                sTimezones.put(ids[i], new TimezoneRow(ids[i], labels[i]));
            }
        }
    }
}
