//
// C++ Implementation: soundprovider
//
// Description: 
//
//
// Author: Eitzenberger Thomas <kde@atpc310d>, (C) 2009
//
// Copyright: See COPYING file that comes with this distribution
//
//
#include "soundproviderfactory.h"

#include <KDebug>

SoundProviderFactory* SoundProviderFactory::instance = NULL;

SoundProviderFactory::SoundProviderFactory(QObject* parent) : QObject(parent)
{
  kDebug() << "CREATED!";
  m_registeredProviders = new ProviderList();
}

SoundProviderFactory::~SoundProviderFactory() {
  delete m_soundfile;
  delete m_audioOutput;
}

bool SoundProviderFactory::init(QObject* parent, Phonon::AudioOutput* audioOutput) {
  if (parent == NULL) {
    kDebug() << "NULL parent not allowed!";
    return false;
  }
  if (instance == NULL) {
    kDebug() << "INSTANCE TO BE CREATED !!!!!!!!!";
    instance = new SoundProviderFactory(parent);
  }
  instance->m_parent = parent;
  if (audioOutput != NULL) {
    instance->m_audioOutput = audioOutput;
    instance->m_soundfile = new Phonon::MediaObject(parent);
    Phonon::createPath(instance->m_soundfile, instance->m_audioOutput);
  }
  return true;
}

QString /*item*/ SoundProviderFactory::getSoundFile(QString lesson, QString item, QString lang) {
  KUrl soundurl;
  
  foreach (SoundProvider* prov, *m_registeredProviders) {
    kDebug() << "checking soundprovider " << prov->name() << " for item:" << item << " in lang:" << lang;
    // check first for local cached data
    if (prov->localCacheActive()) {
      soundurl = prov->lookupSoundUrlForItem(lesson, item, lang, SoundProvider::LOCALCACHE);
    }
    if (!soundurl.isEmpty()) {
      kDebug() << "local file found for item:" << item;
      emit soundFileLoaded(item, soundurl); 
      return item;
    }
  }
  // now search remotely and if cache supproted and active cache data locally
  if (soundurl.isEmpty()) {
    kDebug() << "now checking REMOTELY for " << item;
    foreach (SoundProvider* prov, *SoundProviderFactory::get()->m_registeredProviders) {
      kDebug() << "checking soundprovider " << prov->name() << " for item:" << item;
      soundurl = prov->lookupSoundUrlForItem(lesson, item, lang, SoundProvider::REMOTE);
    }
  }
  return item;
}

void SoundProviderFactory::_soundFileLoaded(QString item, KUrl soundurl) {
  emit soundFileLoaded(item, soundurl);
}

bool SoundProviderFactory::playSoundFile(KUrl soundurl) {
  if (!soundurl.isEmpty()) {
    if (m_audioOutput == NULL) {
      m_audioOutput = new Phonon::AudioOutput(Phonon::MusicCategory);
      m_soundfile = new Phonon::MediaObject(m_parent);
      Phonon::createPath(m_soundfile, m_audioOutput);
    }
    if (m_parent == NULL) {
      kDebug() << "Unable to create phonon soundfile " << soundurl << " - SoundProviderFactory not initialised!"; 
      return false;
    }
    m_soundfile->setCurrentSource(soundurl);
    kDebug() << "PHONON playing: '" << soundurl <<"'";
    m_soundfile->play();

    return true;
  } else {
    kDebug() << "Sound URL is EMPTY: " << soundurl;
  } 
  return false;
}

bool SoundProviderFactory::registerProvider(QString providerName, int priority, SoundProvider* provider)
{
  if (m_registeredProviders->contains(provider)) {
    kDebug() << "sound provider " << providerName << " already registered as " << provider->name();
    
    return false;
  }
  SoundProvider* existingProvider = _getProvider(providerName);
  if (existingProvider != NULL) {
    kDebug() << "duplicate registration of sound provider name " << providerName << " with different providers. Aborting registration";
    
    return false;
  }
  
  ProviderList::iterator it;
  for (it = m_registeredProviders->begin(); it != m_registeredProviders->end(); ++it) {
    if ((*it)->priority() < priority) {
      m_registeredProviders->insert(it, provider);
      provider->m_providerName = providerName;
      provider->m_priority = priority;
      
      return true;
    }
  }
  m_registeredProviders->append(provider);
  provider->m_providerName = providerName;
  provider->m_priority = priority;
  connect(provider, SIGNAL(soundFileLoaded(QString, KUrl)), this, SLOT(_soundFileLoaded(QString, KUrl)));
  kDebug() << "soundprovider " << providerName << " registered!";
  return true;
}

bool SoundProviderFactory::unregisterProvider(QString providerName) {
  SoundProvider* provider = _getProvider(providerName);
  if (provider != NULL) {
    m_registeredProviders->removeOne(provider);
    provider->m_providerName = "";
    disconnect(provider, SIGNAL(soundFileLoaded(QString, KUrl)), this, SLOT(_soundFileLoaded(QString, KUrl)));
    kDebug() << "soundprovider " << providerName << " unregistered";
    
    return true;
  }
  kDebug() << "unregistration of sound provider " << providerName << " failed as no registered instance found";
  
  return false;
}

SoundProvider* SoundProviderFactory::getProvider(QString providerName) {
  SoundProvider* provider = _getProvider(providerName);
  if (provider == NULL) {
    kDebug() << "Unable to find sound provider with name " << providerName;
  }
  return provider;
}

SoundProvider* SoundProviderFactory::_getProvider(QString providerName) {
  foreach (SoundProvider* prov, *m_registeredProviders) {
    if (prov->name() == providerName) {
      return prov;
    }
  }
  return NULL;
}


#include "soundproviderfactory.moc"
