/*
 * Copyright (c) 2016, 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.car.radio;

import android.annotation.NonNull;
import android.content.Context;
import android.hardware.radio.ProgramSelector;
import android.hardware.radio.RadioManager;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import com.android.car.broadcastradio.support.platform.ProgramSelectorExt;

import java.util.ArrayList;
import java.util.List;

/**
 * A controller for the various buttons in the manual tuner screen.
 */
public class ManualTunerController {
    /**
     * The total number of controllable buttons in the manual tuner. This value represents the
     * values 0 - 9.
     */
    private static final int NUM_OF_MANUAL_TUNER_BUTTONS = 10;

    private final StringBuilder mCurrentChannel = new StringBuilder();

    private final TextView mChannelView;

    private int mCurrentRadioBand;

    private final List<Button> mManualTunerButtons = new ArrayList<>(NUM_OF_MANUAL_TUNER_BUTTONS);

    private final String mNumberZero;
    private final String mNumberOne;
    private final String mNumberTwo;
    private final String mNumberThree;
    private final String mNumberFour;
    private final String mNumberFive;
    private final String mNumberSix;
    private final String mNumberSeven;
    private final String mNumberEight;
    private final String mNumberNine;
    private final String mPeriod;

    private ChannelValidator mChannelValidator;
    private final ChannelValidator mAmChannelValidator = new AmChannelValidator();
    private final ChannelValidator mFmChannelValidator = new FMChannelValidator();

    private final int mEnabledButtonColor;
    private final int mDisabledButtonColor;

    private View mDoneButton;
    private ManualTunerClickListener mManualTunerClickListener;

    /**
     * An interface that will perform various validations on {@link #mCurrentChannel}.
     */
    public interface ChannelValidator {
        /**
         * Returns {@code true} if the given character is allowed to be appended to the given
         * number.
         */
        boolean canAppendCharacterToNumber(@NonNull String character, @NonNull String number);

        /**
         * Returns {@code true} if the given number if a valid radio channel frequency.
         */
        boolean isValidChannel(@NonNull String number);

        /**
         * Returns an integer representation of the given number in hertz.
         */
        int convertToHz(@NonNull String number);

        /**
         * Returns {@code true} if a period (decimal point) should be appended to the given
         * number. For example, FM channels should automatically add a period if the given number
         * is over 100 or has two digits.
         */
        boolean shouldAppendPeriod(@NonNull String number);
    }

    /**
     * An interface for a class that will be notified when the done or back buttons of the manual
     * tuner has been clicked.
     */
    public interface ManualTunerClickListener {
        /**
         * Called when the back button on the manual tuner has been clicked.
         */
        void onBack();

        /**
         * Called when the done button has been clicked with the given station that the user has
         * selected.
         */
        void onDone(ProgramSelector sel);
    }

    public ManualTunerController(Context context, View container, int currentRadioBand) {
        mChannelView = container.findViewById(R.id.manual_tuner_channel);

        // Default to FM band.
        if (currentRadioBand != RadioManager.BAND_FM && currentRadioBand != RadioManager.BAND_AM) {
            currentRadioBand = RadioManager.BAND_FM;
        }

        mCurrentRadioBand = currentRadioBand;

        mChannelValidator = mCurrentRadioBand == RadioManager.BAND_AM
                ? mAmChannelValidator
                : mFmChannelValidator;

        mEnabledButtonColor = context.getColor(R.color.manual_tuner_button_text);
        mDisabledButtonColor = context.getColor(R.color.car_radio_control_button_disabled);

        mNumberZero = context.getString(R.string.manual_tuner_0);
        mNumberOne = context.getString(R.string.manual_tuner_1);
        mNumberTwo = context.getString(R.string.manual_tuner_2);
        mNumberThree = context.getString(R.string.manual_tuner_3);
        mNumberFour = context.getString(R.string.manual_tuner_4);
        mNumberFive = context.getString(R.string.manual_tuner_5);
        mNumberSix = context.getString(R.string.manual_tuner_6);
        mNumberSeven = context.getString(R.string.manual_tuner_7);
        mNumberEight = context.getString(R.string.manual_tuner_8);
        mNumberNine = context.getString(R.string.manual_tuner_9);
        mPeriod = context.getString(R.string.manual_tuner_period);

        initializeChannelButtons(container);
        initializeManualTunerButtons(container);

        updateButtonState();
    }

