package zero1hd.rhythmbullet.audio;

import java.io.IOException;
import java.security.InvalidParameterException;

import javax.sound.sampled.AudioFormat;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.audio.Music;
import com.badlogic.gdx.files.FileHandle;

import zero1hd.rhythmbullet.audio.wavedecoder.WavDecoder;

public class WavAudioData implements MusicDataPack {
	private int readWindowSize = 1024;
	private AudioFormat format;
	private int readIndex;
	private int currentReadWindowIndex;
	Music playbackMusic;
	WavDecoder decoder;
	
	public WavAudioData(FileHandle file) {
		reset();
		try {
			decoder = new WavDecoder(file);
		} catch (InvalidParameterException | IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		playbackMusic = Gdx.audio.newMusic(file);
		format = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, (float) decoder.getSampleRate(), 16, decoder.getChannels(), decoder.getChannels()*2, (float) decoder.getSampleRate(), false);
	}
	
	@Override
	public void playbackIndexUpdate() {
		readIndex = (int) (playbackMusic.getPosition() * decoder.getSampleRate() / readWindowSize);
	}
	
	@Override
	public int getPlaybackIndexPosition() {
		return readIndex;
	}
	
	@Override
	public void reset() {
		if (playbackMusic != null) {
			playbackMusic.stop();
		}
	}
	
	@Override
	public int getReadWindowSize() {
		return readWindowSize;
	}
	
	@Override
	public Music getPlaybackMusic() {
		return playbackMusic;
	}

	@Override
	public int readSamples(float[] samples) {
		int samplesRead = 0;
		try {
			samplesRead = decoder.readSamples(samples);
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		if (samplesRead != 0) {
			currentReadWindowIndex++;
		}
		return samplesRead;
	}

	@Override
	public long getSampleCount() {
		return decoder.getFrameLength();
	}

	@Override
	public void dispose() {
		reset();
		playbackMusic.dispose();
		decoder.cleanAndClose();
	}

	@Override
	public float getDuration() {
		return decoder.getDurationInSeconds();
	}

	@Override
	public float getSampleRate() {
		return format.getSampleRate();
	}

	@Override
	public int getCurrentReadWindowIndex() {
		return currentReadWindowIndex;
	}
}
