package com.sahdeepsingh.Bop.services;

/*
 * This to be done in Service
 * 1. add transport controls
 * 2. lol for now
 * */

import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.ContentUris;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Binder;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.PowerManager;
import android.os.RemoteException;
import android.support.v4.media.MediaBrowserCompat;
import android.support.v4.media.MediaMetadataCompat;
import android.support.v4.media.session.MediaSessionCompat;
import android.support.v4.media.session.PlaybackStateCompat;
import android.text.TextUtils;
import android.util.Log;
import android.view.KeyEvent;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.media.MediaBrowserServiceCompat;
import androidx.media.session.MediaButtonReceiver;

import com.sahdeepsingh.Bop.BopUtils.ExtraUtils;
import com.sahdeepsingh.Bop.BopUtils.RecentUtils;
import com.sahdeepsingh.Bop.Handlers.NotificationHandler;
import com.sahdeepsingh.Bop.R;
import com.sahdeepsingh.Bop.SongData.Song;
import com.sahdeepsingh.Bop.playerMain.Main;

import java.io.IOException;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Random;

public class ServicePlayMusic extends MediaBrowserServiceCompat
        implements MediaPlayer.OnPreparedListener,
        MediaPlayer.OnErrorListener,
        MediaPlayer.OnCompletionListener,
        AudioManager.OnAudioFocusChangeListener {


    public static final String ACTION_CMD = "com.sahdeepsingh.Bop.ACTION_CMD";

    public static final String CMD_NAME = "BopPlayer";

    public static final String ACTION_PAUSE = "ACTION_PAUSE";
    //to handle the click delay if the the headshook is double clicked within 5ms
    static final long CLICK_DELAY = 500;
    //handling the pause event and stop service after 5 min if paused
    private static final int STOP_DELAY = Main.settings.get("sleepTimer", 5) * 60000;
    //A static class to handle delay callbacks
    private final DelayedStopHandler mDelayedStopHandler = new DelayedStopHandler(this);

    static long lastClick = 0;


    // The tag we put on debug messages
    final static String TAG = "MusicService";

    /**
     * Token for the interaction between an Activity and this Service.
     */
    private final IBinder musicBind = new MusicBinder();
    /**
     * Index of the current song we're playing on the `data` list.
     */
    public int currentSongPosition;
    /**
     * Copy of the current song being played (or paused).
     * <p>
     * Use it to get info from the current song.
     */
    public Song currentSong = null;
    /**
     * Tells if this service is bound to an Activity.
     */
    public boolean musicBound = false;
    /**
     * Current state of the Service.
     */
    ServiceState serviceState = ServiceState.Preparing;
    /**
     * Use this to get audio focus:
     * <p>
     * 1. Making sure other music apps don't play
     * at the same time;
     */
    AudioManager audioManager;
    //Just migrated to it to support everything where we are lacking
    public MediaSessionCompat mMediaSessionCompat;

    /**
     * Android Media Player - we control it in here.
     */
    public MediaPlayer player;
    /**
     * List of data we're  currently playing.
     */
    private ArrayList<Song> songs;
    /**
     * Flag that indicates whether we're at Shuffle mode.
     */
    private boolean shuffleMode = false;
    /**
     * Random number generator for the Shuffle Mode.
     */
    private Random randomNumberGenerator;
    // 0 single, 1 repeat on , 2 repeat off
    private int repeatMode = 0;
    /**
     * Spawns an on-going notification with our current
     * playing song.
     */
    // private NotificationMusic notification = null;
    NotificationHandler notificationManager;


    private boolean pausedTemporarilyDueToAudioFocus = false;
    private boolean loweredVolumeDueToAudioFocus = false;

    //pausing player if getting noise
    private BroadcastReceiver mNoisyReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (AudioManager.ACTION_AUDIO_BECOMING_NOISY.equals(intent.getAction())) {
                if (Main.settings.get("pauseHeadphoneUnplugged", true)) {
                    pausePlayer();
                }
            } else if (Intent.ACTION_HEADSET_PLUG.equals(intent.getAction())) {
                int state = intent.getIntExtra("state", -1);
                switch (state) {
                    case 0:
                        if (Main.settings.get("pauseHeadphoneUnplugged", true)) {
                            pausePlayer();
                        } else unpausePlayer();
                        break;
                    case 1:
                        if (Main.settings.get("resumeHeadphonePlugged", true)) {
                            unpausePlayer();
                        } else pausePlayer();
                        break;
                }
            }
        }
    };

    //Handling call backs whenever the controlls are broadcasted, also handling headphones event here
    private MediaSessionCompat.Callback mMediaSessionCallback = new MediaSessionCompat.Callback() {

        @Override
        public boolean onMediaButtonEvent(Intent mediaButtonEvent) {
            final String intentAction = mediaButtonEvent.getAction();
            if (Intent.ACTION_MEDIA_BUTTON.equals(intentAction)) {
                final KeyEvent event = mediaButtonEvent.getParcelableExtra(Intent.EXTRA_KEY_EVENT);
                if (event == null) return super.onMediaButtonEvent(mediaButtonEvent);
                final int keycode = event.getKeyCode();
                final int action = event.getAction();
                final long eventTime = event.getEventTime();
                if (event.getRepeatCount() == 0 && action == KeyEvent.ACTION_DOWN) {

                    switch (keycode) {
                        case KeyEvent.KEYCODE_HEADSETHOOK:
                            if (!Main.settings.get("headphoneControl", true))
                                break;
                            if (eventTime - lastClick < CLICK_DELAY) {
                                next(true);
                                playSong();
                                lastClick = 0;
                            } else {
                                if (isPlaying())
                                    pausePlayer();
                                else unpausePlayer();
                                lastClick = eventTime;
                            }
                            break;
                        case KeyEvent.KEYCODE_MEDIA_STOP:
                            stopMusicPlayer();
                            break;
                        case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
                            if (Main.mainMenuHasNowPlayingItem) {
                                if (isPlaying()) pausePlayer();
                                else unpausePlayer();
                            }
                            break;
                        case KeyEvent.KEYCODE_MEDIA_NEXT:
                            next(true);
                            playSong();
                            break;
                        case KeyEvent.KEYCODE_MEDIA_PREVIOUS:
                            previous(true);
                            playSong();
                            break;
                        case KeyEvent.KEYCODE_MEDIA_PAUSE:
                            pausePlayer();
                            break;
                        case KeyEvent.KEYCODE_MEDIA_PLAY:
                            unpausePlayer();
                            break;
                    }
                }
            }
            return super.onMediaButtonEvent(mediaButtonEvent);
        }

        @Override
        public void onPlay() {
            super.onPlay();
            unpausePlayer();
        }

        @Override
        public void onPlayFromMediaId(String mediaId, Bundle extras) {
            super.onPlayFromMediaId(mediaId, extras);
            playSong();
        }

        @Override
        public void onSeekTo(long pos) {
            super.onSeekTo(pos);
            seekTo((int) pos);
        }

        @Override
        public void onPause() {
            super.onPause();
            pausePlayer();
        }

        @Override
        public void onSkipToNext() {
            super.onSkipToNext();
            next(true);
            playSong();
        }

        @Override
        public void onSkipToPrevious() {
            super.onSkipToPrevious();
            previous(true);
            playSong();
        }

        @Override
        public void onStop() {
            super.onStop();
            stopMusicPlayer();
        }
    };


    //Now the Actual game Begins

    public void onCreate() {
        super.onCreate();

        currentSongPosition = 0;

        randomNumberGenerator = new Random();

        audioManager = (AudioManager) getSystemService(AUDIO_SERVICE);

        initMusicPlayer();

        initMediaSession();

        initNoisyReceiver();


        try {
            notificationManager = new NotificationHandler(this);
        } catch (RemoteException e) {
            throw new IllegalStateException("Could not create a NotificationHandler", e);
        }

    }

    private void initNoisyReceiver() {
        //Handles headphones coming unplugged. cannot be done through a manifest receiver
        IntentFilter filter = new IntentFilter();
        filter.addAction(AudioManager.ACTION_AUDIO_BECOMING_NOISY);
        filter.addAction(Intent.ACTION_HEADSET_PLUG);
        registerReceiver(mNoisyReceiver, filter);
    }

    private void initMediaSession() {
        ComponentName mediaButtonReceiver = new ComponentName(getApplicationContext(), MediaButtonReceiver.class);
        mMediaSessionCompat = new MediaSessionCompat(getApplicationContext(), "Tag", mediaButtonReceiver, null);

        mMediaSessionCompat.setCallback(mMediaSessionCallback);
        mMediaSessionCompat.setFlags(MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS | MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS);

        Intent mediaButtonIntent = new Intent(Intent.ACTION_MEDIA_BUTTON);
        mediaButtonIntent.setClass(this, MediaButtonReceiver.class);
        PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, mediaButtonIntent, 0);
        mMediaSessionCompat.setMediaButtonReceiver(pendingIntent);

        setSessionToken(mMediaSessionCompat.getSessionToken());
    }

    /**
     * Initializes the Android's internal MediaPlayer.
     */
    public void initMusicPlayer() {
        if (player == null)
            player = new MediaPlayer();

        // Assures the CPU continues running this service
        // even when the device is sleeping.
        player.setWakeMode(getApplicationContext(),
                PowerManager.PARTIAL_WAKE_LOCK);

        player.setAudioStreamType(AudioManager.STREAM_MUSIC);

        // These are the events that will "wake us up"
        player.setOnPreparedListener(this); // player initialized
        player.setOnCompletionListener(this); // song completed
        player.setOnErrorListener(this);

    }

    /**
     * Cleans resources from Android's native MediaPlayer.
     *
     * @note According to the MediaPlayer guide, you should release
     * the MediaPlayer as often as possible.
     * For example, when losing Audio Focus for an extended
     * period of time.
     */
    public void stopMusicPlayer() {
        if (player == null)
            return;
        Main.mainMenuHasNowPlayingItem = false;
        player.stop();
        player.release();
        player = null;
        notificationManager.stopNotification();
        mDelayedStopHandler.removeCallbacksAndMessages(null);

    }

    /**
     * Sets the "Now Playing List"
     */
    public void setList(ArrayList<Song> theSongs) {
        if (Main.settings.get("savePlaylist", true))
            RecentUtils.saveLastPlaylist(getApplicationContext(), theSongs);
        songs = theSongs;
        currentSongPosition = 0;
    }

    /**
     * Appends a song to the end of the currently playing queue.
     *
     * @param song New song to put at the end.
     */
    public void add(Song song) {
        songs.add(song);
    }

    /**
     * Asks the AudioManager for our application to
     * have the audio focus.
     */
    private boolean requestAudioFocus() {

        //Request audio focus for playback
        int result = audioManager.requestAudioFocus(
                this,
                AudioManager.STREAM_MUSIC,
                AudioManager.AUDIOFOCUS_GAIN);

        //Check if audio focus was granted. If not, stop the service.
        return (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED);
    }

    /**
     * Does something when the audio focus state changed
     *
     * @note Meaning it runs when we get and when we don't get
     * the audio focus from `#requestAudioFocus()`.
     * <p>
     * For example, when we receive a message, we lose the focus
     * and when the ringer stops playing, we get the focus again.
     * <p>
     * So we must avoid the bug that occurs when the user pauses
     * the player but receives a message - and since after that
     * we get the focus, the player will unpause.
     */
    public void onAudioFocusChange(int focusChange) {

        switch (focusChange) {

            // Yay, gained audio focus! Either from losing it for
            // a long or short periods of time.
            case AudioManager.AUDIOFOCUS_GAIN:

                if (player == null)
                    initMusicPlayer();

                if (pausedTemporarilyDueToAudioFocus) {
                    pausedTemporarilyDueToAudioFocus = false;
                    unpausePlayer();
                }

                if (loweredVolumeDueToAudioFocus) {
                    loweredVolumeDueToAudioFocus = false;
                    player.setVolume(1.0f, 1.0f);
                }
                break;

            // Damn, lost the audio focus for a (presumable) long time
            case AudioManager.AUDIOFOCUS_LOSS:
                stopMusicPlayer();
                break;

            // Just lost audio focus but will get it back shortly
            case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:

                if (!isPaused()) {
                    pausePlayer();
                    pausedTemporarilyDueToAudioFocus = true;
                }
                break;

            // Temporarily lost audio focus but I can keep it playing
            // at a low volume instead of stopping completely
            case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
                Log.w(TAG, "audiofocus loss transient can duck");

                player.setVolume(0.1f, 0.1f);
                loweredVolumeDueToAudioFocus = true;
                break;
        }
    }


    /**
     * Called when the music is ready for playback.
     */
    @Override
    public void onPrepared(MediaPlayer mp) {

        serviceState = ServiceState.Playing;

        // Start playback
        player.start();

        mMediaSessionCompat.setActive(true);
        mDelayedStopHandler.removeCallbacksAndMessages(null);
        setMediaPlaybackState(PlaybackStateCompat.STATE_PLAYING);


        // just crating new notification of current song
        notifyCurrentSong();
    }

    private void setMediaSessionMetaData() {
        mMediaSessionCompat.setMetadata(new MediaMetadataCompat.Builder()
                .putBitmap(MediaMetadataCompat.METADATA_KEY_ALBUM_ART, ExtraUtils.getBitmapfromAlbumId(getApplicationContext(), currentSong))
                .putString(MediaMetadataCompat.METADATA_KEY_ARTIST, currentSong.getArtist())
                .putString(MediaMetadataCompat.METADATA_KEY_ALBUM, currentSong.getAlbum())
                .putString(MediaMetadataCompat.METADATA_KEY_TITLE, currentSong.getTitle())
                .putLong(MediaMetadataCompat.METADATA_KEY_DURATION, currentSong.getDurationSeconds())
                .build());
    }

    /**
     * Sets a specific song, already within internal Now Playing List.
     *
     * @param songIndex Index of the song inside the Now Playing List.
     */
    public void setSong(int songIndex) {

        if (songIndex < 0 || songIndex >= songs.size())
            currentSongPosition = 0;
        else
            currentSongPosition = songIndex;
    }

    /**
     * Will be called when the music completes - either when the
     * user presses 'next' or when the music ends or when the user
     * selects another track.
     */
    @Override
    public void onCompletion(MediaPlayer mp) {

        // Keep this state!
        serviceState = ServiceState.Playing;

        // Repeating current song if desired
        if (repeatMode == 0) {
            playSong();
            return;
        }

        // Remember that by calling next(), if played
        // the last song on the list, will reset to the
        // first one.
        next(false);

        // Reached the end, should we restart playing
        // from the first song or simply stop?
        if (currentSongPosition == 0) {
            if (Main.settings.get("repeat_list", true))
                playSong();
            else
                destroySelf();
            return;
        }
        // Common case - skipped a track or anything
        playSong();
    }

    /**
     * If something wrong happens with the MusicPlayer.
     */
    @Override
    public boolean onError(MediaPlayer mp, int what, int extra) {
        mp.reset();
        Log.w(TAG, "onError");
        return false;
    }

    @Override
    public void onDestroy() {

        cancelNotification();

        currentSong = null;

        if (audioManager != null)
            audioManager.abandonAudioFocus(this);

        stopMusicPlayer();
        Log.w(TAG, "onDestroy");

        mDelayedStopHandler.removeCallbacksAndMessages(null);
        unregisterReceiver(mNoisyReceiver);
        super.onDestroy();
    }

    /**
     * Kills the service.
     *
     * @note Explicitly call this when the service is completed
     * or whatnot.
     */
    private void destroySelf() {
        stopSelf();
        currentSong = null;
    }

    // These methods are to be called by the Activity
    // to work on the music-playing.

    /**
     * Jumps to the previous song on the list.
     *
     * @note Remember to call `playSong()` to make the MusicPlayer
     * actually play the music.
     */
    public void previous(boolean userSkippedSong) {
        if (serviceState != ServiceState.Paused && serviceState != ServiceState.Playing)
            return;

        currentSongPosition--;
        if (currentSongPosition < 0)
            currentSongPosition = songs.size() - 1;
    }

    /**
     * Jumps to the next song on the list.
     *
     * @note Remember to call `playSong()` to make the MusicPlayer
     * actually play the music.
     */
    public void next(boolean userSkippedSong) {
        if (serviceState != ServiceState.Paused && serviceState != ServiceState.Playing)
            return;

        currentSongPosition++;

        if (currentSongPosition >= songs.size())
            currentSongPosition = 0;
    }

    public int getPosition() {
        return player.getCurrentPosition();
    }

    public int getDuration() {
        return player.getDuration();
    }

    public boolean isPlaying() {
        boolean returnValue = false;
        if (player != null)
            try {
                returnValue = player.isPlaying();
            } catch (IllegalStateException | NullPointerException e) {

            }

        return returnValue;
    }

    public boolean isPaused() {
        return serviceState == ServiceState.Paused;
    }

    /**
     * Actually plays the song set by `currentSongPosition`.
     */
    public void playSong() {

        if (player == null)
            initMusicPlayer();
        player.stop();
        player.reset();
        // Get the song ID from the list, extract the ID and
        // get an URL based on it
        Song songToPlay = songs.get(currentSongPosition);

        currentSong = songToPlay;

        // Append the external URI with our data'
        Uri songToPlayURI = ContentUris.withAppendedId
                (android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
                        songToPlay.getId());
        try {
            player.setDataSource(getApplicationContext(), songToPlayURI);
        } catch (IOException io) {
            Log.e(TAG, "IOException: couldn't change the song", io);
            destroySelf();
        } catch (Exception e) {
            Log.e(TAG, "Error when changing the song", e);
            destroySelf();
        }

        //setting meta data for notification and whole session
        setMediaSessionMetaData();

        // Prepare the MusicPlayer asynchronously.
        // When finished, will call `onPrepare`
        player.prepareAsync();

        if (Main.settings.get("saveRecent", true))
            RecentUtils.addsong_toRecent(getApplicationContext(), songToPlay);
        if (Main.settings.get("saveCount", true))
            RecentUtils.addcountSongsPlayed(getApplicationContext(), songToPlay);


        serviceState = ServiceState.Preparing;

        Log.w(TAG, "play song");
    }


    private void setMediaPlaybackState(int state) {
        PlaybackStateCompat.Builder playbackstateBuilder = new PlaybackStateCompat.Builder();
        if (state == PlaybackStateCompat.STATE_PLAYING) {
            playbackstateBuilder.setActions(PlaybackStateCompat.ACTION_PLAY_PAUSE | PlaybackStateCompat.ACTION_PAUSE);
        } else {
            playbackstateBuilder.setActions(PlaybackStateCompat.ACTION_PLAY_PAUSE | PlaybackStateCompat.ACTION_PLAY);
        }
        playbackstateBuilder.setState(state, PlaybackStateCompat.PLAYBACK_POSITION_UNKNOWN, 0);
        mMediaSessionCompat.setPlaybackState(playbackstateBuilder.build());
    }

    public void pausePlayer() {
        if (serviceState != ServiceState.Paused && serviceState != ServiceState.Playing)
            return;

        player.pause();
        serviceState = ServiceState.Paused;

        mDelayedStopHandler.removeCallbacksAndMessages(null);
        mDelayedStopHandler.sendEmptyMessageDelayed(0, STOP_DELAY);
        setMediaPlaybackState(PlaybackStateCompat.STATE_PAUSED);

    }

    public void unpausePlayer() {
        if (serviceState != ServiceState.Paused && serviceState != ServiceState.Playing)
            return;

        player.start();
        serviceState = ServiceState.Playing;

        setMediaPlaybackState(PlaybackStateCompat.STATE_PLAYING);

    }

    /**
     * Toggles between Pause and Unpause.
     */
    public void togglePlayback() {
        if (serviceState == ServiceState.Paused)
            unpausePlayer();
        else
            pausePlayer();
    }

    public void seekTo(int position) {
        player.seekTo(position);
    }

    /**
     * Toggles the Shuffle mode
     * (if will play data in random order).
     */
    public void toggleShuffle() {
        shuffleMode = !shuffleMode;
        if (isShuffle()) {
            Collections.shuffle(songs);
        } else Collections.sort(songs, new Comparator<Song>() {
            @Override
            public int compare(Song o1, Song o2) {
                return o1.getTitle().compareTo(o2.getTitle());
            }
        });
    }

    /**
     * Shuffle mode state.
     *
     * @return If Shuffle mode is on/off.
     */
    public boolean isShuffle() {
        return shuffleMode;
    }

    /**
     * Toggles the Repeat mode
     * (if the current song will play again
     * when completed).
     */
    public void toggleRepeat() {
        if (repeatMode == 2)
            repeatMode = 0;
        else repeatMode += 1;

    }

    /**
     * Repeat mode state.
     *
     * @return If Repeat mode is on/off.
     */
    public int isRepeat() {
        return repeatMode;
    }

    // THESE ARE METHODS RELATED TO CONNECTING THE SERVICE
    // TO THE ANDROID PLATFORM
    // NOTHING TO DO WITH MUSIC-PLAYING

    /**
     * Called when the Service is finally bound to the app.
     */
    @Override
    public IBinder onBind(Intent intent) {
        return musicBind;
    }

    @Nullable
    @Override
    public BrowserRoot onGetRoot(@NonNull String clientPackageName, int clientUid, @Nullable Bundle rootHints) {
        if (TextUtils.equals(clientPackageName, getPackageName())) {
            return new BrowserRoot(getString(R.string.app_name), null);
        }

        return null;
    }

    @Override
    public void onLoadChildren(@NonNull String parentId, @NonNull Result<List<MediaBrowserCompat.MediaItem>> result) {
        result.sendResult(null);
    }


    /**
     * Called when the Service is unbound - user quitting
     * the app or something.
     */
    @Override
    public boolean onUnbind(Intent intent) {

        return false;
    }

    /**
     * Displays a notification on the status bar with the
     * current song and some nice buttons.
     */
    public void notifyCurrentSong() {

        if (currentSong == null)
            return;

        if (!requestAudioFocus()) {
            //Stop the service.
            stopSelf();
            Toast.makeText(getApplicationContext(), "FUCK", Toast.LENGTH_LONG).show();
            return;
        }

        notificationManager.startNotification();


    }


    public void cancelNotification() {
        notificationManager.stopNotification();
    }


    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {

        if (intent != null) {
            String action = intent.getAction();
            String command = intent.getStringExtra(CMD_NAME);
            if (ACTION_CMD.equals(action)) {
                if (ACTION_PAUSE.equals(command)) {
                    pausePlayer();
                }
            } else {
                MediaButtonReceiver.handleIntent(mMediaSessionCompat, intent);
            }
        }
        mDelayedStopHandler.removeCallbacksAndMessages(null);
        mDelayedStopHandler.sendEmptyMessageDelayed(0, STOP_DELAY);

        return START_STICKY;
    }

    public int getAudioSession() {
        if (player == null)
            return 0;
        else return player.getAudioSessionId();
    }

    /**
     * Possible states this Service can be on.
     */
    enum ServiceState {

        Preparing,

        // Playback active - media player ready!
        // (but the media player may actually be paused in
        // this state if we don't have audio focus).
        Playing,

        // So that we know we have to resume playback once we get focus back)
        // playback paused (media player ready!)
        Paused
    }

    public class MusicBinder extends Binder {
        public ServicePlayMusic getService() {
            return ServicePlayMusic.this;
        }
    }


    /**
     * A simple handler that stops the service if playback is not active (playing)
     */
    private static class DelayedStopHandler extends Handler {//延迟停止服务handler
        private final WeakReference<ServicePlayMusic> mWeakReference;

        private DelayedStopHandler(ServicePlayMusic service) {
            mWeakReference = new WeakReference<>(service);
        }

        @Override
        public void handleMessage(Message msg) {
            ServicePlayMusic service = mWeakReference.get();
            if (service != null && Main.mainMenuHasNowPlayingItem) {
                if (service.isPlaying()) {
                    return;
                }
                service.stopMusicPlayer();
            }
        }
    }

}