/*
 * 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.Nullable;
import android.content.Intent;
import android.hardware.radio.ProgramSelector;
import android.hardware.radio.RadioManager;
import android.os.Bundle;
import android.util.Log;
import android.util.Pair;

import androidx.car.drawer.CarDrawerActivity;
import androidx.car.drawer.CarDrawerAdapter;
import androidx.car.drawer.DrawerItemViewHolder;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;

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

/**
 * The main activity for the radio. This activity initializes the radio controls and listener for
 * radio changes.
 */
public class CarRadioActivity extends CarDrawerActivity implements
        RadioPresetsFragment.PresetListExitListener,
        MainRadioFragment.RadioPresetListClickListener,
        ManualTunerFragment.ManualTunerCompletionListener {
    private static final String TAG = "Em.RadioActivity";
    private static final String MANUAL_TUNER_BACKSTACK = "MANUAL_TUNER_BACKSTACK";
    private static final String CONTENT_FRAGMENT_TAG = "CONTENT_FRAGMENT_TAG";

    private static final List<Pair<Integer, String>> SUPPORTED_RADIO_BANDS = new ArrayList<>();

    /**
     * Intent action for notifying that the radio state has changed.
     */
    private static final String ACTION_RADIO_APP_STATE_CHANGE
            = "android.intent.action.RADIO_APP_STATE_CHANGE";

    /**
     * Boolean Intent extra indicating if the radio is the currently in the foreground.
     */
    private static final String EXTRA_RADIO_APP_FOREGROUND
            = "android.intent.action.RADIO_APP_STATE";

    /**
     * Whether or not it is safe to make transactions on the
     * {@link androidx.fragment.app.FragmentManager}. This variable prevents a possible exception
     * when calling commit() on the FragmentManager.
     *
     * <p>The default value is {@code true} because it is only after
     * {@link #onSaveInstanceState(Bundle)} has been called that fragment commits are not allowed.
     */
    private boolean mAllowFragmentCommits = true;

    private RadioController mRadioController;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        SUPPORTED_RADIO_BANDS.add(
                new Pair<>(RadioManager.BAND_AM, getString(R.string.radio_am_text)));
        SUPPORTED_RADIO_BANDS.add(
                new Pair<>(RadioManager.BAND_FM, getString(R.string.radio_fm_text)));

        super.onCreate(savedInstanceState);
        setToolbarElevation(0f);

        mRadioController = new RadioController(this);
        setContentFragment(
                MainRadioFragment.newInstance(mRadioController, this /* clickListener */));

    }

    @Override
    protected CarDrawerAdapter getRootAdapter() {
        return new RadioDrawerAdapter();
    }

    @Override
    public void onPresetListClicked() {
        setContentFragment(
                RadioPresetsFragment.newInstance(mRadioController, this /* existListener */));
    }

    @Override
    public void OnPresetListExit() {
        setContentFragment(
                MainRadioFragment.newInstance(mRadioController, this /* clickListener */));
    }

    private void startManualTuner() {
        if (!mAllowFragmentCommits || getSupportFragmentManager().getBackStackEntryCount() > 0) {
            return;
        }

        Fragment currentFragment = getCurrentFragment();
        if (currentFragment instanceof FragmentWithFade) {
            ((FragmentWithFade) currentFragment).fadeOutContent();
        }

        ManualTunerFragment tunerFragment =
                ManualTunerFragment.newInstance(mRadioController.getCurrentRadioBand());
        tunerFragment.setManualTunerCompletionListener(this);

        getSupportFragmentManager().beginTransaction()
                .setCustomAnimations(R.anim.slide_up, R.anim.slide_down,
                        R.anim.slide_up, R.anim.slide_down)
                .add(getContentContainerId(), tunerFragment)
                .addToBackStack(MANUAL_TUNER_BACKSTACK)
                .commit();
    }

    @Override
    public void onStationSelected(ProgramSelector sel) {
        maybeDismissManualTuner();

        Fragment fragment = getCurrentFragment();
        if (fragment instanceof FragmentWithFade) {
            ((FragmentWithFade) fragment).fadeInContent();
        }

        if (sel != null) {
            mRadioController.tune(sel);
        }
    }

    @Override
    protected void onStart() {
        super.onStart();

        if (Log.isLoggable(TAG, Log.DEBUG)) {
            Log.d(TAG, "onStart");
        }

        // Fragment commits are not allowed once the Activity's state has been saved. Once
        // onStart() has been called, the FragmentManager should now allow commits.
        mAllowFragmentCommits = true;

        mRadioController.start();

        Intent broadcast = new Intent(ACTION_RADIO_APP_STATE_CHANGE);
        broadcast.putExtra(EXTRA_RADIO_APP_FOREGROUND, true);
        sendBroadcast(broadcast);
    }

    @Override
    protected void onStop() {
        super.onStop();

        if (Log.isLoggable(TAG, Log.DEBUG)) {
            Log.d(TAG, "onStop");
        }

        Intent broadcast = new Intent(ACTION_RADIO_APP_STATE_CHANGE);
        broadcast.putExtra(EXTRA_RADIO_APP_FOREGROUND, false);
        sendBroadcast(broadcast);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();

        if (Log.isLoggable(TAG, Log.DEBUG)) {
            Log.d(TAG, "onDestroy");
        }

        mRadioController.shutdown();
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        // A transaction can only be committed with this method prior to its containing activity
        // saving its state.
        mAllowFragmentCommits = false;
        super.onSaveInstanceState(outState);
    }

    /**
     * Checks if the manual tuner is currently being displayed. If it is, then dismiss it.
     */
    private void maybeDismissManualTuner() {
        FragmentManager fragmentManager = getSupportFragmentManager();
        if (fragmentManager.getBackStackEntryCount() > 0) {
            // A station can only be selected if the manual tuner fragment has been shown; so, remove
            // that here.
            getSupportFragmentManager().popBackStack();
        }
    }

    private void setContentFragment(Fragment fragment) {
        if (!mAllowFragmentCommits) {
            return;
        }

        getSupportFragmentManager().beginTransaction()
                .replace(getContentContainerId(), fragment, CONTENT_FRAGMENT_TAG)
                .commitNow();
    }

    /**
     * Returns the fragment that is currently being displayed as the content view. Note that this
     * is not necessarily the fragment that is visible. The manual tuner fragment can be displayed
     * on top of this content fragment.
     */
    @Nullable
    private Fragment getCurrentFragment() {
        return getSupportFragmentManager().findFragmentByTag(CONTENT_FRAGMENT_TAG);
    }

    /**
     * An adapter that is responsible for populating the Radio drawer with the available bands to
     * select, as well as the option for opening the manual tuner.
     */
    private class RadioDrawerAdapter extends CarDrawerAdapter {
        private final List<String> mDrawerOptions =
                new ArrayList<>(SUPPORTED_RADIO_BANDS.size() + 1);

        RadioDrawerAdapter() {
            super(CarRadioActivity.this, false /* showDisabledListOnEmpty */);
            setTitle(getString(R.string.app_name));
            // The ordering of options is hardcoded. The click handler below depends on it.
            for (Pair<Integer, String> band : SUPPORTED_RADIO_BANDS) {
                mDrawerOptions.add(band.second);
            }
            mDrawerOptions.add(getString(R.string.manual_tuner_drawer_entry));
        }

        @Override
        protected int getActualItemCount() {
            return mDrawerOptions.size();
        }

        @Override
        public void populateViewHolder(DrawerItemViewHolder holder, int position) {
            holder.getTitle().setText(mDrawerOptions.get(position));
        }

        @Override
        public void onItemClick(int position) {
            getDrawerController().closeDrawer();
            if (position < SUPPORTED_RADIO_BANDS.size()) {
                mRadioController.switchBand(SUPPORTED_RADIO_BANDS.get(position).first);
            } else if (position == SUPPORTED_RADIO_BANDS.size()) {
                startManualTuner();
            } else {
                Log.w(TAG, "Unexpected position: " + position);
            }
        }
    }
}
