/*
 * 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.widget;

import android.content.Context;
import android.os.LocaleList;
import android.text.Editable;
import android.text.InputFilter;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.util.AttributeSet;
import android.util.MathUtils;
import android.view.View;
import android.view.accessibility.AccessibilityManager;

import com.android.internal.R;

/**
 * View to show text input based time picker with hour and minute fields and an optional AM/PM
 * spinner.
 *
 * @hide
 */
public class TextInputTimePickerView extends RelativeLayout {
    public static final int HOURS = 0;
    public static final int MINUTES = 1;
    public static final int AMPM = 2;

    private static final int AM = 0;
    private static final int PM = 1;

    private final EditText mHourEditText;
    private final EditText mMinuteEditText;
    private final TextView mInputSeparatorView;
    private final Spinner mAmPmSpinner;
    private final TextView mErrorLabel;
    private final TextView mHourLabel;
    private final TextView mMinuteLabel;

    private boolean mIs24Hour;
    private boolean mHourFormatStartsAtZero;
    private OnValueTypedListener mListener;

    private boolean mErrorShowing;
    private boolean mTimeSet;

    interface OnValueTypedListener {
        void onValueChanged(int inputType, int newValue);
    }

    public TextInputTimePickerView(Context context) {
        this(context, null);
    }

    public TextInputTimePickerView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public TextInputTimePickerView(Context context, AttributeSet attrs, int defStyle) {
        this(context, attrs, defStyle, 0);
    }

