package zero1hd.rhythmbullet.audio.metadata;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;

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.tag.TagException;
import org.jaudiotagger.tag.id3.ID3v23FieldKey;
import org.jaudiotagger.tag.id3.ID3v23Tag;
import org.jaudiotagger.tag.images.Artwork;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.files.FileHandle;
import com.badlogic.gdx.graphics.Pixmap;
import com.badlogic.gdx.graphics.Texture;

public class MP3Metadata implements AudioMetadata {
	private String title, author, duration, genre;
	private int length;
	private Texture albumCover;
	private FileHandle fileHandle;
	private Pixmap pixmap;
	
	public MP3Metadata(FileHandle fileHandle) {
		this.fileHandle = fileHandle;
		
		try {
			MP3File mp3file = (MP3File) AudioFileIO.read(fileHandle.file());
			ID3v23Tag tag;
			tag = (ID3v23Tag) mp3file.getTagAndConvertOrCreateAndSetDefault();
			
			length = mp3file.getAudioHeader().getTrackLength();
			SimpleDateFormat f = new SimpleDateFormat("m:ss");
			duration = f.format(new Date(length*1000));
			
			author = tag.getFirst(ID3v23FieldKey.ARTIST);
			genre = tag.getFirst(ID3v23FieldKey.GENRE);
			title = tag.getFirst(ID3v23FieldKey.TITLE);
			if (title.isEmpty()) {
				title = fileHandle.nameWithoutExtension().replace('_', ' ');
			}
		} catch (IOException | CannotReadException | TagException | ReadOnlyFileException | InvalidAudioFrameException e) {
			Gdx.app.error("MP3Metadata", "Failed to read metadata of file: " + fileHandle.name());
		}
	}
	
	@Override
	public void loadAlbumCover() {
		if (pixmap == null) {
			try {
				MP3File mp3file;
				mp3file = (MP3File) AudioFileIO.read(fileHandle.file());
				Artwork art = mp3file.getTag().getFirstArtwork();
				if (art != null) {
					byte[] imageData = art.getBinaryData();
					pixmap = new Pixmap(imageData, 0, imageData.length);
				}
				
			} catch (CannotReadException | IOException | TagException | ReadOnlyFileException | InvalidAudioFrameException e) {
				e.printStackTrace();
			}
		}
	}

	@Override
	public String getAuthor() {
		return author;
	}

	@Override
	public String getTitle() {
		return title;
	}

	@Override
	public String getDuration() {
		return duration;
	}
	
	@Override
	public int getLength() {
		return length;
	}
	
	@Override
	public String getGenre() {
		return genre;
	}
	
	@Override
	public void unloadAlbumCover() {
		if (albumCover != null) {
			albumCover.dispose();
			albumCover = null;
		}
	}
	
	@Override
	public Texture getAlbumCover() {
		if (pixmap != null && albumCover == null) {
			albumCover = new Texture(pixmap);
			pixmap.dispose();
			pixmap = null;
		}
		return albumCover;
	}

	@Override
	public FileHandle getFileHandle() {
		return fileHandle;
	}
	
	@Override
	public void dispose() {
		unloadAlbumCover();
	}


}
