/*
 * Copyright (C) 2018 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.content.Context;
import android.graphics.drawable.GradientDrawable;
import android.hardware.radio.ProgramSelector;
import android.view.View;
import android.widget.ImageButton;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

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

import java.util.Objects;

/**
 * A {@link RecyclerView.ViewHolder} that can bind a {@link Program} to the layout
 * {@code R.layout.radio_favorite_item}.
 */
public class ProgramViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
    private final OnPresetClickListener mPresetClickListener;
    private final OnPresetFavoriteListener mPresetFavoriteListener;

    private final Context mContext;
    private final View mPresetsCard;
    private GradientDrawable mPresetItemChannelBg;
    private final TextView mPresetItemChannel;
    private final TextView mPresetItemMetadata;
    private ImageButton mPresetButton;

    /**
     * Interface for a listener when the View held by this ViewHolder has been clicked.
     */
    public interface OnPresetClickListener {
        /**
         * Method to be called when the View in this ViewHolder has been clicked.
         *
         * @param position The position of the View within the RecyclerView this ViewHolder is
         *                 populating.
         */
        void onPresetClicked(int position);
    }


    /**
     * Interface for a listener that will be notified when a favorite in the presets list has been
     * toggled.
     */
    public interface OnPresetFavoriteListener {

        /**
         * Method called when an item's favorite status has been toggled
         */
        void onPresetFavoriteChanged(int position, boolean saveAsFavorite);
    }


    /**
     * @param presetsView A view that contains the layout {@code R.layout.radio_favorite_item}.
     */
    public ProgramViewHolder(@NonNull View presetsView, @NonNull OnPresetClickListener listener,
            @NonNull OnPresetFavoriteListener favoriteListener) {
        super(presetsView);

        mContext = presetsView.getContext();

        mPresetsCard = presetsView.findViewById(R.id.browse_card);
        mPresetsCard.setOnClickListener(this);

        mPresetClickListener = Objects.requireNonNull(listener);
        mPresetFavoriteListener = Objects.requireNonNull(favoriteListener);

        mPresetItemChannel = presetsView.findViewById(R.id.browse_station_channel);
        mPresetItemMetadata = presetsView.findViewById(R.id.browse_item_metadata);
        mPresetButton = presetsView.findViewById(R.id.browse_button);

        mPresetItemChannelBg = (GradientDrawable)
                presetsView.findViewById(R.id.browse_station_background).getBackground();
    }

    @Override
    public void onClick(View view) {
        mPresetClickListener.onPresetClicked(getAdapterPosition());
    }

    /**
     * Binds the given {@link Program} to this View within this ViewHolder.
     */
    public void bindPreset(Program program, boolean isActiveStation, int itemCount,
            boolean isFavorite) {
        // If the preset is null, clear any existing text.
        if (program == null) {
            mPresetItemChannel.setText(null);
            mPresetItemMetadata.setText(null);
            return;
        }

        ProgramSelector sel = program.getSelector();
        mPresetItemChannel.setText(ProgramSelectorExt.getDisplayName(
                sel, ProgramSelectorExt.NAME_NO_MODULATION));

        mPresetItemChannelBg.setColor(mContext.getResources().getColor(isActiveStation
                ? R.color.accent_color
                : R.color.radio_card_color, null));
        mPresetItemChannel.setCompoundDrawablesRelativeWithIntrinsicBounds(isActiveStation
                ? R.drawable.ic_equalizer
                : 0, 0, 0, 0);

        String programName = program.getName();
        if (programName.isEmpty()) {
            // If there is no metadata text, then use text to indicate the favorite number to the
            // user so that list does not appear empty.
            mPresetItemMetadata.setText(mContext.getString(
                    R.string.radio_default_favorite_metadata_text, getAdapterPosition() + 1));
        } else {
            mPresetItemMetadata.setText(programName);
        }
        setFavoriteButtonFilled(isFavorite);
        mPresetButton.setOnClickListener(v -> {
            boolean favoriteToggleOn =
                    ((Integer) mPresetButton.getTag() == R.drawable.ic_star_empty);
            setFavoriteButtonFilled(favoriteToggleOn);
            mPresetFavoriteListener.onPresetFavoriteChanged(getAdapterPosition(), favoriteToggleOn);
        });
    }

    private void setFavoriteButtonFilled(boolean favoriteToggleOn) {
        mPresetButton.setImageResource(favoriteToggleOn
                ? R.drawable.ic_star_filled
                : R.drawable.ic_star_empty);
        mPresetButton.setTag(favoriteToggleOn
                ? R.drawable.ic_star_filled
                : R.drawable.ic_star_empty);
        mPresetButton.setColorFilter(mContext.getColor(favoriteToggleOn
                ? R.color.accent_color
                : R.color.control_button_color));
    }
}
