package zero1hd.rhythmbullet.audio;

import java.security.InvalidParameterException;
import java.util.Random;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Preferences;
import com.badlogic.gdx.audio.Music;
import com.badlogic.gdx.audio.Music.OnCompletionListener;
import com.badlogic.gdx.utils.Array;

import zero1hd.rhythmbullet.events.OnDifferentSongListener;

public class SongController implements OnCompletionListener {
	private SongList songList;
	private MusicDataPack mdp;
	private int currentPlaybackID;
	private boolean autoPlay;
	private boolean shuffle;
	private Random rand;
	
	private Array<OnDifferentSongListener> listeners;
	
	private Preferences prefs;
	public SongController(SongList songList, Preferences prefs) {
		if (prefs == null) throw new NullPointerException("preferences can't be null...");
		if (songList == null) throw new NullPointerException("song list can't be null...");
		if (!songList.isSearched()) throw new InvalidParameterException("Song list has to be searched already.");
		
		this.prefs = prefs;
		listeners = new Array<>();
		this.songList = songList;
		changeSong();
		rand = new Random();
	}
	
	public void play() {
		mdp.getPlaybackMusic().play();
		mdp.getPlaybackMusic().setVolume(prefs.getFloat("music vol"));;
	}
	
	public void setSongByIndex(int index) {
		this.currentPlaybackID = index;
		changeSong();
	}
	
	public void skip() {
		currentPlaybackID++;
		changeSong();
	}
	
	public void previous() {
		currentPlaybackID--;
		changeSong();
	}

	@Override
	public void onCompletion(Music music) {
		if (autoPlay) {
			if (shuffle) {
				currentPlaybackID = rand.nextInt(songList.getAmountOfSongs());
			} else {
				currentPlaybackID++;
				if (currentPlaybackID > songList.getAmountOfSongs()) {
					currentPlaybackID = 0;
				}
			}
			changeSong();
			play();
		}
	}
	
	public void shuffle() {
		currentPlaybackID = rand.nextInt(songList.getAmountOfSongs());
		changeSong();
	}
	
	public void setAutoPlay(boolean autoPlay) {
		this.autoPlay = autoPlay;
	}
	
	public void setShuffle(boolean shuffle) {
		this.shuffle = shuffle;
		shuffle();
	}
	
	public boolean isShuffle() {
		return shuffle;
	}
	
	public boolean isAutoPlay() {
		return autoPlay;
	}
	
	private void changeSong() {
		if (mdp != null) {
			mdp.dispose();
		}
		
		this.mdp = songList.getMusicInfoFromIndex(currentPlaybackID);
		if (mdp == null) {
			mdp = songList.getAudioData(Gdx.files.internal("music/default.mp3"));
		}
		mdp.getPlaybackMusic().setOnCompletionListener(this);
		sendEvent();
	}
	
	public SongList getSongList() {
		return songList;
	}
	
	private void sendEvent() {
		for (int i = 0; i < listeners.size; i++) {
			listeners.get(i).onDifferentSong(mdp);
		}
	}
	
	public void addOnDifferentSongListener(OnDifferentSongListener listener) {
		listeners.add(listener);
	}
	
	public void removeListener(OnDifferentSongListener listener) {
		listeners.removeValue(listener, true);
	}
	
	public MusicDataPack getCurrentSong() {
		return mdp;
	}
}