    /**
     * Initializes the buttons responsible for adjusting the channel to be entered by the manual
     * tuner.
     */
    private void initializeChannelButtons(View container) {
        RadioBandButton amBandButton = container.findViewById(R.id.manual_tuner_am_band);
        RadioBandButton fmBandButton = container.findViewById(R.id.manual_tuner_fm_band);
        mDoneButton = container.findViewById(R.id.manual_tuner_done_button);

        View backButton = container.findViewById(R.id.exit_manual_tuner_button);
        if (backButton != null) {
            backButton.setOnClickListener(v -> {
                if (mManualTunerClickListener != null) {
                    mManualTunerClickListener.onBack();
                }
            });
        }

        mDoneButton.setOnClickListener(v -> {
            if (mManualTunerClickListener == null) {
                return;
            }

            int channelFrequency = mChannelValidator.convertToHz(mCurrentChannel.toString());
            mManualTunerClickListener.onDone(
                    ProgramSelectorExt.createAmFmSelector(channelFrequency));
        });

        if (amBandButton != null) {
            amBandButton.setOnClickListener(v -> {
                mCurrentRadioBand = RadioManager.BAND_AM;
                mChannelValidator = mAmChannelValidator;
                amBandButton.setIsBandSelected(true);
                fmBandButton.setIsBandSelected(false);
                resetChannel();
            });
        }
        if (fmBandButton != null) {
            fmBandButton.setOnClickListener(v -> {
                mCurrentRadioBand = RadioManager.BAND_FM;
                mChannelValidator = mFmChannelValidator;
                amBandButton.setIsBandSelected(false);
                fmBandButton.setIsBandSelected(true);
                resetChannel();
            });
        }
        if (mCurrentRadioBand == RadioManager.BAND_AM && amBandButton != null) {
            amBandButton.setIsBandSelected(true);
        } else if (fmBandButton != null) {
            fmBandButton.setIsBandSelected(true);
        }
    }

    /**
     * Refreshes tuner key state with new radio band, if changed without using AM/FM band buttons
     */
    public void updateCurrentRadioBand(int band) {
        mCurrentRadioBand = band;
        if (band == RadioManager.BAND_FM) {
            mChannelValidator = mFmChannelValidator;
        } else {
            mChannelValidator = mAmChannelValidator;
        }
        resetChannel();
    }

