/*
 * Copyright (C) 2017 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.support.v17.leanback.widget.picker;

import android.content.Context;
import android.content.res.TypedArray;
import android.support.v17.leanback.R;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Locale;

/**
 * {@link TimePicker} is a direct subclass of {@link Picker}.
 * <p>
 * This class is a widget for selecting time and displays it according to the formatting for the
 * current system locale. The time can be selected by hour, minute, and AM/PM picker columns.
 * The AM/PM mode is activated only when the 12 hour format is desired by setting
 * {@code is24HourFormat} attribute to false. Otherwise, TimePicker displays only two columns for a
 * 24 hour time format.
 * <p>
 * This widget can show the current time as the initial value if {@code useCurrentTime} is set to
 * true. Each individual time picker field can be set  set at any time by calling
 * {@link #setHour(int)}, {@link #setMinute(int)} using 24-hour time format. The time format can
 * also be changed at any time by calling {@link #setIs24Hour(boolean)}, and the AM/PM picker column
 * will be activated or deactivated according to the given format.
 *
 * @attr ref R.styleable#lbTimePicker_is24HourFormat
 * @attr ref R.styleable#lbTimePicker_useCurrentTime
 */
public class TimePicker extends Picker {

    static final String TAG = "TimePicker";

    private static final int AM_INDEX = 0;
    private static final int PM_INDEX = 1;

    private static final int HOURS_IN_HALF_DAY = 12;
    PickerColumn mHourColumn;
    PickerColumn mMinuteColumn;
    PickerColumn mAmPmColumn;
    private ViewGroup mPickerView;
    private View mAmPmSeparatorView;
    int mColHourIndex;
    int mColMinuteIndex;
    int mColAmPmIndex;

    private final PickerUtility.TimeConstant mConstant;

    private boolean mIs24hFormat;

    private int mCurrentHour;
    private int mCurrentMinute;
    private int mCurrentAmPmIndex;

