#include "Sounderer.h"

Sounderer::Sounderer() : m_lastCanal(-1), m_folder(""), m_musicName(""), m_music(0x0)
{}

Sounderer::Sounderer(std::string folder) : m_lastCanal(-1), m_folder(folder), m_musicName(""), m_music(0x0)
{}

Sounderer::~Sounderer()
{
    // Musique
    if (m_music != 0x0) Mix_FreeMusic(m_music);

    // Canaux
    for( m_it = m_paquet.begin(); m_it != m_paquet.end(); m_it++ )
        if (m_it->second != 0x0)
        {
            //Lib�ration m�moire
            Mix_FreeChunk(m_it->second);
            m_it->second = 0x0;
        }
}

bool Sounderer::init()
{
    ///SDL extend init
    SDL_InitSubSystem(SDL_INIT_AUDIO);

    ///Impl�mentation des param�tres
    m_rate = 22050;
	m_format = AUDIO_S16SYS;
	m_nbChannels = 2;
	m_bufferSize = 4096;

	///D�marrage du mixer avec les param�tres d�sir�s
	if ( Mix_OpenAudio(m_rate, m_format, m_nbChannels, m_bufferSize) != 0 ) {
		std::cout <<"Impossible d'initialiser le syst�me audio SDL_mixer avec les param�tres d�finis : "<<Mix_GetError()<< std::endl;
		return false;
	}

	///Initialisation termin�e
    return true;
}

bool Sounderer::preLoad(std::string nom, short extension)
{
	/// Cherche le son dans le tableau
    m_it = m_paquet.find(nom);

    /// Si le son est d�j� charg�, pas beson de le refaire
    if (m_it != m_paquet.end())
    {
        if (m_paquet[nom] == 0x0) return false;
        else return true;
    }

    /// Sinon on le charge
    else
    {
        //D�finit l'extension
        std::string ext;
        if (extension == EXT_OGG) ext = ".ogg";
        else ext = ".wav";

        //Compose le source puis le charge
        std::string source(m_folder + nom + ext);
        m_paquet[nom] = Mix_LoadWAV(source.c_str());

        //Teste une erreur
        if (m_paquet[nom] == 0x0)
        {
            std::cout << "Le son " <<nom<< ".wav n'a pas pu �tre charg� : " << Mix_GetError() << std::endl << std::endl;
            return false;
        }

        //Attribut canal libre et r�serv�
        m_lastCanal++;
        m_channel[nom] = m_lastCanal;
    }

    // Fonction termin�e
    return true;
}

bool Sounderer::play(std::string nom, int repetition)
{
    //Capture le canal et joue le son
    if (preLoad(nom))
        m_channel[nom] = Mix_PlayChannel(m_channel[nom], m_paquet[nom], repetition);
    else return false;

	if(m_channel[nom] == -1) {
		std::cout <<"Impossible de jouer le son ''"<<nom<<"'' : "<<Mix_GetError()<< std::endl;
		return false;
	}

	//Fin
	return true;
}

bool Sounderer::fadePlay(std::string nom, int crescendoLenght, int repetition)
{
    //Capture le canal et joue le son
    if (preLoad(nom))
        m_channel[nom] = Mix_FadeInChannel(m_channel[nom], m_paquet[nom], repetition, crescendoLenght);
    else return false;

	if(m_channel[nom] == -1) {
		std::cout <<"Impossible de jouer le son ''"<<nom<<"'' : "<<Mix_GetError()<< std::endl;
		return false;
	}

	//Fin
	return true;
}

bool Sounderer::stop(std::string nom)
{
    if ( m_paquet.find(nom) != m_paquet.end() )
        if ( Mix_Playing(m_channel[nom]) )
        {
            Mix_HaltChannel(m_channel[nom]);
            return true;
        }
    return false;
}

void Sounderer::stopAll()
{
    Mix_HaltChannel(-1);
}

bool Sounderer::startMusic(std::string musicName)
{
    /// 1 S�curit� de pr�sence d'une musique
    if (m_music == 0x0)
    {
        if (musicName != "")
        {
            m_music = Mix_LoadMUS( (m_folder + musicName + ".wav").c_str());
        }

        if (m_music == 0x0){
            std::cout << "Sounderer::startMusic > 1 :" << Mix_GetError() << std::endl;
            return false;
        }
    }

    /// 2 Charge si la musique est diff�rente
    else if (musicName != m_musicName)
    {
        // Charge la nouvelle musique
        Mix_Music* otherMusic(0x0);
        otherMusic = Mix_LoadMUS( (m_folder + musicName + ".wav").c_str());

        // Si la nouvelle musique est bien charg�e, on l'attribue
        if (otherMusic == 0x0)
            std::cout << "Sounderer::startMusic > 2 :" << Mix_GetError() << std::endl;
        else {
            Mix_FreeMusic(m_music);
            m_music = otherMusic;
            otherMusic = 0x0;
            m_musicName = musicName;
        }
    }

    /// 3 Lancement de l'extrait et s�curit�
    if (Mix_FadeInMusic(m_music, INFINITY_LOOP, 3692) == 0)
        return true;
    else {
        std::cout << "Sounderer::startMusic > 3 :" << Mix_GetError() << std::endl;
        return false;
    }
}

void Sounderer::assignFolder(std::string folder)
{
    m_folder = folder;
}