    /**
     * Sets up the click listeners and tags for the manual tuner buttons.
     */
    private void initializeManualTunerButtons(View container) {
        Button numberZero = container.findViewById(R.id.manual_tuner_0);
        numberZero.setOnClickListener(new TuneButtonClickListener(mNumberZero));
        numberZero.setTag(R.id.manual_tuner_button_value, mNumberZero);
        mManualTunerButtons.add(numberZero);

        Button numberOne = container.findViewById(R.id.manual_tuner_1);
        numberOne.setOnClickListener(new TuneButtonClickListener(mNumberOne));
        numberOne.setTag(R.id.manual_tuner_button_value, mNumberOne);
        mManualTunerButtons.add(numberOne);

        Button numberTwo = container.findViewById(R.id.manual_tuner_2);
        numberTwo.setOnClickListener(new TuneButtonClickListener(mNumberTwo));
        numberTwo.setTag(R.id.manual_tuner_button_value, mNumberTwo);
        mManualTunerButtons.add(numberTwo);

        Button numberThree = container.findViewById(R.id.manual_tuner_3);
        numberThree.setOnClickListener(new TuneButtonClickListener(mNumberThree));
        numberThree.setTag(R.id.manual_tuner_button_value, mNumberThree);
        mManualTunerButtons.add(numberThree);

        Button numberFour = container.findViewById(R.id.manual_tuner_4);
        numberFour.setOnClickListener(new TuneButtonClickListener(mNumberFour));
        numberFour.setTag(R.id.manual_tuner_button_value, mNumberFour);
        mManualTunerButtons.add(numberFour);

        Button numberFive = container.findViewById(R.id.manual_tuner_5);
        numberFive.setOnClickListener(new TuneButtonClickListener(mNumberFive));
        numberFive.setTag(R.id.manual_tuner_button_value, mNumberFive);
        mManualTunerButtons.add(numberFive);

        Button numberSix = container.findViewById(R.id.manual_tuner_6);
        numberSix.setOnClickListener(new TuneButtonClickListener(mNumberSix));
        numberSix.setTag(R.id.manual_tuner_button_value, mNumberSix);
        mManualTunerButtons.add(numberSix);

        Button numberSeven = container.findViewById(R.id.manual_tuner_7);
        numberSeven.setOnClickListener(new TuneButtonClickListener(mNumberSeven));
        numberSeven.setTag(R.id.manual_tuner_button_value, mNumberSeven);
        mManualTunerButtons.add(numberSeven);

        Button numberEight = container.findViewById(R.id.manual_tuner_8);
        numberEight.setOnClickListener(new TuneButtonClickListener(mNumberEight));
        numberEight.setTag(R.id.manual_tuner_button_value, mNumberEight);
        mManualTunerButtons.add(numberEight);

        Button numberNine = container.findViewById(R.id.manual_tuner_9);
        numberNine.setOnClickListener(new TuneButtonClickListener(mNumberNine));
        numberNine.setTag(R.id.manual_tuner_button_value, mNumberNine);
        mManualTunerButtons.add(numberNine);

        container.findViewById(R.id.manual_tuner_backspace)
                .setOnClickListener(new BackSpaceListener());
    }

    /**
     * Sets the given {@link ManualTunerClickListener} to be notified when the done button of the manual
     * tuner has been clicked.
     */
    public void setDoneButtonListener(ManualTunerClickListener listener) {
        mManualTunerClickListener = listener;
    }

    /**
     * Iterates through all the buttons in {@link #mManualTunerButtons} and updates whether or not
     * they are enabled based on the current {@link #mChannelValidator}.
     */
    private void updateButtonState() {
        String currentChannel = mCurrentChannel.toString();

        for (int i = 0, size = mManualTunerButtons.size(); i < size; i++) {
            Button button = mManualTunerButtons.get(i);
            String value = (String) button.getTag(R.id.manual_tuner_button_value);

            boolean enabled = mChannelValidator.canAppendCharacterToNumber(value, currentChannel);

            button.setEnabled(enabled);
            button.setTextColor(enabled ? mEnabledButtonColor : mDisabledButtonColor);
        }

        mDoneButton.setEnabled(mChannelValidator.isValidChannel(currentChannel));
    }

    /**
     * A {@link ChannelValidator} for the AM band. Note this validator is for US regions.
     */
    private final class AmChannelValidator implements ChannelValidator {
        private static final int AM_LOWER_LIMIT = 530;
        private static final int AM_UPPER_LIMIT = 1700;

        @Override
        public boolean canAppendCharacterToNumber(@NonNull String character,
                @NonNull String number) {
            // There are no decimal points for AM numbers.
            if (character.equals(mPeriod)) {
                return false;
            }

            int charValue = Integer.valueOf(character);

            switch (number.length()) {
                case 0:
                    // 5 and 1 are the first digits of AM_LOWER_LIMIT and AM_UPPER_LIMIT.
                    return charValue >= 5 || charValue == 1;
                case 1:
                    // Ensure that the number is above the lower AM limit of 530.
                    return !number.equals(mNumberFive) || charValue >= 3;
                case 2:
                    // Any number is allowed to be appended if the current AM station being entered
                    // is a number in the 1000s.
                    if (String.valueOf(number.charAt(0)).equals(mNumberOne)) {
                        return true;
                    }

                    // Otherwise, only zero is allowed because AM stations go in increments of 10.
                    return character.equals(mNumberZero);
                case 3:
                    // AM station are in increments of 10, so for a 3 digit AM station, only a
                    // zero is allowed at the end. Note, no need to check if the "number" is a
                    // number in the 1000s because this should be handled by "case 2".
                    return character.equals(mNumberZero);
                default:
                    // Otherwise, just disallow the character.
                    return false;
            }
        }

