//
// C++ Interface: soundprovider
//
// Description: 
//
//
// Author: Eitzenberger Thomas <kde@atpc310d>, (C) 2009
//
// Copyright: See COPYING file that comes with this distribution
//
//
#ifndef SOUNDPROVIDERFACTORY_H
#define SOUNDPROVIDERFACTORY_H

#include <QObject>
#include <QLinkedList>
#include <QThread>

#include <KDebug>
#include <KUrl>

#include "phonon/audiooutput.h"
#include "phonon/mediaobject.h"

#include "soundprovider.h"

#include "libkedusoundprovider_export.h"

typedef QLinkedList<SoundProvider*> ProviderList;

/// This class provides the interface to use voice files form the internet or locally cached sound files to be played for a given word/language pair.
 /**
  * It uses SoundProvider instances that are registered to the factory to check for existig sound files and emits a signal if/when a 
  * valid sound file has been found.
  * As a first step the factory needs to be initialized. Next step is to create and register a specific Soundprovider and 
  * connect the signal of the factory to a local callback method. In this callback slot the factory's playSoundFile method 
  * can be called to play the sound file via phonon. Below you can see an examplaric code sample...
  *
  * <pre>
  *   SoundProviderFactory::init(this, NULL); // "this" param is a QWidget e.g.
  *  
  *   SoundProviderFactory* factory = SoundProviderFactory::get();
  *
  *   WiktionaryProvider* wikiprov = new WiktionaryProvider(factory);
  *   factory->registerProvider("wiktionary", 90, wikiprov);
  *
  *   // connect the signal to a receiving slot that 
  *   // deals with the finally received sound file
  *   connect(factory, SIGNAL(soundFileLoaded(QString, KUrl)), 
  *           this, SLOT(soundFileLoaded(QString, KUrl)));
  *   ...
  *   // Sometime later :O)
  *   SoundProviderFactory* factory = SoundProviderFactory::get();
  *   factory->getSoundFile(lesson, word, lang);
  *
  *   // After the sound file has been found , and optionally downloaded 
  *   // the sondFileLoaded SLOT will be called in which you can play the soundurl
  *   // or remember this soundurl in a member field and 
  *   // play it later on button click request using:
  *
  *   factory->playSoundFile(KUrl(m_soundUrl));
  *
  * </pre>
  */
class LIBKEDUSOUNDPROVIDER_EXPORT SoundProviderFactory : public QObject {
  Q_OBJECT
      
  //TODO add feature to allow application to specify in which local folder to cache data locally
  public:
    ~SoundProviderFactory();
    static bool init(QObject* parent, Phonon::AudioOutput* audioOutput = NULL);
    static SoundProviderFactory* get() { return instance; }
    
    bool registerProvider(QString providerName, int priority, SoundProvider* provider);
    SoundProvider* getProvider(QString providerName);
    bool unregisterProvider(QString providerName);
    
    QString /* thread ID key */ getSoundFile(QString lesson, QString item, QString lang);
    bool playSoundFile(KUrl soundFile);
    
  Q_SIGNALS:
    /// emitted when/if a valid sound file has been found for the given item.
    /**
     * whether the URL is a local or remote one depends on the specific implementation of the 
     * used sound provider instance.
     *
     * @param item word to find a soundfile for
     * @param soundurl URL to a valid local or remote soundfile for the given word.
     */
    void soundFileLoaded(QString /* thread ID key */item, KUrl soundurl);
  
    
  private:
    SoundProviderFactory(QObject* parent);
    
    static SoundProviderFactory* instance;
    
    ProviderList* m_registeredProviders;
    QObject* m_parent;
    Phonon::AudioOutput* m_audioOutput;
    Phonon::MediaObject* m_soundfile;
    
    SoundProvider* _getProvider(QString providerName);
    
  private Q_SLOTS:
    void _soundFileLoaded(QString /* thread ID key */item, KUrl localSoundFile);

    friend class DownloaderThread;
};
#endif
