package de.danoeh.antennapod.activity;

import android.annotation.TargetApi;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.graphics.PixelFormat;
import android.media.AudioManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.view.ViewCompat;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.ImageButton;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView;
import android.widget.Toast;

import com.afollestad.materialdialogs.MaterialDialog;
import com.bumptech.glide.Glide;
import com.joanzapata.iconify.IconDrawable;
import com.joanzapata.iconify.fonts.FontAwesomeIcons;

import de.danoeh.antennapod.R;
import de.danoeh.antennapod.core.feed.FeedItem;
import de.danoeh.antennapod.core.feed.FeedMedia;
import de.danoeh.antennapod.core.preferences.UserPreferences;
import de.danoeh.antennapod.core.service.playback.PlaybackService;
import de.danoeh.antennapod.core.storage.DBReader;
import de.danoeh.antennapod.core.storage.DBTasks;
import de.danoeh.antennapod.core.storage.DBWriter;
import de.danoeh.antennapod.core.util.Converter;
import de.danoeh.antennapod.core.util.ShareUtils;
import de.danoeh.antennapod.core.util.StorageUtils;
import de.danoeh.antennapod.core.util.playback.MediaPlayerError;
import de.danoeh.antennapod.core.util.playback.Playable;
import de.danoeh.antennapod.core.util.playback.PlaybackController;
import de.danoeh.antennapod.dialog.SleepTimerDialog;
import de.danoeh.antennapod.dialog.VariableSpeedDialog;
import rx.Observable;
import rx.android.schedulers.AndroidSchedulers;
import rx.schedulers.Schedulers;


/**
 * Provides general features which are both needed for playing audio and video
 * files.
 */
public abstract class MediaplayerActivity extends AppCompatActivity implements OnSeekBarChangeListener {
    private static final String TAG = "MediaplayerActivity";
    private static final String PREFS = "MediaPlayerActivityPreferences";
    private static final String PREF_SHOW_TIME_LEFT = "showTimeLeft";

    protected PlaybackController controller;

    protected TextView txtvPosition;
    protected TextView txtvLength;
    protected SeekBar sbPosition;
    protected Button butPlaybackSpeed;
    protected ImageButton butRev;
    protected TextView txtvRev;
    protected ImageButton butPlay;
    protected ImageButton butFF;
    protected TextView txtvFF;
    protected ImageButton butSkip;

    protected boolean showTimeLeft = false;

    private boolean isFavorite = false;

    private PlaybackController newPlaybackController() {
        return new PlaybackController(this, false) {

            @Override
            public void setupGUI() {
                MediaplayerActivity.this.setupGUI();
            }

            @Override
            public void onPositionObserverUpdate() {
                MediaplayerActivity.this.onPositionObserverUpdate();
            }

            @Override
            public void onBufferStart() {
                MediaplayerActivity.this.onBufferStart();
            }

            @Override
            public void onBufferEnd() {
                MediaplayerActivity.this.onBufferEnd();
            }

            @Override
            public void onBufferUpdate(float progress) {
                MediaplayerActivity.this.onBufferUpdate(progress);
            }

            @Override
            public void handleError(int code) {
                MediaplayerActivity.this.handleError(code);
            }

            @Override
            public void onReloadNotification(int code) {
                MediaplayerActivity.this.onReloadNotification(code);
            }

            @Override
            public void onSleepTimerUpdate() {
                supportInvalidateOptionsMenu();
            }

            @Override
            public ImageButton getPlayButton() {
                return butPlay;
            }

            @Override
            public void postStatusMsg(int msg) {
                MediaplayerActivity.this.postStatusMsg(msg);
            }

            @Override
            public void clearStatusMsg() {
                MediaplayerActivity.this.clearStatusMsg();
            }

            @Override
            public boolean loadMediaInfo() {
                return MediaplayerActivity.this.loadMediaInfo();
            }

            @Override
            public void onAwaitingVideoSurface() {
                MediaplayerActivity.this.onAwaitingVideoSurface();
            }

            @Override
            public void onServiceQueried() {
                MediaplayerActivity.this.onServiceQueried();
            }

            @Override
            public void onShutdownNotification() {
                finish();
            }

            @Override
            public void onPlaybackEnd() {
                finish();
            }

            @Override
            public void onPlaybackSpeedChange() {
                MediaplayerActivity.this.onPlaybackSpeedChange();
            }

            @Override
            protected void setScreenOn(boolean enable) {
                super.setScreenOn(enable);
                MediaplayerActivity.this.setScreenOn(enable);
            }
        };

    }