        @Override
        public boolean isValidChannel(@NonNull String number) {
            if (number.length() == 0) {
                return false;
            }

            // No decimal points for AM channels.
            if (number.contains(mPeriod)) {
                return false;
            }

            int value = Integer.valueOf(number);
            return value >= AM_LOWER_LIMIT && value <= AM_UPPER_LIMIT;
        }

        @Override
        public int convertToHz(@NonNull String number) {
            // The number should already been in Hz, so just perform a straight conversion.
            return Integer.valueOf(number);
        }

        @Override
        public boolean shouldAppendPeriod(@NonNull String number) {
            // No decimal points for AM channels.
            return false;
        }
    }

    /**
     * A {@link ChannelValidator} for the FM band. Note that this validator is for US regions.
     */
    private final class FMChannelValidator implements ChannelValidator {
        private static final int FM_LOWER_LIMIT = 87900;
        private static final int FM_UPPER_LIMIT = 107900;

        /**
         * The value including the decimal point of the FM upper limit.
         */
        private static final String FM_UPPER_LIMIT_CHARACTERISTIC = "107.";

        /**
         * The lower limit of FM channels in kilohertz before the decimal point.
         */
        private static final int FM_LOWER_LIMIT_NO_DECIMAL_KHZ = 87;

        private static final String KILOHERTZ_CONVERSION_DIGITS = "000";
        private static final String KILOHERTZ_CONVERSION_DIGITS_WITH_DECIMAL = "00";

        @Override
        public boolean canAppendCharacterToNumber(@NonNull String character,
                @NonNull String number) {
            int indexOfPeriod = number.indexOf(mPeriod);

            if (character.equals(mPeriod)) {
                // Only one decimal point is allowed.
                if (indexOfPeriod != -1) {
                    return false;
                }

                // There needs to be at least two digits before a decimal point is allowed.
                return number.length() >= 2;
            }

            if (number.length() == 0) {
                // No need to check for the decimal point here because it's handled by the first
                // if case.
                int charValue = Integer.valueOf(character);

                // 8 and 1 are the first digits of FM_LOWER_LIMIT and FM_UPPER_LIMIT;
                return charValue >= 8 || charValue == 1;
            }

            if (indexOfPeriod == -1) {
                switch (number.length()) {
                    case 1:
                        // If the number is 1, then only a zero is allowed afterwards since FM
                        // channels can only go up to 108.1.
                        if (number.equals(mNumberOne)) {
                            return character.equals(mNumberZero);
                        }

                        // If the number 8, then we need to only allow 7 and above. This is because
                        // the lower limit of FM channels is 87.9.
                        if (number.equals(mNumberEight)) {
                            int numberValue = Integer.valueOf(character);
                            return numberValue >= 7;
                        }

                        // Otherwise, any number is allowed.
                        return true;

                    case 2:
                        // If there are two digits, only allow another character to be added if the
                        // resulting character will be in the 100s but less than 107.
                        return String.valueOf(number.charAt(0)).equals(mNumberOne)
                                && !character.equals(mNumberEight)
                                && !character.equals(mNumberNine);

                    case 3:
                    default:
                        // If there are already three digits, no more numbers can be added
                        // without a decimal point.
                        return false;
                }
            } else if (number.length() - 1 > indexOfPeriod) {
                // Only one number if allowed after the decimal point.
                return false;
            }

            // If the number being entered it right up on the FM upper limit, then the allowed
            // character can only be a 1 because the upper limit is 108.1.
            if (number.equals(FM_UPPER_LIMIT_CHARACTERISTIC)) {
                return character.equals(mNumberNine);
            }

            // Otherwise, FM frequencies can only end in an odd digit (e.g. 96.5 and not 96.4).
            int charValue = Integer.valueOf(character);
            return charValue % 2 == 1;
        }

