package com.studio4plus.homerplayer.service;

import android.media.AudioManager;
import android.media.MediaPlayer;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.Message;

import com.studio4plus.homerplayer.HomerPlayerApplication;
import com.studio4plus.homerplayer.model.AudioBook;
import com.studio4plus.homerplayer.model.Position;

import java.io.File;
import java.io.IOException;

public class AudioBookPlayer extends Handler {

    public interface Observer {
        public void onPlaybackStopped();
    }

    private static final int MSG_CONTROL_FILE_COMPLETE = 1;
    private static final int MSG_CONTROL_STOPPED = 2;

    private final Handler playbackThreadHandler;
    private final Observer observer;

    private AudioBook audioBook;

    public AudioBookPlayer(Observer observer, AudioBook book) {
        super(Looper.getMainLooper());
        this.observer = observer;
        this.audioBook = book;
        HandlerThread thread = new HandlerThread("Playback");
        thread.start();
        playbackThreadHandler = new PlaybackHandler(thread.getLooper(), this);
    }

    public void startPlayback() {
        Message message = playbackThreadHandler.obtainMessage(PlaybackHandler.MSG_PLAYBACK_START);
        message.obj = new BookPlaybackInfo(audioBook);
        playbackThreadHandler.sendMessage(message);
    }

    public void stopPlayback() {
        Message message = playbackThreadHandler.obtainMessage(PlaybackHandler.MSG_PLAYBACK_STOP);
        playbackThreadHandler.sendMessage(message);
    }

    @Override
    public void handleMessage(Message message) {
        switch(message.what) {
            case MSG_CONTROL_FILE_COMPLETE:
                boolean playMore = audioBook.advanceFile();
                if (playMore) {
                    startPlayback();
                } else {
                    audioBook.resetPosition();
                    observer.onPlaybackStopped();
                }
                break;
            case MSG_CONTROL_STOPPED: {
                audioBook.updatePosition(message.arg1);
                observer.onPlaybackStopped();
                break;
            }
        }
    }

    private static class BookPlaybackInfo {
        public final File directoryPath;
        public final Position position;

        private BookPlaybackInfo(AudioBook audioBook) {
            this.directoryPath =
                    HomerPlayerApplication.getAudioBookManager().getAbsolutePath(audioBook);
            this.position = audioBook.getLastPosition();
        }
    }

    private static class PlaybackHandler extends Handler implements MediaPlayer.OnCompletionListener  {

        public static final int MSG_PLAYBACK_START = 1;
        public static final int MSG_PLAYBACK_STOP = 2;

        private final Handler controlHandler;
        private MediaPlayer mediaPlayer;

        private PlaybackHandler(Looper looper, Handler controlHandler) {
            super(looper);
            this.controlHandler = controlHandler;
        }

        @Override
        public void handleMessage(Message message) {
            switch(message.what) {
                case MSG_PLAYBACK_START:
                    BookPlaybackInfo playbackInfo = (BookPlaybackInfo) message.obj;
                    startPlayback(playbackInfo.directoryPath, playbackInfo.position);
                    break;
                case MSG_PLAYBACK_STOP:
                    stopPlayback();
                    break;
            }
        }

        private void startPlayback(final File directoryPath, final Position lastPosition) {
            mediaPlayer = new MediaPlayer();
            mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
            mediaPlayer.setOnCompletionListener(this);

            File currentFile = new File(directoryPath, lastPosition.filePath);
            try {
                mediaPlayer.setDataSource(currentFile.getAbsolutePath());
                mediaPlayer.prepare();
                mediaPlayer.seekTo(lastPosition.seekPosition);
                mediaPlayer.start();
            } catch (IOException e) {
                // TODO: notify the UI and clean up.
                e.printStackTrace();
            }
        }

        @Override
        public void onCompletion(MediaPlayer mp) {
            releaseMediaPlayer();

            Message message = controlHandler.obtainMessage(MSG_CONTROL_FILE_COMPLETE);
            controlHandler.sendMessage(message);
        }

        private void stopPlayback() {
            if (mediaPlayer != null) {
                mediaPlayer.stop();
                Message message = controlHandler.obtainMessage(MSG_CONTROL_STOPPED);
                message.arg1 = mediaPlayer.getCurrentPosition();
                controlHandler.sendMessage(message);
                releaseMediaPlayer();
            }
        }

        private void releaseMediaPlayer() {
            mediaPlayer.release();
            mediaPlayer = null;
        }
    }
}

@@ -1272,24 +1272,25 @@
 START);%0A
+%0A
         
 message.
@@ -1285,52 +1285,343 @@
     
-message.obj = new BookPlaybackInfo(audioBook
+Position position = audioBook.getLastPosition();%0A        File bookDirectory =%0A                HomerPlayerApplication.getAudioBookManager().getAbsolutePath(audioBook);%0A        File currentFile = new File(bookDirectory, position.filePath);%0A%0A        message.obj = new PlaybackStartInfo(currentFile.getAbsolutePath(), position.seekPosition
 );%0A 
@@ -2519,28 +2519,24 @@
 c class 
-Book
 Playback
 Info %7B%0A 
@@ -2523,24 +2523,29 @@
 ass Playback
+Start
 Info %7B%0A     
@@ -2556,38 +2556,35 @@
 ublic final 
-File directory
+String file
 Path;%0A      
@@ -2598,26 +2598,26 @@
 c final 
-Position p
+int startP
 osition;
@@ -2634,28 +2634,24 @@
 private 
-Book
 Playback
 Info(Aud
@@ -2646,160 +2646,92 @@
 back
-Info(AudioBook audioBook) %7B%0A            this.directoryPath =%0A                    HomerPlayerApplication.getAudioBookManager().getAbsolutePath(audioBook)
+StartInfo(String filePath, int startPosition) %7B%0A            this.filePath = filePath
 ;%0A  
@@ -2745,17 +2745,22 @@
    this.
-p
+startP
 osition 
@@ -2761,32 +2761,20 @@
 ition = 
-audioBook.getLas
+star
 tPositio
@@ -2766,34 +2766,32 @@
  = startPosition
-()
 ;%0A        %7D%0A    
@@ -2833,16 +2833,28 @@
 kHandler
+%0A           
  extends
@@ -2906,17 +2906,16 @@
 istener 
- 
 %7B%0A%0A     
@@ -3437,28 +3437,24 @@
         
-Book
 Playback
 Info pla
@@ -3441,24 +3441,29 @@
     Playback
+Start
 Info playbac
@@ -3475,20 +3475,16 @@
  = (
-Book
 Playback
 Info
@@ -3475,24 +3475,29 @@
  = (Playback
+Start
 Info) messag
@@ -3550,25 +3550,20 @@
 ackInfo.
-directory
+file
 Path, pl
@@ -3573,17 +3573,22 @@
 ackInfo.
-p
+startP
 osition)
@@ -3789,46 +3789,39 @@
 nal 
-File directoryPath, final Position las
+String filePath, final int star
 tPos
@@ -4005,87 +4005,8 @@
 );%0A%0A
-            File currentFile = new File(directoryPath, lastPosition.filePath);%0A
     
@@ -4065,37 +4065,16 @@
 rce(
-currentFile.getAbsolut
+fil
 ePath
-()
 );%0A 
@@ -4150,25 +4150,13 @@
 kTo(
-lastPosition.seek
+start
 Posi

Remove playback start logic away from PlayerHandler.