    public TextInputTimePickerView(Context context, AttributeSet attrs, int defStyle,
            int defStyleRes) {
        super(context, attrs, defStyle, defStyleRes);

        inflate(context, R.layout.time_picker_text_input_material, this);

        mHourEditText = findViewById(R.id.input_hour);
        mMinuteEditText = findViewById(R.id.input_minute);
        mInputSeparatorView = findViewById(R.id.input_separator);
        mErrorLabel = findViewById(R.id.label_error);
        mHourLabel = findViewById(R.id.label_hour);
        mMinuteLabel = findViewById(R.id.label_minute);

        mHourEditText.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {}

            @Override
            public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {}

            @Override
            public void afterTextChanged(Editable editable) {
                if (parseAndSetHourInternal(editable.toString()) && editable.length() > 1) {
                    AccessibilityManager am = (AccessibilityManager) context.getSystemService(
                            context.ACCESSIBILITY_SERVICE);
                    if (!am.isEnabled()) {
                        mMinuteEditText.requestFocus();
                    }
                }
            }
        });

        mMinuteEditText.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {}

            @Override
            public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {}

            @Override
            public void afterTextChanged(Editable editable) {
                parseAndSetMinuteInternal(editable.toString());
            }
        });

        mAmPmSpinner = findViewById(R.id.am_pm_spinner);
        final String[] amPmStrings = TimePicker.getAmPmStrings(context);
        ArrayAdapter<CharSequence> adapter =
                new ArrayAdapter<CharSequence>(context, R.layout.simple_spinner_dropdown_item);
        adapter.add(TimePickerClockDelegate.obtainVerbatim(amPmStrings[0]));
        adapter.add(TimePickerClockDelegate.obtainVerbatim(amPmStrings[1]));
        mAmPmSpinner.setAdapter(adapter);
        mAmPmSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> adapterView, View view, int position,
                    long id) {
                if (position == 0) {
                    mListener.onValueChanged(AMPM, AM);
                } else {
                    mListener.onValueChanged(AMPM, PM);
                }
            }

            @Override
            public void onNothingSelected(AdapterView<?> adapterView) {}
        });
    }

    void setListener(OnValueTypedListener listener) {
        mListener = listener;
    }

    void setHourFormat(int maxCharLength) {
        mHourEditText.setFilters(new InputFilter[] {
                new InputFilter.LengthFilter(maxCharLength)});
        mMinuteEditText.setFilters(new InputFilter[] {
                new InputFilter.LengthFilter(maxCharLength)});
        final LocaleList locales = mContext.getResources().getConfiguration().getLocales();
        mHourEditText.setImeHintLocales(locales);
        mMinuteEditText.setImeHintLocales(locales);
    }

    boolean validateInput() {
        final String hourText = TextUtils.isEmpty(mHourEditText.getText())
                ? mHourEditText.getHint().toString()
                : mHourEditText.getText().toString();
        final String minuteText = TextUtils.isEmpty(mMinuteEditText.getText())
                ? mMinuteEditText.getHint().toString()
                : mMinuteEditText.getText().toString();

        final boolean inputValid = parseAndSetHourInternal(hourText)
                && parseAndSetMinuteInternal(minuteText);
        setError(!inputValid);
        return inputValid;
    }

    void updateSeparator(String separatorText) {
        mInputSeparatorView.setText(separatorText);
    }

    private void setError(boolean enabled) {
        mErrorShowing = enabled;

        mErrorLabel.setVisibility(enabled ? View.VISIBLE : View.INVISIBLE);
        mHourLabel.setVisibility(enabled ? View.INVISIBLE : View.VISIBLE);
        mMinuteLabel.setVisibility(enabled ? View.INVISIBLE : View.VISIBLE);
    }

    private void setTimeSet(boolean timeSet) {
        mTimeSet = mTimeSet || timeSet;
    }

    private boolean isTimeSet() {
        return mTimeSet;
    }

    /**
     * Computes the display value and updates the text of the view.
     * <p>
     * This method should be called whenever the current value or display
     * properties (leading zeroes, max digits) change.
     */
    void updateTextInputValues(int localizedHour, int minute, int amOrPm, boolean is24Hour,
            boolean hourFormatStartsAtZero) {
        final String hourFormat = "%d";
        final String minuteFormat = "%02d";

        mIs24Hour = is24Hour;
        mHourFormatStartsAtZero = hourFormatStartsAtZero;

        mAmPmSpinner.setVisibility(is24Hour ? View.INVISIBLE : View.VISIBLE);

        if (amOrPm == AM) {
            mAmPmSpinner.setSelection(0);
        } else {
            mAmPmSpinner.setSelection(1);
        }

        if (isTimeSet()) {
            mHourEditText.setText(String.format(hourFormat, localizedHour));
            mMinuteEditText.setText(String.format(minuteFormat, minute));
        } else {
            mHourEditText.setHint(String.format(hourFormat, localizedHour));
            mMinuteEditText.setHint(String.format(minuteFormat, minute));
        }


        if (mErrorShowing) {
            validateInput();
        }
    }

    private boolean parseAndSetHourInternal(String input) {
        try {
            final int hour = Integer.parseInt(input);
            if (!isValidLocalizedHour(hour)) {
                final int minHour = mHourFormatStartsAtZero ? 0 : 1;
                final int maxHour = mIs24Hour ? 23 : 11 + minHour;
                mListener.onValueChanged(HOURS, getHourOfDayFromLocalizedHour(
                        MathUtils.constrain(hour, minHour, maxHour)));
                return false;
            }
            mListener.onValueChanged(HOURS, getHourOfDayFromLocalizedHour(hour));
            setTimeSet(true);
            return true;
        } catch (NumberFormatException e) {
            // Do nothing since we cannot parse the input.
            return false;
        }
    }

    private boolean parseAndSetMinuteInternal(String input) {
        try {
            final int minutes = Integer.parseInt(input);
            if (minutes < 0 || minutes > 59) {
                mListener.onValueChanged(MINUTES, MathUtils.constrain(minutes, 0, 59));
                return false;
            }
            mListener.onValueChanged(MINUTES, minutes);
            setTimeSet(true);
            return true;
        } catch (NumberFormatException e) {
            // Do nothing since we cannot parse the input.
            return false;
        }
    }

    private boolean isValidLocalizedHour(int localizedHour) {
        final int minHour = mHourFormatStartsAtZero ? 0 : 1;
        final int maxHour = (mIs24Hour ? 23 : 11) + minHour;
        return localizedHour >= minHour && localizedHour <= maxHour;
    }

    private int getHourOfDayFromLocalizedHour(int localizedHour) {
        int hourOfDay = localizedHour;
        if (mIs24Hour) {
            if (!mHourFormatStartsAtZero && localizedHour == 24) {
                hourOfDay = 0;
            }
        } else {
            if (!mHourFormatStartsAtZero && localizedHour == 12) {
                hourOfDay = 0;
            }
            if (mAmPmSpinner.getSelectedItemPosition() == 1) {
                hourOfDay += 12;
            }
        }
        return hourOfDay;
    }
}