        @Override
        public boolean isValidChannel(@NonNull String number) {
            if (number.length() == 0) {
                return false;
            }

            // Strip the period from the number and ensure the number string is represented in
            // kilohertz.
            String updatedNumber = convertNumberToKilohertz(number);
            int value = Integer.valueOf(updatedNumber);
            return value >= FM_LOWER_LIMIT && value <= FM_UPPER_LIMIT;
        }

        @Override
        public int convertToHz(@NonNull String number) {
            return Integer.valueOf(convertNumberToKilohertz(number));
        }

        @Override
        public boolean shouldAppendPeriod(@NonNull String number) {
            // Check if there is already a decimal point.
            if (number.contains(mPeriod)) {
                return false;
            }

            int value = Integer.valueOf(number);
            return value >= FM_LOWER_LIMIT_NO_DECIMAL_KHZ;
        }

        /**
         * Converts the given number to its kilohertz representation. For example, 87.9 will be
         * converted to 87900.
         */
        private String convertNumberToKilohertz(String number) {
            if (number.contains(mPeriod)) {
                return number.replace(mPeriod, "")
                        + KILOHERTZ_CONVERSION_DIGITS_WITH_DECIMAL;
            }

            return number + KILOHERTZ_CONVERSION_DIGITS;
        }
    }

    /**
     * Sets the {@link #mCurrentChannel} on {@link #mChannelView}. Will append a decimal point to
     * the text if necessary. This is based on the current {@link ChannelValidator}.
     */
    private void setChannelText() {
        if (mChannelValidator.shouldAppendPeriod(mCurrentChannel.toString())) {
            mCurrentChannel.append(mPeriod);
        }

        mChannelView.setText(mCurrentChannel.toString());
    }

    /**
     * Resets any radio station that may have been entered and updates the button states
     * accordingly.
     */
    private void resetChannel() {
        mChannelView.setText(null);

        // Clear the string buffer by setting the length to zero rather than allocating a new
        // one.
        mCurrentChannel.setLength(0);

        updateButtonState();
    }

    /**
     * A {@link android.view.View.OnClickListener} that handles back space clicks. It is responsible
     * for removing characters from the {@link #mChannelView} TextView.
     */
    private class BackSpaceListener implements View.OnClickListener {
        @Override
        public void onClick(View v) {
            if (mCurrentChannel.length() == 0) {
                return;
            }

            // Since the period cannot be added manually by the user, remove it for them. Both
            // before and after the deletion of a non-period character.
            deleteLastCharacterIfPeriod();
            mCurrentChannel.deleteCharAt(mCurrentChannel.length() - 1);

            mChannelView.setText(mCurrentChannel.toString());

            updateButtonState();
        }

        /**
         * Checks if the last character in {@link ManualTunerController#mCurrentChannel} is a
         * period. If it is, then removes it.
         */
        private void deleteLastCharacterIfPeriod() {
            int lastIndex = mCurrentChannel.length() - 1;
            String lastCharacter = String.valueOf(mCurrentChannel.charAt(lastIndex));

            // If we delete a character and the resulting last character is the decimal point,
            // delete that as well.
            if (lastCharacter.equals(mPeriod)) {
                mCurrentChannel.deleteCharAt(lastIndex);
            }
        }
    }

    /**
     * A {@link android.view.View.OnClickListener} for each of the manual tuner buttons that
     * will update the number being displayed when pressed.
     */
    private class TuneButtonClickListener implements View.OnClickListener {
        private final String mValue;

        TuneButtonClickListener(String value) {
            mValue = value;
        }

        @Override
        public void onClick(View v) {
            mCurrentChannel.append(mValue);
            setChannelText();
            updateButtonState();
        }
    }
}