    protected void onPlaybackSpeedChange() {
        updateButPlaybackSpeed();
    }

    protected void onServiceQueried() {
        supportInvalidateOptionsMenu();
    }

    protected void chooseTheme() {
        setTheme(UserPreferences.getTheme());
    }

    protected void setScreenOn(boolean enable) {
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        chooseTheme();
        super.onCreate(savedInstanceState);

        Log.d(TAG, "onCreate()");
        StorageUtils.checkStorageAvailability(this);
        setVolumeControlStream(AudioManager.STREAM_MUSIC);

        orientation = getResources().getConfiguration().orientation;
        getWindow().setFormat(PixelFormat.TRANSPARENT);
    }

    @Override
    protected void onPause() {
        super.onPause();
        controller.reinitServiceIfPaused();
        controller.pause();
    }

    /**
     * Should be used to switch to another player activity if the mime type is
     * not the correct one for the current activity.
     */
    protected abstract void onReloadNotification(int notificationCode);

    /**
     * Should be used to inform the user that the PlaybackService is currently
     * buffering.
     */
    protected abstract void onBufferStart();

    /**
     * Should be used to hide the view that was showing the 'buffering'-message.
     */
    protected abstract void onBufferEnd();

    protected void onBufferUpdate(float progress) {
        if (sbPosition != null) {
            sbPosition.setSecondaryProgress((int) progress
                    * sbPosition.getMax());
        }
    }

    /**
     * Current screen orientation.
     */
    protected int orientation;

    @Override
    protected void onStart() {
        super.onStart();
        if (controller != null) {
            controller.release();
        }
        controller = newPlaybackController();
    }

    @Override
    protected void onStop() {
        super.onStop();
        Log.d(TAG, "onStop()");
        if (controller != null) {
            controller.release();
        }
    }

    @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
    @Override
    public void onTrimMemory(int level) {
        super.onTrimMemory(level);
        Glide.get(this).trimMemory(level);
    }

