package de.rico.adventure.actions.custom;

import javax.media.opengl.GL;

import de.rico.adventure.actions.AbstractAction;
import de.rico.adventure.actions.ActionScheduler;
import de.rico.engine.effect.sound.Mp3Sound;

/**
 * This game action can be used to play an mp3 sound file either
 * in a queued or a concurrent way.
 * @author Frank Bruns
 *
 */
public class PlayMP3 extends AbstractAction
{
	private String path = null;
	private boolean concurrent = false;
	private boolean soundStarted = false;
	private Mp3Sound mp3 = null;

	/**
	 * Game action that plays an mp3 file queued or concurrently.
	 * Note that concurrently played sound file won't stop playing
	 * when the game action was removed from the action queue.
	 * <br>
	 * <br>
	 * <b>Note:</b> In some rare cases you would like to start a looped
	 * sound in a queued manner on the game action scheduler.
	 * But you really have to be cautious with looping the sound.
	 * If you loop the sound there are two scenarios to consider:
	 * <br>
	 * <ol>
	 *   <li>If you loop the sound and play it concurrently there is
	 *   no easy way to stop the sound again. You will have to get a
	 *   hold on this game action's object and call the
	 *   <code>stop()</code> method to stop it.
	 *   </li>
	 *   <li>If you loop the sound and don't play it concurrently
	 *   the sound will block the game action queue forever and ever.
	 *   So to stop such a sound you will have to remove the action
	 *   from the queue manually, by calling its <code>removeFirst()</code>
	 *   method
	 *   </li>
	 * </ol>
	 * @param path path to mp3 sound file
	 * @param loop loop the sound? --> true=yes, false=no
	 * @param concurrent play concurrently --> true=yes, false=no
	 */
	public PlayMP3(String path, boolean loop, boolean concurrent)
	{
		this.path = path;
		this.concurrent = concurrent;
		this.mp3 = new Mp3Sound(path,loop); // don't loop
	}

	/* (non-Javadoc)
	 * @see de.rico.adventure.actions.AbstractAction#update(long)
	 */
	@Override
	public void update(long elapsedTime)
	{
		if(this.concurrent == true)
		{
			// start playing and remove action
			this.mp3.play();
			ActionScheduler.getInstance().removeFirst();
		}
		else
		{
			// start sound, if not yet started
			if(this.soundStarted == false)
			{
				this.mp3.play();
				this.soundStarted = true;
			}

			// if the sound finished playing, remove the game action
			// from the queue
			if(this.mp3.hasFinished() == true)
				ActionScheduler.getInstance().removeFirst();
		}
	}

	/* (non-Javadoc)
	 * @see de.rico.adventure.actions.AbstractAction#draw(javax.media.opengl.GL)
	 */
	@Override
	public void draw(GL gl)
	{
		// TODO Auto-generated method stub

	}

	/* (non-Javadoc)
	 * @see de.rico.adventure.actions.AbstractAction#finishUp()
	 */
	@Override
	public void finishUp()
	{
		// stop sound file, if it was played in a queued manner.
		if(this.concurrent == false)
		{
			this.mp3.stop();
			this.mp3 = null;
		}

	}

	/**
	 * This is a method to stop the playback of the sound in the special
	 * case that you looped the sound and played it concurrently. See the
	 * javadoc comments on that case at the constructor. The method will
	 * have no effect in any other case.
	 *
	 */
	public void stop()
	{
		if(this.mp3.isLooped() && this.concurrent)
			this.mp3.stop();
	}
}
