#ifndef STREAMDESCRIPTOR_H
#define STREAMDESCRIPTOR_H

#include "SoundDescriptor.h"
#include "fmod/fmod.h"
#ifdef WIN32
#define NOMINMAX // pour novodex
#include <windows.h>
#else
#include "fmod/wincompat.h"
#endif



namespace SoundSystem
{
	/**
	 * Classe decrivant un son basé sur un STREAM.
	 *
	 * Cette classe utilise un STREAM pour stocker le son en memoire. Ceci permet la lecture de sons plus long
	 * avec des ressources memoires moins importantes. Neanmoins, contrairement au sample, un STREAM ne peut etre lue
	 * que par un son a la fois, il faut donc faire appel a la methode canPlay() pour savoir si le stream peut etre joué
	 * sous peine de crée des artefactes sonores. En effet, l'appel a la methode play() alors qu'un son est deja en
	 * train d'etre joué remplace le son joué par le nouveau, mais la lecture des stream dans FMOD etant decoupé en 
	 * samples, il est possible que le son precedent continu a joué puis soit coupé brusquement quand le sample se
	 * termine.
	 * 
	 * Un autre point restrictif des stream est qu'il n'est pas possible de changer leur mode de looping en
	 * cours de lecture. Pour changer le mode de looping d'un stream l'arreter, le nettoyer de la memoire (methode
	 * free()), le recharger en mmoire avec la methode load(), puis recommencer la lecture avec play().
	 *
	 * Les stream sont à utiliser pour des sons qui ne risquent pas d'etre lancée de facon aleatoire ou plusieurs fois
	 * en même temps, mais par contre ils sont particulierement adapté pour les sons long qui necessiterait une memoire
	 * importante si ils etait joué par des sample, ce qui demande en plus un temps de chargement et de decompression
	 * important, alors que les streams realisent le même travail en demandant moins de ressources.
	 */
	class StreamDescriptor : public SoundDescriptor
	{
	protected:
		/**
		 * le stream FMOD utilisé pour jouer.
		 */
		FSOUND_STREAM * stream;
		/**
		 * le channel sur lequel est joué le stream
		 */
		int channel;
	public:
		/**
		 * constructeur par defaut
		 */
		StreamDescriptor(void);

		/**
		 * destructeur par defaut
		 */
		virtual ~StreamDescriptor(void);

		/**
		 * charge le stream en memoire
		 */
		void load(bool loop = false);
		/**
		 * libere le stream de la memoire. Tout les son joué sur ce stream seront stopé.
		 */
		void free();
		/**
		 * lance un son basé sur ce stream
		 *
		 * Attention a bien faire appel a la methode canPlay() avant de faire appel a cette methode. en effet, les 
		 * stream ne peuvent joué qu'un seul son à la fois, et aucun test n'est fait dans cette methode pour savoir
		 * si un son est deja lancé sur ce stream.
		 * @return int : le channel du son lancé. -1 si le lancement n'a pas pu s'effectué.
		 */
		int play();

		/**
		 * definit si le sample peut etre joué ou pas.
		 *
		 * @return bool : true si le son peut etre joué, false sinon
		 */
		bool canPlay();

		/**
		 * retourne le type du descripteur
		 */
		DescriptorType getType(){return STREAM;};
	};
}// namespace SoundSystem



#endif
