/*
   Copyright (C) 2001 Carsten Duvenhorst <duvenhorst@m2.uni-hannover.de>

   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 <tdeconfig.h>
#include <klineedit.h>
#include <tdelocale.h>

#include <tqcheckbox.h>
#include <tqcombobox.h>
#include <tqgroupbox.h>
#include <tqslider.h>
#include <tqtabwidget.h>
#include <tdeaboutdata.h>
#include <knuminput.h>
#include <tqregexp.h>
#include <tqlabel.h>

#include <audiocdencoder.h>
#include "kcmaudiocd.moc"
#include <tdeconfigdialogmanager.h>

KAudiocdModule::KAudiocdModule(TQWidget *parent, const char *name)
  : AudiocdConfig(parent, name), configChanged(false)
{
    TQString foo = i18n("Report errors found on the cd.");

    setButtons(Default|Apply|Help);

    config = new TDEConfig("kcmaudiocdrc");

    TQPtrList<AudioCDEncoder> encoders;
    AudioCDEncoder::findAllPlugins(0, encoders);
    AudioCDEncoder *encoder;
    for ( encoder = encoders.first(); encoder; encoder = encoders.next() ){
      if (encoder->init()) {
        TDEConfigSkeleton *config = NULL;
        TQWidget *widget = encoder->getConfigureWidget(&config);
        if(widget && config){
	   tabWidget->addTab(widget, i18n("%1 Encoder").arg(encoder->type()));
             TDEConfigDialogManager *configManager = new TDEConfigDialogManager(widget, config, TQString(encoder->type()+" EncoderConfigManager").latin1());
           encoderSettings.append(configManager);
        }
      }
    }

    load();
  
    TDEConfigDialogManager *widget;
    for ( widget = encoderSettings.first(); widget; widget = encoderSettings.next() ){
      connect(widget, TQ_SIGNAL(widgetModified()), this, TQ_SLOT(slotModuleChanged()));
    }
   
    //CDDA Options
    connect(cd_specify_device,TQ_SIGNAL(clicked()),this,TQ_SLOT(slotConfigChanged()));
    connect(ec_enable_check,TQ_SIGNAL(clicked()),this,TQ_SLOT(slotEcEnable()));
    connect(ec_skip_check,TQ_SIGNAL(clicked()),TQ_SLOT(slotConfigChanged()));
    connect(cd_device_string,TQ_SIGNAL(textChanged(const TQString &)),TQ_SLOT(slotConfigChanged()));
    connect(niceLevel,TQ_SIGNAL(valueChanged(int)),TQ_SLOT(slotConfigChanged()));

    // File Name
    connect(fileNameLineEdit, TQ_SIGNAL(textChanged(const TQString &)), this, TQ_SLOT(slotConfigChanged()));
    connect(albumNameLineEdit, TQ_SIGNAL(textChanged(const TQString &)), this, TQ_SLOT(slotConfigChanged()));
    connect( kcfg_replaceInput, TQ_SIGNAL( textChanged(const TQString&) ), this, TQ_SLOT( updateExample() ) );
    connect( kcfg_replaceOutput, TQ_SIGNAL( textChanged(const TQString&) ), this, TQ_SLOT( updateExample() ) );
    connect( example, TQ_SIGNAL( textChanged(const TQString&) ), this, TQ_SLOT( updateExample() ) );
    connect( kcfg_replaceInput, TQ_SIGNAL( textChanged(const TQString&) ), this, TQ_SLOT( slotConfigChanged() ) );
    connect( kcfg_replaceOutput, TQ_SIGNAL( textChanged(const TQString&) ), this, TQ_SLOT( slotConfigChanged() ) );
    connect( example, TQ_SIGNAL( textChanged(const TQString&) ), this, TQ_SLOT( slotConfigChanged() ) );

    TDEAboutData *about =
    new TDEAboutData(I18N_NOOP("kcmaudiocd"), I18N_NOOP("TDE Audio CD IO Slave"),
                   0, 0, TDEAboutData::License_GPL,
                   I18N_NOOP("(c) 2000 - 2005 Audio CD developers"));

    about->addAuthor("Benjamin C. Meyer", I18N_NOOP("Current Maintainer"), "ben@meyerhome.net");
    about->addAuthor("Carsten Duvenhorst", 0, "duvenhorst@duvnet.de");
    setAboutData(about);
}

KAudiocdModule::~KAudiocdModule()
{
    delete config;
}

TQString removeQoutes(const TQString& text)
{
   TQString deqoutedString=text;
   TQRegExp qoutedStringRegExp("^\".*\"$");
   if (qoutedStringRegExp.exactMatch(text))
   {
      deqoutedString=text.mid(1, text.length()-2);
   }
   return deqoutedString;
}

bool needsQoutes(const TQString& text)
{
   TQRegExp spaceAtTheBeginning("^\\s+.*$");
   TQRegExp spaceAtTheEnd("^.*\\s+$");
   return (spaceAtTheBeginning.exactMatch(text) || spaceAtTheEnd.exactMatch(text));
   
   
}

void KAudiocdModule::updateExample()
{
  TQString text = example->text();
  TQString deqoutedReplaceInput=removeQoutes(kcfg_replaceInput->text());
  TQString deqoutedReplaceOutput=removeQoutes(kcfg_replaceOutput->text());

  text.replace( TQRegExp(deqoutedReplaceInput), deqoutedReplaceOutput );
  exampleOutput->setText(text);
}

void KAudiocdModule::defaults() {
	load( false );
}

void KAudiocdModule::save() {
  if (!configChanged ) return;

  {
    TDEConfigGroupSaver saver(config, "CDDA");

    // autosearch is the name of the config option, which has the
    // reverse sense of the current text of the configuration option,
    // which is specify the device. Therefore, invert the value on write.
    //
    config->writeEntry("autosearch", !(cd_specify_device->isChecked()) );
    config->writeEntry("device",cd_device_string->text());
    config->writeEntry("disable_paranoia",!(ec_enable_check->isChecked()));
    config->writeEntry("never_skip",!(ec_skip_check->isChecked()));
    config->writeEntry("niceLevel", niceLevel->value());
  }
  
  {
    TDEConfigGroupSaver saver(config, "FileName");
    config->writeEntry("file_name_template", fileNameLineEdit->text());
    config->writeEntry("album_name_template", albumNameLineEdit->text());
    config->writeEntry("regexp_example", example->text());
    // save qouted if required
    TQString replaceInput=kcfg_replaceInput->text();
    TQString replaceOutput=kcfg_replaceOutput->text();
    if (needsQoutes(replaceInput))
    {
       replaceInput=TQString("\"")+replaceInput+TQString("\"");
    }
    if (needsQoutes(replaceOutput))
    {
       replaceOutput=TQString("\"")+replaceOutput+TQString("\"");
    }
    config->writeEntry("regexp_search", replaceInput);
    config->writeEntry("regexp_replace", replaceOutput);
  }

  TDEConfigDialogManager *widget;
  for ( widget = encoderSettings.first(); widget; widget = encoderSettings.next() ){
    widget->updateSettings();
  }
  
  config->sync();

  configChanged = false;

}

void KAudiocdModule::load() {
	load( false );
}

void KAudiocdModule::load(bool useDefaults) {

	config->setReadDefaults( useDefaults );

  {
    TDEConfigGroupSaver saver(config, "CDDA");


    // Specify <=> not autosearch, as explained above in ::save()
    cd_specify_device->setChecked( !(config->readBoolEntry("autosearch",true)) );
    cd_device_string->setText(config->readEntry("device","/dev/cdrom"));
    ec_enable_check->setChecked(!(config->readBoolEntry("disable_paranoia",false)));
    ec_skip_check->setChecked(!(config->readBoolEntry("never_skip",true)));
    niceLevel->setValue(config->readNumEntry("niceLevel", 0));
  }

  {
    TDEConfigGroupSaver saver(config, "FileName");
    fileNameLineEdit->setText(config->readEntry("file_name_template", "%{albumartist} - %{number} - %{title}"));
    albumNameLineEdit->setText(config->readEntry("album_name_template", "%{albumartist} - %{albumtitle}"));
    kcfg_replaceInput->setText(config->readEntry("regexp_search"));
    kcfg_replaceOutput->setText(config->readEntry("regexp_replace"));
    example->setText(config->readEntry("example", i18n("Cool artist - example audio file.wav")));
  }
  
  TDEConfigDialogManager *widget;
  for ( widget = encoderSettings.first(); widget; widget = encoderSettings.next() ){
    widget->updateWidgets();
  }

  emit changed( useDefaults );
}

TQString KAudiocdModule::handbookSection() const
{
 	int index = tabWidget->currentPageIndex();
 	if (index == 0)
		return "audiocd-general";
	else if (index == 1)
		return "audiocd-names";
 	else
 		return TQString::null;
}

void KAudiocdModule::slotModuleChanged() {
	TDEConfigDialogManager *widget;
	for ( widget = encoderSettings.first(); widget; widget = encoderSettings.next() ){
		if(widget->hasChanged()){
			slotConfigChanged();
			break;
		}
	}
}

void KAudiocdModule::slotConfigChanged() {
	configChanged = true;
	emit changed(true);
}

/*
#    slot for the error correction settings
*/
void KAudiocdModule::slotEcEnable() {
  if (!(ec_skip_check->isChecked())) {
    ec_skip_check->setChecked(true);
  } else {
    if (ec_skip_check->isEnabled()) {
      ec_skip_check->setChecked(false);
    }
  }

  slotConfigChanged();
}

TQString KAudiocdModule::quickHelp() const
{
  return i18n("<h1>Audio CDs</h1> The Audio CD IO-Slave enables you to easily"
              " create wav, MP3 or Ogg Vorbis files from your audio CD-ROMs or DVDs."
              " The slave is invoked by typing <i>\"audiocd:/\"</i> in Konqueror's location"
              " bar. In this module, you can configure"
              " encoding, and device settings. Note that MP3 and Ogg"
              " Vorbis encoding are only available if TDE was built with a recent"
              " version of the LAME or Ogg Vorbis libraries.");
}

extern "C"
{
    TDECModule *create_audiocd(TQWidget *parent, const char */*name*/)
    {
        return new KAudiocdModule(parent, "kcmaudiocd");
    }

}
