package com.gamepatriot.framework2d.implementation;

import android.media.AudioManager;
import android.media.SoundPool;

import com.gamepatriot.androidframework.framework.AndroidSoundHandler;
import com.gamepatriot.framework2d.R;

/**
 * The SoundHandler class controls short-term audio playback (Sound effects).
 * 
 * @see AudioSoundHandler
 * @author Pete Schmitz, May 9, 2013
 *
 */
public class SoundHandler implements AndroidSoundHandler {
	
	/**
	 * The Sound enum allows an association between a flag to represent a sound resource, the resource index, and the SoundPool index (the index it was loaded at).
	 * 
	 * @author Pete Schmitz, May 9, 2013
	 *
	 */
	public static enum Sound{
		SFX_EXAMPLE(R.raw.sfxexample);
		
		/** The SoundPool index associated with this flag. **/
		private int poolIndex = -1;
		
		/** The resource index associated with this flag. **/
		private int resourceIndex = -1;
		
		
		private Sound(int $index){
			resourceIndex = $index;
		}
		
		public void setPoolIndex(int $index){
			poolIndex = $index;
		}
		
		/** Returns the sound pool index (index it was loaded as) that is associated with this flag. **/
		public int getPoolIndex(){
			return poolIndex;
		}
		
		/** Returns the resource index that is associated with this flag. **/
		public int getResourceIndex(){
			return resourceIndex;
		}
	}
	
	/** The default sound audio is played at. **/
	public static float DEFAULT_SOUND_VOLUME = 1.0f;
	
	
	//Containers
	
	/** The sound pool that loads all resources defined in the enum {@link Sound}. **/
	private final SoundPool soundPool;
	
	
	//Flags
	
	/** Flag for the left volume. **/
	private float soundVolumeLeft;
	
	/** Flag for the right volume. **/
	private float soundVolumeRight;
	
	/** Whether or not audio playback is allowed. **/
	public boolean soundsEnabled = true;
	
	
	//References
	
	/** Main reference this application is using. **/
	private final Main main;
	
	
	/**
	 * Constructor
	 * @param $main				Reference to the application's {@link Main} object.
	 * @param $soundEnabled		Whether or not audio should be allowed once constructed.
	 */
	public SoundHandler(Main $main, boolean $soundEnabled){
		main = $main;
		
		soundVolume(DEFAULT_SOUND_VOLUME);
		soundPool = new SoundPool(Main.AUDIO_STREAM_MAX, AudioManager.STREAM_MUSIC, 0);
		
		loadSounds();
		
		//Toggle startup
		if ($soundEnabled) unmuteSounds();
		else muteSounds();
	}
	
	@Override
	public void muteSounds() {
		soundsEnabled = false;
	}
	
	@Override
	public void unmuteSounds() {
		soundsEnabled = true;
	}
	
	/**
	 * Play audio based on the Sound ID provided.
	 * @param $sound		The sound ID to play.
	 */
	public void playSound(Sound $sound) {
		if (!soundsEnabled) return;
		
		int $soundIndex = $sound.getPoolIndex();
		
		if ($soundIndex >= 0) soundPool.play($soundIndex, soundVolumeLeft, soundVolumeRight, 0, 0, 1.0f);
	}
	
	@Override
	public void soundVolume(float $amount) {
		leftSoundVolume($amount);
		rightSoundVolume($amount);
	}
	
	@Override
	public void leftSoundVolume(float $amount) {
		soundVolumeLeft = $amount;
	}
	
	@Override
	public void rightSoundVolume(float $amount) {
		soundVolumeRight = $amount;
	}
	
	/** Load all sounds defined in the enum {@link Sound}. **/
	private void loadSounds(){
		int $poolIndex;
		for (Sound $sound : Sound.values()){
			$poolIndex = soundPool.load(main, $sound.getResourceIndex(), 1);
			$sound.setPoolIndex($poolIndex);
		}
	}
	
}
