package vazkii.minetunes.playlist;
import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Random;
import java.util.Set;
import java.util.TreeSet;
import net.minecraft.nbt.NBTTagCompound;
import vazkii.minetunes.config.MTConfig;
import vazkii.minetunes.gui.GuiPlaylistManager;
import vazkii.minetunes.playlist.provider.IProviderStateCallback;
import vazkii.minetunes.playlist.provider.PlaylistProvider;
import vazkii.minetunes.playlist.provider.ProviderDirectory;
import vazkii.minetunes.playlist.provider.ProviderM3U;
public class Playlist {
private static final String TAG_NAME = "name";
private static final String TAG_FILE_PATH = "filePath";
private static final String TAG_SONG_COUNT = "songCount";
private static final String TAG_SONG_PREFIX = "song";
public final List<MP3Metadata> metadataList;
public final File file;
public String storeName = "";
Random rand = new Random();
public Playlist(File file, Collection<MP3Metadata> metaSet) {
this.file = file;
this.metadataList = new ArrayList(metaSet);
}
public static Playlist build(File file, IProviderStateCallback callback) {
PlaylistProvider provider = file.isDirectory() ? ProviderDirectory.instance : file.getName().endsWith(".m3u") ? ProviderM3U.instance : null;
return provider == null ? null : provider.provide(file, callback);
}
public static Playlist build(NBTTagCompound cmp) {
String name = cmp.getString(TAG_NAME);
String filePath = cmp.getString(TAG_FILE_PATH);
int count = cmp.getInteger(TAG_SONG_COUNT);
Set<MP3Metadata> metadataSet = new TreeSet();
for(int i = 0; i < count; i++) {
NBTTagCompound cmp1 = cmp.getCompoundTag(TAG_SONG_PREFIX + i);
metadataSet.add(new MP3Metadata(i, cmp1));
}
Playlist playlist = new Playlist(new File(filePath), metadataSet);
playlist.storeName = name;
return playlist;
}
public void writeToNBT(NBTTagCompound cmp, String name) {
cmp.setString(TAG_NAME, name);
cmp.setString(TAG_FILE_PATH, file.getAbsolutePath());
cmp.setInteger(TAG_SONG_COUNT, metadataList.size());
int i = 0;
for(MP3Metadata meta : metadataList) {
NBTTagCompound cmp1 = new NBTTagCompound();
meta.writeToNBT(cmp1);
cmp.setTag(TAG_SONG_PREFIX + i, cmp1);
i++;
}
}
public MP3Metadata nextSong() {
int index = nextSongIndex();
boolean valid = index >= 0 && index < metadataList.size();
if(valid) {
GuiPlaylistManager.selectCurrentSong(index);
return metadataList.get(index);
}
return null;
}
public int nextSongIndex() {
switch(MTConfig.playMode) {
case 1: return repeat();
case 2: return loop();
case 3: return shuffle();
}
return stop();
}
public int stop() {
return -1;
}
public int repeat() {
return GuiPlaylistManager.getCurrentSong();
}
public int loop() {
int selected = GuiPlaylistManager.getCurrentSong();
int index = selected + 1;
if(index >= metadataList.size())
index = 0;
return index;
}
public int shuffle() {
int selected = GuiPlaylistManager.getCurrentSong();
int size = metadataList.size();
if(size < 2)
return selected;
int index = selected;
int next = loop();
int tries = 0;
while((index == selected || index == next) && tries < 50) {
index = rand.nextInt(size);
++tries;
}
return index;
}
}