/**
 * This file is part of the KAudioCreator package
 * Copyright (C) 2003 Benjamin C Meyer (ben+kaudiocreator at meyerhome dot net)
 *
 * 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 library 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

#include "encoderconfigimp.h"
#include "encoderedit.h"
#include "prefs.h"

#include <tqpushbutton.h>
#include <tqlineedit.h>
#include <tdeconfigdialog.h>
#include <tdemessagebox.h>
#include <tdelocale.h>
#include <tdeconfig.h>

/**
 * Constructor.
 */
EncoderConfigImp::EncoderConfigImp( TQWidget* parent, const char* name) :
    EncoderConfig (parent, name) {
  connect(addEncoder, TQ_SIGNAL(clicked()), this, TQ_SLOT(addEncoderSlot()));
  connect(removeEncoder, TQ_SIGNAL(clicked()), this, TQ_SLOT(removeEncoderSlot()));
  connect(configureEncoder, TQ_SIGNAL(clicked()), this, TQ_SLOT(configureEncoderSlot()));
  connect(kcfg_currentEncoder, TQ_SIGNAL(doubleClicked ( TQListBoxItem * )),this, TQ_SLOT(configureEncoderSlot()));

  // If there are no encoders then store the three default ones.
  if( Prefs::lastKnownEncoder() == 0){
    EncoderPrefs *encPrefs;

    encPrefs = EncoderPrefs::prefs("Encoder_0");
    encPrefs->setEncoderName(i18n("Ogg Vorbis"));
    encPrefs->setCommandLine("oggenc -o %o --artist %{artist} --album %{albumtitle} --title %{title} --date %{year} --tracknum %{number} --genre %{genre} %f");
    encPrefs->setExtension("ogg");
    encPrefs->setPercentLength(4);
    encPrefs->writeConfig();

    encPrefs = EncoderPrefs::prefs("Encoder_1");
    encPrefs->setEncoderName(i18n("MP3"));
    encPrefs->setCommandLine("lame --preset standard --tt %{title} --ta %{artist} --tl %{albumtitle} --ty %{year} --tn %{number} --tg %{genre} %f %o");
    encPrefs->setExtension("mp3");
    encPrefs->setPercentLength(2);
    encPrefs->writeConfig();

    encPrefs = EncoderPrefs::prefs("Encoder_2");
    encPrefs->setEncoderName(i18n("Wav"));
    encPrefs->setCommandLine("mv %f %o");
    encPrefs->setExtension("wav");
    encPrefs->setPercentLength(2);
    encPrefs->writeConfig();

    encPrefs = EncoderPrefs::prefs("Encoder_3");
    encPrefs->setEncoderName(i18n("FLAC"));
    encPrefs->setCommandLine("flac --best -o %o --tag=Artist=%{artist} --tag=Album=%{albumtitle} --tag=Date=%{year} --tag=Title=%{title} --tag=Tracknumber=%{number} --tag=Genre=%{genre} %f");
    encPrefs->setExtension("flac");
    encPrefs->setPercentLength(2);
    encPrefs->writeConfig();

    Prefs::setLastKnownEncoder(3);
    Prefs::writeConfig();
  }

  loadEncoderList();
}

/**
 * Clear map
 * Clear listbox
 * Load list of encoders.
 */
void EncoderConfigImp::loadEncoderList(){
  encoderNames.clear();
  kcfg_currentEncoder->clear();

  bool foundCurrentEncoder = false;

  int lastEncoder = 0;
  int lastKnownEncoder = Prefs::lastKnownEncoder();
  lastKnownEncoder++;
  for( int i=0; i<=lastKnownEncoder; i++ ){
    TQString currentGroup = TQString("Encoder_%1").arg(i);
    if(EncoderPrefs::hasPrefs(currentGroup)){
      lastEncoder = i;
      EncoderPrefs *encPrefs = EncoderPrefs::prefs(currentGroup);
      TQString encoderName = encPrefs->encoderName();
      kcfg_currentEncoder->insertItem(encoderName);
      encoderNames.insert(encoderName, currentGroup);
      if(Prefs::currentEncoder() == i)
	foundCurrentEncoder = true;
    }
  }
  if(lastEncoder != Prefs::lastKnownEncoder()){
    Prefs::setLastKnownEncoder(lastEncoder);
    Prefs::writeConfig();
  }

  // Make sure that the current encoder is valid.
  if(!foundCurrentEncoder && kcfg_currentEncoder->count() > 0)
    kcfg_currentEncoder->setCurrentItem(0);
}

/**
 * Find empty group
 * bring up dialog for that group.
 */
void EncoderConfigImp::addEncoderSlot(){
  bool foundEmptyGroup = false;
  uint number = 0;
  TQString groupName;
  while(!foundEmptyGroup){
    groupName = TQString("Encoder_%1").arg(number);
    if(!EncoderPrefs::hasPrefs(groupName))
      foundEmptyGroup = true;
    else
      number++;
  }

  if(TDEConfigDialog::showDialog(groupName.latin1()))
    return;

  TDEConfigDialog *dialog = new TDEConfigDialog(this, groupName.latin1(), EncoderPrefs::prefs(groupName), 
                                            KDialogBase::Swallow,
                                            KDialogBase::Ok | KDialogBase::Cancel | KDialogBase::Help);
  dialog->setCaption(i18n("Configure Encoder"));
  dialog->addPage(new EncoderEdit(0, groupName.latin1()), i18n("Encoder Configuration"), "package_settings");
  connect(dialog, TQ_SIGNAL(settingsChanged()), this, TQ_SLOT(loadEncoderList()));
  dialog->show();
}

