/*
 * 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.animation.Animator;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import com.android.car.radio.service.RadioStation;
import com.android.car.view.PagedListView;

import java.util.List;

/**
 * A fragment that is responsible for displaying a list of the user's saved radio stations.
 */
public class RadioPresetsFragment extends Fragment implements
        FragmentWithFade,
        PresetsAdapter.OnPresetItemClickListener,
        RadioAnimationManager.OnExitCompleteListener,
        RadioController.RadioStationChangeListener,
        RadioStorage.PresetsChangeListener {
    private static final String TAG = "PresetsFragment";
    private static final int ANIM_DURATION_MS = 200;

    private View mRootView;
    private View mCurrentRadioCard;

    private RadioStorage mRadioStorage;
    private RadioController mRadioController;
    private RadioAnimationManager mAnimManager;

    private PresetListExitListener mPresetListExitListener;

    private PagedListView mPresetsList;
    private final PresetsAdapter mPresetsAdapter = new PresetsAdapter();

    /**
     * An interface that will be notified when the user has indicated that they would like to
     * exit the preset list.
     */
    public interface PresetListExitListener {
        /**
         * Method to be called when the preset list should be closed and the main radio display
         * should be shown.
         */
        void OnPresetListExit();
    }

    /**
     * Sets the {@link RadioController} that is responsible for updating the UI of this fragment
     * with the information of the current radio station.
     */
    private void setRadioController(RadioController radioController) {
        mRadioController = radioController;
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        mRootView = inflater.inflate(R.layout.radio_presets_list, container, false);
        Context context = getContext();

        mPresetsAdapter.setOnPresetItemClickListener(this);

        mCurrentRadioCard = mRootView.findViewById(R.id.current_radio_station_card);

        mAnimManager = new RadioAnimationManager(getContext(), mRootView);
        mAnimManager.playEnterAnimation();

        // Clicking on the current radio station card will close the activity and return to the
        // main radio screen.
        mCurrentRadioCard.setOnClickListener(v -> {
            mAnimManager.playExitAnimation(RadioPresetsFragment.this /* listener */);
        });

        mPresetsList = mRootView.findViewById(R.id.presets_list);
        mPresetsList.setLightMode();
        mPresetsList.setDefaultItemDecoration(new ItemSpacingDecoration(context));
        mPresetsList.setAdapter(mPresetsAdapter);
        mPresetsList.getLayoutManager().setOffsetRows(false);
        mPresetsList.getRecyclerView().addOnScrollListener(new PresetListScrollListener(
                context, mRootView, mCurrentRadioCard, mPresetsList));

        mRadioStorage = RadioStorage.getInstance(context);
        mRadioStorage.addPresetsChangeListener(this);
        setPresetsOnList(mRadioStorage.getPresets());

        return mRootView;
    }

    @Override
    public void fadeOutContent() {
        ObjectAnimator containerAlphaAnimator =
                ObjectAnimator.ofFloat(mCurrentRadioCard, View.ALPHA, 0f);
        containerAlphaAnimator.setDuration(ANIM_DURATION_MS);
        containerAlphaAnimator.addListener(new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(Animator animation) {}

            @Override
            public void onAnimationEnd(Animator animation) {
                mCurrentRadioCard.setVisibility(View.GONE);
            }

            @Override
            public void onAnimationCancel(Animator animation) {}

            @Override
            public void onAnimationRepeat(Animator animation) {}
        });

        ObjectAnimator presetListAlphaAnimator =
                ObjectAnimator.ofFloat(mPresetsList, View.ALPHA, 0f);
        presetListAlphaAnimator.setDuration(ANIM_DURATION_MS);
        presetListAlphaAnimator.addListener(new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(Animator animation) {}

            @Override
            public void onAnimationEnd(Animator animation) {
                mPresetsList.setVisibility(View.GONE);
            }

            @Override
            public void onAnimationCancel(Animator animation) {}

            @Override
            public void onAnimationRepeat(Animator animation) {}
        });

        AnimatorSet animatorSet = new AnimatorSet();
        animatorSet.playTogether(containerAlphaAnimator, presetListAlphaAnimator);
        animatorSet.start();
    }

    @Override
    public void fadeInContent() {
        // Only the current radio card needs to be faded in as that is the only part
        // of the fragment that will peek over the manual tuner.
        ObjectAnimator containerAlphaAnimator =
                ObjectAnimator.ofFloat(mCurrentRadioCard, View.ALPHA, 1f);
        containerAlphaAnimator.setDuration(ANIM_DURATION_MS);
        containerAlphaAnimator.addListener(new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(Animator animation) {
                mCurrentRadioCard.setVisibility(View.VISIBLE);
            }

            @Override
            public void onAnimationEnd(Animator animation) {}

            @Override
            public void onAnimationCancel(Animator animation) {}

            @Override
            public void onAnimationRepeat(Animator animation) {}
        });

        ObjectAnimator presetListAlphaAnimator =
                ObjectAnimator.ofFloat(mPresetsList, View.ALPHA, 1f);
        presetListAlphaAnimator.setDuration(ANIM_DURATION_MS);
        presetListAlphaAnimator.addListener(new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(Animator animation) {
                mPresetsList.setVisibility(View.VISIBLE);
            }

            @Override
            public void onAnimationEnd(Animator animation) {}

            @Override
            public void onAnimationCancel(Animator animation) {}

            @Override
            public void onAnimationRepeat(Animator animation) {}
        });

        AnimatorSet animatorSet = new AnimatorSet();
        animatorSet.playTogether(containerAlphaAnimator, presetListAlphaAnimator);
        animatorSet.start();
    }

    @Override
    public void onStart() {
        super.onStart();
        mRadioController.initialize(mRootView);
        mRadioController.setShouldColorStatusBar(true);
        mRadioController.setRadioStationChangeListener(this);

        mPresetsAdapter.setActiveRadioStation(mRadioController.getCurrentRadioStation());
    }

    @Override
    public void onDestroy() {
        mRadioStorage.removePresetsChangeListener(this);
        mPresetListExitListener = null;
        super.onDestroy();
    }

    @Override
    public void onExitAnimationComplete() {
        if (mPresetListExitListener != null) {
            mPresetListExitListener.OnPresetListExit();
        }
    }

    @Override
    public void onPresetItemClicked(RadioStation station) {
        mRadioController.tuneToRadioChannel(station);
    }

    @Override
    public void onRadioStationChanged(RadioStation station) {
        if (Log.isLoggable(TAG, Log.DEBUG)) {
            Log.d(TAG, "onRadioStationChanged(): " + station);
        }

        mPresetsAdapter.setActiveRadioStation(station);
    }

    @Override
    public void onPresetsRefreshed() {
        if (Log.isLoggable(TAG, Log.DEBUG)) {
            Log.d(TAG, "onPresetsRefreshed()");
        }

        setPresetsOnList(mRadioStorage.getPresets());
    }

    /**
     * Sets the given list of presets into the PagedListView {@link #mPresetsList}.
     */
    private void setPresetsOnList(List<RadioStation> presets) {
        if (Log.isLoggable(TAG, Log.DEBUG)) {
            Log.d(TAG, "setPresetsOnList(). # of presets: " + presets.size());
        }

        if (Log.isLoggable(TAG, Log.VERBOSE)) {
            for (RadioStation radioStation : presets) {
                Log.v(TAG, "\t" + radioStation);
            }
        }

        mPresetsAdapter.setPresets(presets);
    }

    /**
     * A {@link com.android.car.view.PagedListView.Decoration} that draws a line between
     * the items.
     */
    public static class ItemSpacingDecoration extends PagedListView.DividerDecoration {
        private final int mLineStart;

        public ItemSpacingDecoration(Context context) {
            super(context);
            Resources res = context.getResources();
            mLineStart = res.getDimensionPixelSize(R.dimen.stream_card_keyline_3);
        }

        @Override
        public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {
            View presetCard = parent.findViewById(R.id.preset_card);

            if (presetCard == null) {
                return;
            }

            int left = mLineStart + presetCard.getLeft();
            int right = presetCard.getRight();
            int childCount = parent.getChildCount();

            for (int i = 0; i < childCount; i++) {
                View child = parent.getChildAt(i);
                int bottom = child.getBottom();
                int top = bottom - mDividerHeight;

                // Draw a divider line between each item. No need to draw the line for the last
                // item.
                if (i != childCount - 1) {
                    c.drawRect(left, top, right, bottom, mPaint);
                }
            }
        }
    }

    /**
     * Returns a new instance of the {@link RadioPresetsFragment}.
     *
     * @param radioController The {@link RadioController} that is responsible for updating the UI
     *                        of the returned fragment.
     */
    public static RadioPresetsFragment newInstance(RadioController radioController,
            PresetListExitListener existListener) {
        RadioPresetsFragment fragment = new RadioPresetsFragment();
        fragment.setRadioController(radioController);
        fragment.mPresetListExitListener = existListener;

        return fragment;
    }
}
