#include "MusicManager.h"

using namespace SoundSystem;

MusicManager::MusicManager(void)
{
	stream = NULL;
	channel = -1;
	level = 255;
	playList.clear();
	playList.setLooping(false);
	playList.setRandom(false);
	started = false;
}

MusicManager::~MusicManager(void)
{
	playList.clear();
	stop();
}

bool MusicManager::addMusic(const string& filePath)
{
	return playList.add(filePath);
}

bool MusicManager::loadPlayList(const string& filePath, bool append)
{
	return playList.load(filePath,append);
}

void MusicManager::update()
{
	if (started)
	{
		// on verifie si le son est terminé ou pas
		if (getElapsedTime() > getMusicLength() -2000)
		{
			// on passe à la musique suivante
			next();
		}
	}
}

void MusicManager::stop()
{
	FSOUND_Stream_Close(stream);
	stream = NULL;
	channel = -1;
	started = false;
}

void MusicManager::start()
{
	playList.start();
	started = true;
	if (!playList.isFinish())
	{
		string file = playList.next();
		if (file != "")
		{
			playMusic(file);
		}
		else
		{
			// erreure dans la playList
			cerr << "MusicManager::start : erreur, la playList a retournée une chaine vide." << endl;
			cerr << "stopping MusicManager..." << endl;
			stop();
		}
	}
}

void MusicManager::pause(bool pause)
{
	if (started)
	{
		if (pause)
		{
			FSOUND_SetPaused(channel,1);
		}
		else
		{
			FSOUND_SetPaused(channel,0);
		}
	}
}

bool MusicManager::isPaused()
{
	return FSOUND_GetPaused(channel) == 1;
}

bool MusicManager::isPlaying()
{
	return FSOUND_IsPlaying(channel) == 1;
}

void MusicManager::setVolume(int volume)
{
	if (volume < 0) volume = 0;
	else if (volume > 255) volume = 255;
	FSOUND_SetVolume(channel,volume);
	level = volume;
}

int	MusicManager::getVolume()
{
	return FSOUND_GetVolume(channel);
}

bool MusicManager::playMusic(const string& filePath)
{
	// shut down previous music...
	bool paused = isPaused();
	if (stream != NULL)
	{
		FSOUND_StopSound(channel);
		FSOUND_Stream_Close(stream);
		stream = NULL;
		channel = -1;
	}
	bool ret = false;
	int flag = FSOUND_16BITS | FSOUND_SIGNED | FSOUND_HW2D;
	cout << "starting to play music "<< filePath << endl;
	stream = FSOUND_Stream_Open(filePath.c_str(),flag,0,0);
	if (stream != NULL)
	{
		channel = FSOUND_Stream_Play(FSOUND_FREE, stream);
		ret = channel != -1;
		if (!ret)
		{
			cerr << "MusicManager::playMusic : erreur. Impossible de lancer le fichier "<< filePath << endl;
		}
		else
		{
			// on met le volume de la musique a niveau
			setVolume(level);
			pause(paused);
		}
	}
	else
	{
		cerr << "MusicManager::playMusic : erreur. Impossible d'ouvrir le fichier "<< filePath << endl;
	}
	return ret;
}

int MusicManager::getElapsedTime()
{
	int ret = 0;
	if (started)
	{
		ret = FSOUND_Stream_GetTime(stream);
	}
	return ret;
}

int MusicManager::getMusicLength()
{
	int ret = 1;
	if (started)
	{
		ret = FSOUND_Stream_GetLengthMs(stream);
	}
	return ret;
}

void MusicManager::setRandom(bool rand)
{
	playList.setRandom(rand);
}

bool MusicManager::isRandom()
{
	return playList.isRandom();
}

void MusicManager::setLooping(bool loop)
{
	playList.setLooping(loop);
}

bool MusicManager::isLooping()
{
	return playList.isLooping();
}

void MusicManager::next()
{
	// il est terminé, on passe a la musique suivante
	if (!playList.isFinish())
	{
		// on specifie que le manager est bien en train de jouer. ceci permet d'eviter le bug qui
		// apparait quand la playListe s'est terminée, et que l'utilisateur passe en mode looping
		// puis passa a la chanson suivante.
		started = true;
		string file = playList.next();
		// sanity check (normalement le fonctionnement de la playListe devrait nous assurer
		// que tout fichier passé est valide et existe sur le disque)
		if (file != "")
		{
			// a partir de ce moment, on a plus aucun control sur le fichier joué precedamant, toute
			// action s'effectue sur le nouveau fichier son...
			// MAJ : plus d'importance, le fichier son precedent est stoppé...
			int index = 0;
			while(!playMusic(file) && index < playList.size() && !playList.isFinish())
			{
				index++;
				file = playList.next();
			}
			if (index == playList.size())
			{
				cerr << "MusicManager::update : impossible de charger un fichier de la playList." <<endl;
				cerr << "clearing playList..."<< endl;
				playList.clear();
				cerr << "stopping MusicManager..." << endl;
				stop();
			}
		}
		else
		{
			// mmmmhhhh... probleme dans la playList ??? hop on arrete le manager de music et on log tout ca...
			cerr << "MusicManager::update : erreur, la playList a retournée une chaine vide." << endl;
			cerr << "stopping MusicManager..." << endl;
			stop();
		}
	}
	else
	{
		// la playList est terminée... on arrete le MusicManager
		stop();
	}

}