    @Override
    public void onLowMemory() {
        super.onLowMemory();
        Glide.get(this).clearMemory();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        super.onCreateOptionsMenu(menu);
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.mediaplayer, menu);
        return true;
    }

    @Override
    public boolean onPrepareOptionsMenu(Menu menu) {
        super.onPrepareOptionsMenu(menu);
        if (controller == null) {
            return false;
        }
        Playable media = controller.getMedia();

        menu.findItem(R.id.support_item).setVisible(
                media != null && media.getPaymentLink() != null &&
                        (media instanceof FeedMedia) &&
                        ((FeedMedia) media).getItem() != null &&
                        ((FeedMedia) media).getItem().getFlattrStatus().flattrable()
        );

        boolean hasWebsiteLink = media != null && media.getWebsiteLink() != null;
        menu.findItem(R.id.visit_website_item).setVisible(hasWebsiteLink);

        boolean isItemAndHasLink = media != null && (media instanceof FeedMedia) &&
                ((FeedMedia) media).getItem() != null && ((FeedMedia) media).getItem().getLink() != null;
        menu.findItem(R.id.share_link_item).setVisible(isItemAndHasLink);
        menu.findItem(R.id.share_link_with_position_item).setVisible(isItemAndHasLink);

        boolean isItemHasDownloadLink = media != null && (media instanceof FeedMedia) && ((FeedMedia) media).getDownload_url() != null;
        menu.findItem(R.id.share_download_url_item).setVisible(isItemHasDownloadLink);
        menu.findItem(R.id.share_download_url_with_position_item).setVisible(isItemHasDownloadLink);

        menu.findItem(R.id.share_item).setVisible(hasWebsiteLink || isItemAndHasLink || isItemHasDownloadLink);

        menu.findItem(R.id.add_to_favorites_item).setVisible(false);
        menu.findItem(R.id.remove_from_favorites_item).setVisible(false);
        if(media != null && media instanceof FeedMedia) {
            menu.findItem(R.id.add_to_favorites_item).setVisible(!isFavorite);
            menu.findItem(R.id.remove_from_favorites_item).setVisible(isFavorite);
        }

        boolean sleepTimerSet = controller.sleepTimerActive();
        boolean sleepTimerNotSet = controller.sleepTimerNotActive();
        menu.findItem(R.id.set_sleeptimer_item).setVisible(sleepTimerNotSet);
        menu.findItem(R.id.disable_sleeptimer_item).setVisible(sleepTimerSet);

        if (this instanceof AudioplayerActivity) {
            int[] attrs = {R.attr.action_bar_icon_color};
            TypedArray ta = obtainStyledAttributes(UserPreferences.getTheme(), attrs);
            int textColor = ta.getColor(0, Color.GRAY);
            ta.recycle();
            menu.findItem(R.id.audio_controls).setIcon(new IconDrawable(this,
                    FontAwesomeIcons.fa_sliders).color(textColor).actionBarSize());
        } else {
            menu.findItem(R.id.audio_controls).setVisible(false);
        }

        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        if (controller == null) {
            return false;
        }
        Playable media = controller.getMedia();
        if (item.getItemId() == android.R.id.home) {
            Intent intent = new Intent(MediaplayerActivity.this,
                    MainActivity.class);
            intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP
                    | Intent.FLAG_ACTIVITY_NEW_TASK);
            startActivity(intent);
            return true;
        } else {
            if (media != null) {
                switch (item.getItemId()) {
                    case R.id.add_to_favorites_item:
                        if(media instanceof FeedMedia) {
                            FeedItem feedItem = ((FeedMedia)media).getItem();
                            if(feedItem != null) {
                                DBWriter.addFavoriteItem(feedItem);
                                isFavorite = true;
                                invalidateOptionsMenu();
                                Toast.makeText(this, R.string.added_to_favorites, Toast.LENGTH_SHORT)
                                     .show();
                            }
                        }
                        break;
                    case R.id.remove_from_favorites_item:
                        if(media instanceof FeedMedia) {
                            FeedItem feedItem = ((FeedMedia)media).getItem();
                            if(feedItem != null) {
                                DBWriter.removeFavoriteItem(feedItem);
                                isFavorite = false;
                                invalidateOptionsMenu();
                                Toast.makeText(this, R.string.removed_from_favorites, Toast.LENGTH_SHORT)
                                     .show();
                            }
                        }
                        break;
                    case R.id.disable_sleeptimer_item:
                        if (controller.serviceAvailable()) {

                            MaterialDialog.Builder stDialog = new MaterialDialog.Builder(this);
                            stDialog.title(R.string.sleep_timer_label);
                            stDialog.content(getString(R.string.time_left_label)
                                    + Converter.getDurationStringLong((int) controller
                                    .getSleepTimerTimeLeft()));
                            stDialog.positiveText(R.string.disable_sleeptimer_label);
                            stDialog.negativeText(R.string.cancel_label);
                            stDialog.callback(new MaterialDialog.ButtonCallback() {
                                @Override
                                public void onPositive(MaterialDialog dialog) {
                                    dialog.dismiss();
                                    controller.disableSleepTimer();
                                }

                                @Override
                                public void onNegative(MaterialDialog dialog) {
                                    dialog.dismiss();
                                }
                            });
                            stDialog.build().show();
                        }
                        break;
                    case R.id.set_sleeptimer_item:
                        if (controller.serviceAvailable()) {
                            SleepTimerDialog td = new SleepTimerDialog(this) {
                                @Override
                                public void onTimerSet(long millis, boolean shakeToReset, boolean vibrate) {
                                    controller.setSleepTimer(millis, shakeToReset, vibrate);
                                }
                            };
                            td.createNewDialog().show();
                        }
                        break;
                    case R.id.audio_controls:
                        MaterialDialog dialog = new MaterialDialog.Builder(this)
                                .title(R.string.audio_controls)
                                .customView(R.layout.audio_controls, false)
                                .neutralText(R.string.close_label)
                                .onNeutral((dialog1, which) -> {
                                    final SeekBar left = (SeekBar) dialog1.findViewById(R.id.volume_left);
                                    final SeekBar right = (SeekBar) dialog1.findViewById(R.id.volume_right);
                                    UserPreferences.setVolume(left.getProgress(), right.getProgress());
                                })
                                .show();
                        final SeekBar barPlaybackSpeed = (SeekBar) dialog.findViewById(R.id.playback_speed);
                        final Button butDecSpeed = (Button) dialog.findViewById(R.id.butDecSpeed);
                        butDecSpeed.setOnClickListener(v -> {
                            if(controller != null && controller.canSetPlaybackSpeed()) {
                                barPlaybackSpeed.setProgress(barPlaybackSpeed.getProgress() - 2);
                            } else {
                                VariableSpeedDialog.showGetPluginDialog(this);
                            }
                        });
                        final Button butIncSpeed = (Button) dialog.findViewById(R.id.butIncSpeed);
                        butIncSpeed.setOnClickListener(v -> {
                            if(controller != null && controller.canSetPlaybackSpeed()) {
                                barPlaybackSpeed.setProgress(barPlaybackSpeed.getProgress() + 2);
                            } else {
                                VariableSpeedDialog.showGetPluginDialog(this);
                            }
                        });

                        final TextView txtvPlaybackSpeed = (TextView) dialog.findViewById(R.id.txtvPlaybackSpeed);
                        float currentSpeed = 1.0f;
                        try {
                            currentSpeed = Float.parseFloat(UserPreferences.getPlaybackSpeed());
                        } catch (NumberFormatException e) {
                            Log.e(TAG, Log.getStackTraceString(e));
                            UserPreferences.setPlaybackSpeed(String.valueOf(currentSpeed));
                        }

                        txtvPlaybackSpeed.setText(String.format("%.2fx", currentSpeed));
                        barPlaybackSpeed.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
                            @Override
                            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                                if(controller != null && controller.canSetPlaybackSpeed()) {
                                    float playbackSpeed = (progress + 10) / 20.0f;
                                    controller.setPlaybackSpeed(playbackSpeed);
                                    String speed = String.format("%.2f", playbackSpeed);
                                    UserPreferences.setPlaybackSpeed(speed);
                                    txtvPlaybackSpeed.setText(speed + "x");
                                } else if(fromUser) {
                                    float speed = Float.valueOf(UserPreferences.getPlaybackSpeed());
                                    barPlaybackSpeed.post(() -> {
                                        barPlaybackSpeed.setProgress((int) (20 * speed) - 10);
                                    });
                                }
                            }

                            @Override
                            public void onStartTrackingTouch(SeekBar seekBar) {
                                if(controller != null && !controller.canSetPlaybackSpeed()) {
                                    VariableSpeedDialog.showGetPluginDialog(MediaplayerActivity.this);
                                }
                            }

                            @Override
                            public void onStopTrackingTouch(SeekBar seekBar) {
                            }
                        });
                        barPlaybackSpeed.setProgress((int) (20 * currentSpeed) - 10);

                        final SeekBar barLeftVolume = (SeekBar) dialog.findViewById(R.id.volume_left);
                        barLeftVolume.setProgress(100);
                        final SeekBar barRightVolume = (SeekBar) dialog.findViewById(R.id.volume_right);
                        barRightVolume.setProgress(100);
                        final CheckBox stereoToMono = (CheckBox) dialog.findViewById(R.id.stereo_to_mono);
                        stereoToMono.setChecked(UserPreferences.stereoToMono());
                        if (controller != null && !controller.canDownmix()) {
                            stereoToMono.setEnabled(false);
                            String sonicOnly = getString(R.string.sonic_only);
                            stereoToMono.setText(stereoToMono.getText() + " [" + sonicOnly + "]");
                        }

                        barLeftVolume.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
                            @Override
                            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                                float leftVolume = 1.0f, rightVolume = 1.0f;
                                if (progress < 100) {
                                    leftVolume = progress / 100.0f;
                                }
                                if (barRightVolume.getProgress() < 100) {
                                    rightVolume = barRightVolume.getProgress() / 100.0f;
                                }
                                controller.setVolume(leftVolume, rightVolume);
                            }

                            @Override
                            public void onStartTrackingTouch(SeekBar seekBar) {
                            }

                            @Override
                            public void onStopTrackingTouch(SeekBar seekBar) {
                            }
                        });
                        barRightVolume.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
                            @Override
                            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                                float leftVolume = 1.0f, rightVolume = 1.0f;
                                if (progress < 100) {
                                    rightVolume = progress / 100.0f;
                                }
                                if (barLeftVolume.getProgress() < 100) {
                                    leftVolume = barLeftVolume.getProgress() / 100.0f;
                                }
                                controller.setVolume(leftVolume, rightVolume);
                            }

                            @Override
                            public void onStartTrackingTouch(SeekBar seekBar) {
                            }

                            @Override
                            public void onStopTrackingTouch(SeekBar seekBar) {
                            }
                        });
                        stereoToMono.setOnCheckedChangeListener((buttonView, isChecked) -> {
                            UserPreferences.stereoToMono(isChecked);
                            if (controller != null) {
                                controller.setDownmix(isChecked);
                            }
                        });
                        break;
                    case R.id.visit_website_item:
                        Uri uri = Uri.parse(media.getWebsiteLink());
                        startActivity(new Intent(Intent.ACTION_VIEW, uri));
                        break;
                    case R.id.support_item:
                        if (media instanceof FeedMedia) {
                            DBTasks.flattrItemIfLoggedIn(this, ((FeedMedia) media).getItem());
                        }
                        break;
                    case R.id.share_link_item:
                        if (media instanceof FeedMedia) {
                            ShareUtils.shareFeedItemLink(this, ((FeedMedia) media).getItem());
                        }
                        break;
                    case R.id.share_download_url_item:
                        if (media instanceof FeedMedia) {
                            ShareUtils.shareFeedItemDownloadLink(this, ((FeedMedia) media).getItem());
                        }
                        break;
                    case R.id.share_link_with_position_item:
                        if (media instanceof FeedMedia) {
                            ShareUtils.shareFeedItemLink(this, ((FeedMedia) media).getItem(), true);
                        }
                        break;
                    case R.id.share_download_url_with_position_item:
                        if (media instanceof FeedMedia) {
                            ShareUtils.shareFeedItemDownloadLink(this, ((FeedMedia) media).getItem(), true);
                        }
                        break;
                    default:
                        return false;
                }
                return true;
            } else {
                return false;
            }
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        Log.d(TAG, "onResume()");
        StorageUtils.checkStorageAvailability(this);
        controller.init();
    }

    /**
     * Called by 'handleStatus()' when the PlaybackService is waiting for
     * a video surface.
     */
    protected abstract void onAwaitingVideoSurface();

    protected abstract void postStatusMsg(int resId);

    protected abstract void clearStatusMsg();

    protected void onPositionObserverUpdate() {
        if (controller != null) {
            int currentPosition = controller.getPosition();
            int duration = controller.getDuration();
            Log.d(TAG, "currentPosition " + Converter
                    .getDurationStringLong(currentPosition));
            if (currentPosition != PlaybackService.INVALID_TIME
                    && duration != PlaybackService.INVALID_TIME
                    && controller.getMedia() != null) {
                txtvPosition.setText(Converter
                        .getDurationStringLong(currentPosition));
                if (showTimeLeft) {
                    txtvLength.setText("-" + Converter
                            .getDurationStringLong(duration - currentPosition));
                } else {
                    txtvLength.setText(Converter
                            .getDurationStringLong(duration));
                }
                updateProgressbarPosition(currentPosition, duration);
            } else {
                Log.w(TAG, "Could not react to position observer update because of invalid time");
            }
        }
    }

    private void updateProgressbarPosition(int position, int duration) {
        Log.d(TAG, "updateProgressbarPosition(" + position + ", " + duration + ")");
        float progress = ((float) position) / duration;
        sbPosition.setProgress((int) (progress * sbPosition.getMax()));
    }

    /**
     * Load information about the media that is going to be played or currently
     * being played. This method will be called when the activity is connected
     * to the PlaybackService to ensure that the activity has the right
     * FeedMedia object.
     */
    protected boolean loadMediaInfo() {
        Log.d(TAG, "loadMediaInfo()");
        Playable media = controller.getMedia();
        SharedPreferences prefs = getSharedPreferences(PREFS, MODE_PRIVATE);
        showTimeLeft = prefs.getBoolean(PREF_SHOW_TIME_LEFT, false);
        if (media != null) {
            txtvPosition.setText(Converter.getDurationStringLong((media.getPosition())));

            if (media.getDuration() != 0) {
                txtvLength.setText(Converter.getDurationStringLong(media.getDuration()));
                float progress = ((float) media.getPosition()) / media.getDuration();
                sbPosition.setProgress((int) (progress * sbPosition.getMax()));
                if (showTimeLeft) {
                    int timeLeft = media.getDuration() - media.getPosition();
                    txtvLength.setText("-" + Converter.getDurationStringLong(timeLeft));
                }
            }
            checkFavorite();
            if(butPlaybackSpeed != null) {
                if (controller == null) {
                    butPlaybackSpeed.setVisibility(View.GONE);
                } else {
                    butPlaybackSpeed.setVisibility(View.VISIBLE);
                    if (controller.canSetPlaybackSpeed()) {
                        ViewCompat.setAlpha(butPlaybackSpeed, 1.0f);
                    } else {
                        ViewCompat.setAlpha(butPlaybackSpeed, 0.5f);
                    }
                }
                updateButPlaybackSpeed();
            }
            return true;
        } else {
            return false;
        }
    }

    protected void setupGUI() {
        setContentView(getContentViewResourceId());
        sbPosition = (SeekBar) findViewById(R.id.sbPosition);
        txtvPosition = (TextView) findViewById(R.id.txtvPosition);

        SharedPreferences prefs = getSharedPreferences(PREFS, MODE_PRIVATE);
        showTimeLeft = prefs.getBoolean(PREF_SHOW_TIME_LEFT, false);
        Log.d("timeleft", showTimeLeft ? "true" : "false");
        txtvLength = (TextView) findViewById(R.id.txtvLength);
        txtvLength.setOnClickListener(v -> {
            showTimeLeft = !showTimeLeft;
            Playable media = controller.getMedia();
            if (media == null) {
                return;
            }

            String length;
            if (showTimeLeft) {
                length = "-" + Converter.getDurationStringLong(media.getDuration() - media.getPosition());
            } else {
                length = Converter.getDurationStringLong(media.getDuration());
            }
            txtvLength.setText(length);

            SharedPreferences.Editor editor = prefs.edit();
            editor.putBoolean(PREF_SHOW_TIME_LEFT, showTimeLeft);
            editor.apply();
            Log.d("timeleft on click", showTimeLeft ? "true" : "false");
        });

        butPlaybackSpeed = (Button) findViewById(R.id.butPlaybackSpeed);
        butRev = (ImageButton) findViewById(R.id.butRev);
        txtvRev = (TextView) findViewById(R.id.txtvRev);
        if (txtvRev != null) {
            txtvRev.setText(String.valueOf(UserPreferences.getRewindSecs()));
        }
        butPlay = (ImageButton) findViewById(R.id.butPlay);
        butFF = (ImageButton) findViewById(R.id.butFF);
        txtvFF = (TextView) findViewById(R.id.txtvFF);
        if (txtvFF != null) {
            txtvFF.setText(String.valueOf(UserPreferences.getFastFowardSecs()));
        }
        butSkip = (ImageButton) findViewById(R.id.butSkip);

        // SEEKBAR SETUP

        sbPosition.setOnSeekBarChangeListener(this);

        // BUTTON SETUP

        if(butPlaybackSpeed != null) {
            butPlaybackSpeed.setOnClickListener(v -> {
                if (controller == null) {
                    return;
                }
                if (controller.canSetPlaybackSpeed()) {
                    String[] availableSpeeds = UserPreferences.getPlaybackSpeedArray();
                    String currentSpeed = UserPreferences.getPlaybackSpeed();

                    // Provide initial value in case the speed list has changed
                    // out from under us
                    // and our current speed isn't in the new list
                    String newSpeed;
                    if (availableSpeeds.length > 0) {
                        newSpeed = availableSpeeds[0];
                    } else {
                        newSpeed = "1.00";
                    }

                    for (int i = 0; i < availableSpeeds.length; i++) {
                        if (availableSpeeds[i].equals(currentSpeed)) {
                            if (i == availableSpeeds.length - 1) {
                                newSpeed = availableSpeeds[0];
                            } else {
                                newSpeed = availableSpeeds[i + 1];
                            }
                            break;
                        }
                    }
                    UserPreferences.setPlaybackSpeed(newSpeed);
                    controller.setPlaybackSpeed(Float.parseFloat(newSpeed));
                } else {
                    VariableSpeedDialog.showGetPluginDialog(this);
                }
            });
            butPlaybackSpeed.setOnLongClickListener(v -> {
                VariableSpeedDialog.showDialog(this);
                return true;
            });
        }

        if (butRev != null) {
            butRev.setOnClickListener(v -> {
                int curr = controller.getPosition();
                controller.seekTo(curr - UserPreferences.getRewindSecs() * 1000);
            });
            butRev.setOnLongClickListener(new View.OnLongClickListener() {

                int choice;

                @Override
                public boolean onLongClick(View v) {
                    int checked = 0;
                    int rewindSecs = UserPreferences.getRewindSecs();
                    final int[] values = getResources().getIntArray(R.array.seek_delta_values);
                    final String[] choices = new String[values.length];
                    for (int i = 0; i < values.length; i++) {
                        if (rewindSecs == values[i]) {
                            checked = i;
                        }
                        choices[i] = String.valueOf(values[i]) + " " + getString(R.string.time_seconds);
                    }
                    choice = values[checked];
                    AlertDialog.Builder builder = new AlertDialog.Builder(MediaplayerActivity.this);
                    builder.setTitle(R.string.pref_rewind);
                    builder.setSingleChoiceItems(choices, checked,
                            (dialog, which) -> {
                                choice = values[which];
                            });
                    builder.setNegativeButton(R.string.cancel_label, null);
                    builder.setPositiveButton(R.string.confirm_label, (dialog, which) -> {
                        UserPreferences.setPrefRewindSecs(choice);
                        txtvRev.setText(String.valueOf(choice));
                    });
                    builder.create().show();
                    return true;
                }
            });
        }

        butPlay.setOnClickListener(controller.newOnPlayButtonClickListener());

        if (butFF != null) {
            butFF.setOnClickListener(v -> {
                int curr = controller.getPosition();
                controller.seekTo(curr + UserPreferences.getFastFowardSecs() * 1000);
            });
            butFF.setOnLongClickListener(new View.OnLongClickListener() {

                int choice;

                @Override
                public boolean onLongClick(View v) {
                    int checked = 0;
                    int rewindSecs = UserPreferences.getFastFowardSecs();
                    final int[] values = getResources().getIntArray(R.array.seek_delta_values);
                    final String[] choices = new String[values.length];
                    for (int i = 0; i < values.length; i++) {
                        if (rewindSecs == values[i]) {
                            checked = i;
                        }
                        choices[i] = String.valueOf(values[i]) + " " + getString(R.string.time_seconds);
                    }
                    choice = values[checked];
                    AlertDialog.Builder builder = new AlertDialog.Builder(MediaplayerActivity.this);
                    builder.setTitle(R.string.pref_fast_forward);
                    builder.setSingleChoiceItems(choices, checked,
                            (dialog, which) -> {
                                choice = values[which];
                            });
                    builder.setNegativeButton(R.string.cancel_label, null);
                    builder.setPositiveButton(R.string.confirm_label, (dialog, which) -> {
                        UserPreferences.setPrefFastForwardSecs(choice);
                        txtvFF.setText(String.valueOf(choice));
                    });
                    builder.create().show();
                    return true;
                }
            });
        }

        if (butSkip != null) {
            butSkip.setOnClickListener(v -> {
                sendBroadcast(new Intent(PlaybackService.ACTION_SKIP_CURRENT_EPISODE));
            });
        }
    }

    protected abstract int getContentViewResourceId();

    void handleError(int errorCode) {
        final AlertDialog.Builder errorDialog = new AlertDialog.Builder(this);
        errorDialog.setTitle(R.string.error_label);
        errorDialog
                .setMessage(MediaPlayerError.getErrorString(this, errorCode));
        errorDialog.setNeutralButton("OK",
                (dialog, which) -> {
                    dialog.dismiss();
                    finish();
                }
        );
        errorDialog.create().show();
    }

    float prog;

    @Override
    public void onProgressChanged (SeekBar seekBar,int progress, boolean fromUser) {
        if (controller != null) {
            prog = controller.onSeekBarProgressChanged(seekBar, progress, fromUser, txtvPosition);
            if (showTimeLeft && prog != 0) {
                int duration = controller.getDuration();
                String length = "-" + Converter.getDurationStringLong(duration - (int) (prog * duration));
                txtvLength.setText(length);
            }
        }
    }

    private void updateButPlaybackSpeed() {
        if (controller != null && butPlaybackSpeed != null) {
            butPlaybackSpeed.setText(UserPreferences.getPlaybackSpeed() + "x");
        }
    }

    @Override
    public void onStartTrackingTouch(SeekBar seekBar) {
        if (controller != null) {
            controller.onSeekBarStartTrackingTouch(seekBar);
        }
    }

    @Override
    public void onStopTrackingTouch(SeekBar seekBar) {
        if (controller != null) {
            controller.onSeekBarStopTrackingTouch(seekBar, prog);
        }
    }

    private void checkFavorite() {
        Playable playable = controller.getMedia();
            if (playable != null && playable instanceof FeedMedia) {
                FeedItem feedItem = ((FeedMedia) playable).getItem();
                if (feedItem != null) {
                    Observable.fromCallable(() -> DBReader.getFeedItem(feedItem.getId()))
                            .subscribeOn(Schedulers.newThread())
                            .observeOn(AndroidSchedulers.mainThread())
                            .subscribe(item -> {
                                boolean isFav = item.isTagged(FeedItem.TAG_FAVORITE);
                                if(isFavorite != isFav) {
                                    isFavorite = isFav;
                                    invalidateOptionsMenu();
                                }
                            });
                }
            }
    }

}