/**
 * If
 * Something is selected
 * There is more then 1 thing left
 * The user says ok to delete.
 * Is not the current encoder.
 * Then
 * The group is removed from the list
 * Deleted from the config.
 */
void EncoderConfigImp::removeEncoderSlot(){
  if(!kcfg_currentEncoder->selectedItem()){
    KMessageBox:: sorry(this, i18n("Please select an encoder."), i18n("No Encoder Selected"));
    return;
  }
  if(kcfg_currentEncoder->count() <= 1){
    KMessageBox:: sorry(this, i18n("At least one encoder must exist."), i18n("Can Not Remove"));
    return;
  }
  if(KMessageBox::warningContinueCancel(this, i18n("Delete encoder?"), i18n("Delete Encoder"),KStdGuiItem::del())
      == KMessageBox::Cancel )
    return;

  TQString groupName = encoderNames[kcfg_currentEncoder->currentText()];
  kcfg_currentEncoder->removeItem(kcfg_currentEncoder->currentItem());

  delete TDEConfigDialog::exists(groupName.latin1());

  EncoderPrefs::deletePrefs(groupName);
}

/**
 * If
 * Something is selected
 * Group exists
 * Then
 * Bring up dialog
 */
void EncoderConfigImp::configureEncoderSlot() {
  if(!kcfg_currentEncoder->selectedItem()){
    KMessageBox:: sorry(this, i18n("Please select an encoder."), i18n("No Encoder Selected"));
    return;
  }
  TQString groupName = encoderNames[kcfg_currentEncoder->currentText()];
  TDEConfig &config = *TDEGlobal::config();
  if(!config.hasGroup(groupName))
    return;

  if(TDEConfigDialog::showDialog(groupName.latin1()))
    return;

  TDEConfigDialog *dialog = new TDEConfigDialog(this, groupName.latin1(), EncoderPrefs::prefs(groupName),
                                            KDialogBase::Swallow,
                                            KDialogBase::Ok | KDialogBase::Cancel | KDialogBase::Help);
  dialog->setCaption(i18n("Configure Encoder"));
  dialog->addPage(new EncoderEdit(0, groupName.latin1()), i18n("Encoder Configuration"), "package_settings");
  connect(dialog, TQ_SIGNAL(destroyed(TQObject *)), this, TQ_SLOT(updateEncoder(TQObject *)));
  connect(dialog, TQ_SIGNAL(settingsChanged()), this, TQ_SIGNAL(encoderUpdated()));
  connect(dialog, TQ_SIGNAL(settingsChanged(const char *)), this, TQ_SLOT(updateEncoder(const char *)));
  dialog->show();
}

/**
 * If object exists update encoder
 */
void EncoderConfigImp::updateEncoder(TQObject * obj){
  if(!obj)
   return;
  updateEncoder(obj->name());
}

/**
 * If
 * Exists
 * Then
 * Get name
 * Make sure group exists
 * Update name
 * Update Map
 * If current encoder update also.
 */
void EncoderConfigImp::updateEncoder(const char *dialogName){
  TQString groupName = dialogName;
  TQString encoderName;
  bool found = false;
  TQMap<TQString, TQString>::Iterator it;
  for ( it = encoderNames.begin(); it != encoderNames.end(); ++it ) {
    if(it.data() == groupName){
      found = true;
      encoderName = it.key();
    }
  }
  if(!found)
    return;
  if(!EncoderPrefs::hasPrefs(groupName))
    return;
  TQString newName = EncoderPrefs::prefs(groupName)->encoderName();
  if(newName == encoderName)
    return;

  TQListBoxItem *item = kcfg_currentEncoder->findItem(encoderName);
  if(!item)
    return;
  kcfg_currentEncoder->changeItem(newName, kcfg_currentEncoder->index(item));

  encoderNames.insert(newName, groupName);
  encoderNames.erase(encoderName);
}

TQDict<EncoderPrefs> *EncoderPrefs::m_prefs = 0;

EncoderPrefs *EncoderPrefs::prefs(const TQString &groupName)
{
  if (!m_prefs)
  {
     m_prefs = new TQDict<EncoderPrefs>();
     m_prefs->setAutoDelete(true);
  }
  EncoderPrefs *encPrefs = m_prefs->find(groupName);
  if (encPrefs)
    return encPrefs;

  encPrefs = new EncoderPrefs(groupName);
  encPrefs->readConfig();
  m_prefs->insert(groupName, encPrefs);
  return encPrefs;
}

bool EncoderPrefs::hasPrefs(const TQString &groupName)
{
  TDEConfig &config = *TDEGlobal::config();
  return config.hasGroup(groupName);
}

void EncoderPrefs::deletePrefs(const TQString &groupName)
{
  TDEConfig &config = *TDEGlobal::config();
  config.deleteGroup(groupName);
  if (!m_prefs)
    return;
  m_prefs->remove(groupName);
}

#include "encoderconfigimp.moc"

