/* -------------------------------------------------------------
   From KDE Tuberling
   mailto:e.bischoff@noos.fr
 ------------------------------------------------------------- */
/*
 * Copyright (C) 2001 Eric Bischoff
   2004-2007 Anne-Marie Mahfouf <annma@kde.org>

    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */

#include "soundfactory.h"

#include <KMessageBox>
#include <KLocale>
#include <KDebug>
#include <KRandomSequence>
#include <KStandardDirs>
#include <Phonon/MediaObject>

#include "klettres.h"
#include "prefs.h"

SoundFactory::SoundFactory(KLettres *parent, const char *)
        : QObject(parent), m_player(0)
{
    klettres = parent;

    namesList.clear();
    filesList.clear();
    sounds = 0;

    bool ok = klettres->loadLayout(m_layoutsDocument);
    if (ok)  {
	change(Prefs::language());
    }
    if (!ok)  {
	loadFailure();
    }  else  {
	setSoundSequence();
    }
}

SoundFactory::~SoundFactory()
{
}

void SoundFactory::change(const QString &currentLanguage)
{
    //go load the sounds for the current language
    bool ok = loadLanguage(m_layoutsDocument, currentLanguage);
    //tell the user if there are no sounds or get the random sounds
    if (!ok)  {
	loadFailure();
    }  else  {
	setSoundSequence();
    }
}

void SoundFactory::playSound(int mySound)
{
    QString soundFile;

    if ((uint) mySound >= sounds) {
	return;
    }

    soundFile = KStandardDirs::locate("data", "klettres/" + filesList[mySound]);
    kDebug() << "soundFile " << soundFile;

    if (soundFile.isEmpty()) {
	return;
    }

    if (!m_player)  {
        m_player = Phonon::createPlayer(Phonon::GameCategory, soundFile);
        m_player->setParent(this);
    }  else  {
        m_player->setCurrentSource(soundFile);
    }
    m_player->play();
}

void SoundFactory::loadFailure()
{
    KMessageBox::error(klettres, i18n("Error while loading the sound names."));
}

bool SoundFactory::loadLanguage(QDomDocument &layoutDocument, const QString &currentLanguage)
{
    QDomNodeList languagesList,
    alphabetList,
    syllablesList,
    soundNamesList;
    QDomElement languageElement,
    alphabetElement,
    syllableElement,
    soundNameElement;
    QDomAttr nameAttribute, fileAttribute;

    languagesList = layoutDocument.elementsByTagName("language");
    QDomAttr codeAttribute;
    //check if the sound files match current language
    languageElement = (const QDomElement &) languagesList.item(0).toElement();
    codeAttribute = languageElement.attributeNode("code");

    if (currentLanguage != codeAttribute.value()) {
        kDebug() << "Fail reading language !!! ";
        return false;
    } else {
	kDebug() << "current language " << currentLanguage;
    }
    //load the sounds for level 1 and 2 (alphabet)
    if ((Prefs::level() == 1) || (Prefs::level() == 2))  {
        alphabetList = languageElement.elementsByTagName("alphabet");
        if (alphabetList.count() != 1) {
            return false;
	}
        alphabetElement = (const QDomElement &) alphabetList.item(0).toElement();
        soundNamesList = alphabetElement.elementsByTagName("sound");
    }

    //load the sounds for level 3 and 4 (syllables)
    if ((Prefs::level() == 3) || (Prefs::level() == 4))  {
        syllablesList = languageElement.elementsByTagName("syllables");
        if (syllablesList.count() != 1)
            return false;

        syllableElement = (const QDomElement &) syllablesList.item(0).toElement();

        soundNamesList = syllableElement.elementsByTagName("sound");
    }
    //Counts the number of sounds
    sounds = soundNamesList.count();
    kDebug() << "number of sounds" << sounds << endl;
    if (sounds < 1)  {
        return false;
    }
    namesList.clear();
    filesList.clear();

    for (uint sound = 0; sound < sounds; sound++)  {
        soundNameElement = (const QDomElement &) soundNamesList.item(sound).toElement();
        nameAttribute = soundNameElement.attributeNode("name");
        //namesList helds the names of the letter or syllable to display
        namesList.append(nameAttribute.value());
        fileAttribute = soundNameElement.attributeNode("file");
        //filesList helds the names of the sound files (i.e the location of the sounds like fr/alpha/a-0.mp3)
        filesList.append(fileAttribute.value());
    }
    if (namesList.isEmpty()) {
	return false;
    }
    if (filesList.isEmpty())  {
	return false;
    }
    return true;
}

void SoundFactory::setSoundSequence()
{
    // Seed the random number generator
    KRandomSequence randomSequence;
    randomList.clear();
    //get the number of sounds then shuffle it: each number will be taken once then the sequence will come back
    for (uint j = 0; j < sounds; j++) 
        randomList.append(j);

    randomSequence.randomize(randomList);
}

#include "soundfactory.moc"