    /**
     * Constructor called when inflating a TimePicker widget. This version uses a default style of
     * 0, so the only attribute values applied are those in the Context's Theme and the given
     * AttributeSet.
     *
     * @param context the context this TimePicker widget is associated with through which we can
     *                access the current theme attributes and resources
     * @param attrs the attributes of the XML tag that is inflating the TimePicker widget
     */
    public TimePicker(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    /**
     * Constructor called when inflating a TimePicker widget.
     *
     * @param context the context this TimePicker widget is associated with through which we can
     *                access the current theme attributes and resources
     * @param attrs the attributes of the XML tag that is inflating the TimePicker widget
     * @param defStyleAttr An attribute in the current theme that contains a reference to a style
     *                     resource that supplies default values for the widget. Can be 0 to not
     *                     look for defaults.
     */
    public TimePicker(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        mConstant = PickerUtility.getTimeConstantInstance(Locale.getDefault(),
                context.getResources());

        setSeparator(mConstant.timeSeparator);
        mPickerView = (ViewGroup) findViewById(R.id.picker);
        final TypedArray attributesArray = context.obtainStyledAttributes(attrs,
                R.styleable.lbTimePicker);
        mIs24hFormat = attributesArray.getBoolean(R.styleable.lbTimePicker_is24HourFormat, false);
        boolean useCurrentTime = attributesArray.getBoolean(R.styleable.lbTimePicker_useCurrentTime,
                true);

        updateColumns(getTimePickerFormat());

        // The column range for the minute and AM/PM column is static and does not change, whereas
        // the hour column range can change depending on whether 12 or 24 hour format is set at
        // any given time.
        updateHourColumn(false);
        updateMin(mMinuteColumn, 0);
        updateMax(mMinuteColumn, 59);

        updateMin(mAmPmColumn, 0);
        updateMax(mAmPmColumn, 1);

        updateAmPmColumn();

        if (useCurrentTime) {
            Calendar currentDate = PickerUtility.getCalendarForLocale(null,
                    mConstant.locale);
            setHour(currentDate.get(Calendar.HOUR_OF_DAY));
            setMinute(currentDate.get(Calendar.MINUTE));
        }
    }

    private static boolean updateMin(PickerColumn column, int value) {
        if (value != column.getMinValue()) {
            column.setMinValue(value);
            return true;
        }
        return false;
    }

    private static boolean updateMax(PickerColumn column, int value) {
        if (value != column.getMaxValue()) {
            column.setMaxValue(value);
            return true;
        }
        return false;
    }

    /**
     *
     * @return the time picker format string based on the current system locale and the layout
     *         direction
     */
    private String getTimePickerFormat() {
        // Obtain the time format string per the current locale (e.g. h:mm a)
        String hmaPattern  = ((SimpleDateFormat) DateFormat
                .getTimeInstance(DateFormat.SHORT, mConstant.locale)).toPattern();
        boolean isRTL = TextUtils.getLayoutDirectionFromLocale(mConstant.locale) == View
                .LAYOUT_DIRECTION_RTL;
        boolean isAmPmAtEnd = hmaPattern.indexOf("a") > hmaPattern.indexOf("m");
        // Hour will always appear to the left of minutes regardless of layout direction.
        String timePickerFormat = isRTL ? "mh" : "hm";

        return isAmPmAtEnd ? (timePickerFormat + "a") : ("a" + timePickerFormat);
    }

    private void updateColumns(String timePickerFormat) {
        if (TextUtils.isEmpty(timePickerFormat)) {
            timePickerFormat = "hma";
        }
        timePickerFormat = timePickerFormat.toUpperCase();

        mHourColumn = mMinuteColumn = mAmPmColumn = null;
        mColHourIndex = mColMinuteIndex = mColAmPmIndex = -1;

        ArrayList<PickerColumn> columns = new ArrayList<>(3);
        for (int i = 0; i < timePickerFormat.length(); i++) {
            switch (timePickerFormat.charAt(i)) {
                case 'H':
                    columns.add(mHourColumn = new PickerColumn());
                    mHourColumn.setStaticLabels(mConstant.hours24);
                    mColHourIndex = i;
                    break;
                case 'M':
                    columns.add(mMinuteColumn = new PickerColumn());
                    mMinuteColumn.setStaticLabels(mConstant.minutes);
                    mColMinuteIndex = i;
                    break;
                case 'A':
                    columns.add(mAmPmColumn = new PickerColumn());
                    mAmPmColumn.setStaticLabels(mConstant.ampm);
                    mColAmPmIndex = i;
                    updateMin(mAmPmColumn, 0);
                    updateMax(mAmPmColumn, 1);
                    break;
                default:
                    throw new IllegalArgumentException("Invalid time picker format.");
            }
        }
        setColumns(columns);
        mAmPmSeparatorView = mPickerView.getChildAt(mColAmPmIndex == 0 ? 1 :
                (2 * mColAmPmIndex - 1));
    }

    /**
     * Updates the range in the hour column and notifies column changed if notifyChanged is true.
     * Hour column can have either [0-23] or [1-12] depending on whether the 24 hour format is set
     * or not.
     *
     * @param notifyChanged {code true} if we should notify data set changed on the hour column,
     *                      {@code false} otherwise.
     */
    private void updateHourColumn(boolean notifyChanged) {
        updateMin(mHourColumn, mIs24hFormat ? 0 : 1);
        updateMax(mHourColumn, mIs24hFormat ? 23 : 12);
        if (notifyChanged) {
            setColumnAt(mColHourIndex, mHourColumn);
        }
    }

    /**
     * Updates AM/PM column depending on whether the 24 hour format is set or not. The visibility of
     * this column is set to {@code GONE} for a 24 hour format, and {@code VISIBLE} in 12 hour
     * format. This method also updates the value of this column for a 12 hour format.
     */
    private void updateAmPmColumn() {
        if (mIs24hFormat) {
            mColumnViews.get(mColAmPmIndex).setVisibility(GONE);
            mAmPmSeparatorView.setVisibility(GONE);
        } else {
            mColumnViews.get(mColAmPmIndex).setVisibility(VISIBLE);
            mAmPmSeparatorView.setVisibility(VISIBLE);
            setColumnValue(mColAmPmIndex, mCurrentAmPmIndex, false);
        }
    }

    /**
     * Sets the currently selected hour using a 24-hour time.
     *
     * @param hour the hour to set, in the range (0-23)
     * @see #getHour()
     */
    public void setHour(int hour) {
        if (hour < 0 || hour > 23) {
            throw new IllegalArgumentException("hour: " + hour + " is not in [0-23] range in");
        }
        mCurrentHour = hour;
        if (!mIs24hFormat) {
            if (mCurrentHour >= HOURS_IN_HALF_DAY) {
                mCurrentAmPmIndex = PM_INDEX;
                if (mCurrentHour > HOURS_IN_HALF_DAY) {
                    mCurrentHour -= HOURS_IN_HALF_DAY;
                }
            } else {
                mCurrentAmPmIndex = AM_INDEX;
                if (mCurrentHour == 0) {
                    mCurrentHour = HOURS_IN_HALF_DAY;
                }
            }
            updateAmPmColumn();
        }
        setColumnValue(mColHourIndex, mCurrentHour, false);
    }

    /**
     * Returns the currently selected hour using 24-hour time.
     *
     * @return the currently selected hour in the range (0-23)
     * @see #setHour(int)
     */
    public int getHour() {
        if (mIs24hFormat) {
            return mCurrentHour;
        }
        if (mCurrentAmPmIndex == AM_INDEX) {
            return mCurrentHour % HOURS_IN_HALF_DAY;
        }
        return (mCurrentHour % HOURS_IN_HALF_DAY) + HOURS_IN_HALF_DAY;
    }

    /**
     * Sets the currently selected minute.
     *
     * @param minute the minute to set, in the range (0-59)
     * @see #getMinute()
     */
    public void setMinute(int minute) {
        if (mCurrentMinute == minute) {
            return;
        }
        if (minute < 0 || minute > 59) {
            throw new IllegalArgumentException("minute: " + minute + " is not in [0-59] range.");
        }
        mCurrentMinute = minute;
        setColumnValue(mColMinuteIndex, mCurrentMinute, false);
    }

    /**
     * Returns the currently selected minute.
     *
     * @return the currently selected minute, in the range (0-59)
     * @see #setMinute(int)
     */
    public int getMinute() {
        return mCurrentMinute;
    }

    /**
     * Sets whether this widget displays a 24-hour mode or a 12-hour mode with an AM/PM picker.
     *
     * @param is24Hour {@code true} to display in 24-hour mode,
     *                 {@code false} ti display in 12-hour mode with AM/PM.
     * @see #is24Hour()
     */
    public void setIs24Hour(boolean is24Hour) {
        if (mIs24hFormat == is24Hour) {
            return;
        }
        // the ordering of these statements is important
        int currentHour = getHour();
        mIs24hFormat = is24Hour;
        updateHourColumn(true);
        setHour(currentHour);
        updateAmPmColumn();
    }

    /**
     * @return {@code true} if this widget displays time in 24-hour mode,
     *         {@code false} otherwise.
     *
     * @see #setIs24Hour(boolean)
     */
    public boolean is24Hour() {
        return mIs24hFormat;
    }

    /**
     * Only meaningful for a 12-hour time.
     *
     * @return {@code true} if the currently selected time is in PM,
     *         {@code false} if the currently selected time in in AM.
     */
    public boolean isPm() {
        return (mCurrentAmPmIndex == PM_INDEX);
    }

    @Override
    public void onColumnValueChanged(int columnIndex, int newValue) {
        if (columnIndex == mColHourIndex) {
            mCurrentHour = newValue;
        } else if (columnIndex == mColMinuteIndex) {
            mCurrentMinute = newValue;
        } else if (columnIndex == mColAmPmIndex) {
            mCurrentAmPmIndex = newValue;
        } else {
            throw new IllegalArgumentException("Invalid column index.");
        }
    }
}
