| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -2,6 +2,15 @@ package zero1hd.polyjet.ui.builders;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import java.io.IOException;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import org.jaudiotagger.audio.AudioFileIO;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import org.jaudiotagger.audio.exceptions.CannotReadException;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import org.jaudiotagger.audio.exceptions.InvalidAudioFrameException;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import org.jaudiotagger.audio.exceptions.ReadOnlyFileException;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import org.jaudiotagger.audio.mp3.MP3File;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import org.jaudiotagger.audio.wav.WavTag;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import org.jaudiotagger.tag.FieldKey;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import org.jaudiotagger.tag.TagException;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import com.badlogic.gdx.Gdx;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import com.badlogic.gdx.Preferences;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import com.badlogic.gdx.files.FileHandle;
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -12,11 +21,9 @@ import com.badlogic.gdx.scenes.scene2d.ui.Button;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import com.badlogic.gdx.scenes.scene2d.ui.Image;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import com.badlogic.gdx.scenes.scene2d.ui.Label;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import com.badlogic.gdx.scenes.scene2d.ui.Skin;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import com.badlogic.gdx.scenes.scene2d.ui.Table;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import com.badlogic.gdx.utils.Align;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import com.badlogic.gdx.utils.Disposable;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import com.mpatric.mp3agic.ID3v2;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import com.mpatric.mp3agic.InvalidDataException;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import com.mpatric.mp3agic.Mp3File;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import com.mpatric.mp3agic.UnsupportedTagException;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import zero1hd.wavedecoder.WavInfo;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -26,6 +33,7 @@ public class MusicSelectable extends Button implements Disposable {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					private String songName;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					private Texture albumCover;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					WavInfo wavinfo;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					private String author;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					private int previousTop;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					private int ratedDifficulty;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					private byte[] albumWorkBytes;
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -33,6 +41,9 @@ public class MusicSelectable extends Button implements Disposable {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					private Image imageIcon;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					private ScrollText displayName;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					private Label runTime;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					private Label authorLabel;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					private Label previousTopLabel;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					private Label ratedDifficultyLabel;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					private Skin skin;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					public MusicSelectable(FileHandle musicFile, Preferences musicData, final Skin skin, Texture defaultAlbumC) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						super(skin, "info-button");
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -41,23 +52,36 @@ public class MusicSelectable extends Button implements Disposable {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						this.albumCover = defaultAlbumC;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						if (musicFile.extension().toLowerCase().equals("mp3")) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							MP3File mp3File;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							try {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								Mp3File mp3File = new Mp3File(musicFile.file());
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								durationInSeconds = mp3File.getLengthInSeconds();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								mp3File = new MP3File(musicFile.file());
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								durationInSeconds = mp3File.getAudioHeader().getTrackLength();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								if (mp3File.hasId3v2Tag()) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
									ID3v2 id3v2tag = mp3File.getId3v2Tag();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
									albumWorkBytes = id3v2tag.getAlbumImage();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
									
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
									songName = id3v2tag.getTitle();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								if (mp3File.getTag() != null) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
									albumWorkBytes = mp3File.getTag().getFirstArtwork().getBinaryData();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							} catch (UnsupportedTagException | InvalidDataException | IOException e) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								Gdx.app.debug("Music Selector", "Error while reading tag for " + musicFile.name());
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								songName = mp3File.getTag().getFirst(FieldKey.TITLE);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								author = mp3File.getTag().getFirst(FieldKey.ARTIST);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							} catch (IOException | TagException | ReadOnlyFileException | InvalidAudioFrameException e) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								// TODO Auto-generated catch block
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								e.printStackTrace();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						} else {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							wavinfo = new WavInfo(musicFile.file());
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							durationInSeconds = wavinfo.getDurationInSeconds();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							try {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								WavTag wavTag = (WavTag) AudioFileIO.read(wavinfo.getFile()).getTag();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								songName = wavTag.getFirst(FieldKey.TITLE);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								author = wavTag.getFirst(FieldKey.ARTIST);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							} catch (CannotReadException | IOException | TagException | ReadOnlyFileException
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
									| InvalidAudioFrameException e) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								// TODO Auto-generated catch block
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								e.printStackTrace();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						if (durationInSeconds > 60 * 5) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							invalidMusic = true;
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -69,23 +93,47 @@ public class MusicSelectable extends Button implements Disposable {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						previousTop = musicData.getInteger(songName + ":previous top");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						ratedDifficulty = musicData.getInteger(songName + ":difficulty");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						if (author == null || author.isEmpty()) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							author = "N/A";
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					public void addInfoToPanel() {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						displayName = new ScrollText(songName, skin, true);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						add(displayName).fillX().spaceBottom(20f);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						defaults().align(Align.top);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						add(displayName).fillX().padTop(15f).top();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						row();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						String formattedTime = "Run time: "+ String.valueOf(durationInSeconds/60) + ":";
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						if (durationInSeconds - (durationInSeconds/60)*60 < 10) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							formattedTime = formattedTime.concat("0");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						Table songInfoTable = new Table();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						formattedTime = formattedTime.concat(String.valueOf(durationInSeconds - (durationInSeconds/60)*60));
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						runTime = new Label(formattedTime, skin, "sub-font", skin.getColor("default"));
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						add(runTime);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						songInfoTable.add(runTime).center();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						songInfoTable.row();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						authorLabel = new Label("Author: " + author, skin, "sub-font", skin.getColor("default"));
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						songInfoTable.add(authorLabel).expandY();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						songInfoTable.row();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						previousTopLabel = new Label("Previous Top: " + previousTop, skin, "sub-font", skin.getColor("default"));
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						songInfoTable.add(previousTopLabel).center();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						songInfoTable.row();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						ratedDifficultyLabel = new Label("Difficulty: " + ratedDifficulty, skin, "sub-font", skin.getColor("default"));
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						songInfoTable.add(ratedDifficultyLabel).expandY();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						songInfoTable.row();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						row();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						add(songInfoTable).expandY().center();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						row();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						if (albumWorkBytes != null && !invalidMusic) {
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -100,7 +148,7 @@ public class MusicSelectable extends Button implements Disposable {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							Gdx.app.debug("UI", "album cover invalid or null for image: " + songName);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						add(imageIcon);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						add(imageIcon).size(246f);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					public int getPreviousTop() {
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				 
 |