/***************************************************************************
 *   Copyright (C) 2005-2006 by Andreas Silberstorff   *
 *   ml@andreas-silberstorff.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 Steet, Fifth Floor, Boston, MA 02110-1301, USA.             *
 *                                                                         *
 *   In addition, as a special exception, the copyright holders give       *
 *   permission to link the code of this program with any edition of       *
 *   the Qt library by Trolltech AS, Norway (or with modified versions     *
 *   of Qt that use the same license as Qt), and distribute linked         *
 *   combinations including the two.  You must obey the GNU General        *
 *   Public License in all respects for all of the code used other than    *
 *   Qt.  If you modify this file, you may extend this exception to        *
 *   your version of the file, but you are not obligated to do so.  If     *
 *   you do not wish to do so, delete this exception statement from        *
 *   your version.                                                         *
 ***************************************************************************/
#include "prefs.h"
#include "settings.h"
#include <kalvaprofile.h>
#include <kalvacmd.h>

#include <qstring.h>
#include <qregexp.h>
#include <qapplication.h>
#include <qcheckbox.h>
#include <qtable.h>
#include <qtextedit.h>
#include <qtextstream.h>
#include <qstringlist.h>

#include <ktextedit.h>
#include <kdebug.h>
#include <kglobal.h>
#include <klocale.h>
#include <kconfigbase.h>
#include <kstandarddirs.h>
#include <klineedit.h>
#include <kcombobox.h>
#include <knuminput.h>
#include <klistbox.h>
#include <kprocess.h>
#include <krun.h>
#include <kdirlister.h>
#include <kmessagebox.h>
#include <kdirwatch.h>
#include <kurllabel.h>

#include <qdir.h>
#include <cmath>

#include <kmessagebox.h>

#include <kdeversion.h>
#undef KDE_3_3_FEATURES
#if defined(KDE_MAKE_VERSION)
#if KDE_VERSION >= KDE_MAKE_VERSION(3,3,0)
	#define KDE_3_3_FEATURES
	#include "kalvanewstuff.h"
#endif
#endif

Prefs::Prefs()
	: Prefs_base()
{
#ifdef KDE_3_3_FEATURES
   m_newHWProfiles = 0;
   m_newQProfiles = 0;
   m_newChlsts = 0;
   m_proc = 0;
#endif
kdDebug() << "KALVA_HARDWARE_PROFILE = " << KALVA_HARDWARE_PROFILE << endl;
kdDebug() << "KALVA_QUALITY_PROFILE = " << KALVA_QUALITY_PROFILE << endl;
kdDebug() << "KALVA_CHANNELLIST = " << KALVA_CHANNELLIST << endl;

	m_hwprofile = new KalvaProfile( KALVA_HARDWARE_PROFILE );
	m_qprofile = new KalvaProfile( KALVA_QUALITY_PROFILE );
	m_chlst = new KalvaProfile( KALVA_CHANNELLIST );

   m_hwprofiles_dir = KGlobal::dirs()->saveLocation( "data",
                                                     "kalva/hwprofile", true);
   m_qprofiles_dir  = KGlobal::dirs()->saveLocation( "data",
                                                     "kalva/qprofile",  true);
   m_chlsts_dir     = KGlobal::dirs()->saveLocation( "data",
                                                     "kalva/chlst",     true);
   loadAudiodevList();
   loadHWProfileChooser();
   loadQProfileChooser();
   loadChlstChooser();

   chlstsWatcher = new KDirWatch( this );
//   chlstsWatcher->addDir( m_chlsts_dir, KDirWatch::WatchFiles);
   chlstsWatcher->addDir( m_chlsts_dir, true, false);
   hwprofilesWatcher = new KDirWatch( this );
//   hwprofilesWatcher->addDir( m_hwprofiles_dir, KDirWatch::WatchFiles);
   hwprofilesWatcher->addDir( m_hwprofiles_dir, true, false );
   qprofilesWatcher = new KDirWatch( this );
//   qprofilesWatcher->addDir( m_qprofiles_dir, KDirWatch::WatchFiles );
   qprofilesWatcher->addDir( m_qprofiles_dir, true, false );
   //monitor destDir for changes; reload Chooser when files are created.
   connect( chlstsWatcher, SIGNAL( dirty( const QString & ) ),
            this, SLOT(   slotLoadChlstChooser( const QString & ) ) );
   connect( hwprofilesWatcher, SIGNAL( dirty( const QString & ) ),
            this, SLOT(   slotLoadHWProfileChooser( const QString & ) ) );
   connect( qprofilesWatcher, SIGNAL( dirty( const QString & ) ),
            this, SLOT(   slotLoadQProfileChooser( const QString & ) ) );
}


void Prefs::slotSetAumixdev ( const QString& audiodev )
{
   QString myAudiodev = audiodev.stripWhiteSpace();
   kdDebug() << "in slotSetAumixdev, audiodev = " << audiodev << endl;
   kdDebug() << "stripped audiodev = " << myAudiodev << endl;

   if    ( audiodev.contains( QRegExp("^\\[.*\\]$") ) ) 
      kcfg_aumixdev->setText( QString::null );
   else if ( myAudiodev.compare("vol") == 0 )
       kcfg_aumixdev->setText("v");
   else if ( myAudiodev.compare("bass") == 0 )
       kcfg_aumixdev->setText("b");
   else if ( myAudiodev.compare("cd") == 0 )
       kcfg_aumixdev->setText("c");
   else if ( myAudiodev.compare("igain") == 0 )
       kcfg_aumixdev->setText("i");
   else if ( myAudiodev.compare("mic") == 0 )
       kcfg_aumixdev->setText("m");
   else if ( myAudiodev.compare("lineout") == 0 )
       kcfg_aumixdev->setText("o");
   else if ( myAudiodev.compare("speaker") == 0 )
       kcfg_aumixdev->setText("p");
   else if ( myAudiodev.compare("synthesizer") == 0 )
       kcfg_aumixdev->setText("s");
   else if ( myAudiodev.compare("treble") == 0 )
       kcfg_aumixdev->setText("t");
   else if ( myAudiodev.compare("pcm") == 0 )
       kcfg_aumixdev->setText("w");
   else if ( myAudiodev.compare("imix") == 0 )
       kcfg_aumixdev->setText("x");
   else if ( myAudiodev.compare("line") == 0 )
       kcfg_aumixdev->setText("l");
   else if ( myAudiodev.contains( QRegExp("line\\d") ) )  {
       kcfg_aumixdev->setText( myAudiodev.remove("line") );
   }
   else  {
      kdWarning() << i18n("device not known to aumix") << endl;
      kcfg_aumixdev->setText( QString::null );
   }
}

/*************************************************************************
 * crop and aspect computation
 * (Allghorhythm by Matthias Wieser)
 *************************************************************************/
void Prefs::setCrop ()
{
	float  overscan        = m_hwprofile->getValueFloat( "factor" );
	QString res            = m_qprofile->getValueString( "tvscale" );
	QString targetedAspect = m_qprofile->getValueString( "targetedAspect" );

	KalvaCropAndAspect* computer = new KalvaCropAndAspect(
			overscan, res, targetedAspect
		);
	computer->compute();
	double aspect = computer->getAspect();
	QString crop = computer->getCrop();
	kcfg_crop->setText( crop);
	kcfg_aspect->setText( QString("%1").arg(aspect) );
	return;
}

void Prefs::slotSetCrop( const QString & )
{
   setCrop();
}

void Prefs::slotSetCrop( double )
{
	setCrop();
}

/*************************************************************************
 * 
 *************************************************************************/
void Prefs::setAudiodevList(KProcess *, char* stdOutAudiodevs, int)
{
	QString OutAudiodevs = (QString)stdOutAudiodevs;
	OutAudiodevs.remove( (QRegExp)"\\s\\d+" );
	OutAudiodevs.remove( (QRegExp)"," );
	m_audiodevs = QStringList::split( (QRegExp)"[PR]?\n",
						OutAudiodevs );
	m_audiodev->insertStringList( m_audiodevs, -1 );
	m_audiodev->setCurrentItem( kcfg_audiodev->text() );
}

void Prefs::loadAudiodevList()
{
	m_audiodev->clear();
	m_audiodev->insertItem(i18n("[don't use aumix]"),-1);
	if (!m_proc)
		m_proc = new KProcess;
	(*m_proc) << "aumix" << "-q";
	QApplication::connect(
		m_proc,
		SIGNAL( processExited( KProcess * ) ),
		this,
		SLOT( aumixExited( KProcess * ) ) );
	QApplication::connect(
		m_proc,
		SIGNAL( receivedStdout( KProcess *, char*, int ) ),
		this,
		SLOT( setAudiodevList( KProcess *, char*, int ) ) );
	QApplication::connect(
		m_proc,
		SIGNAL( receivedStderr( KProcess *, char*, int ) ),
		this,
		SLOT( setAudiodevList( KProcess *, char*, int ) ) );
	m_proc->start( KProcess::NotifyOnExit, KProcess::Stdout );
}

void Prefs::aumixExited(KProcess *proc)
{ 
	if (proc->normalExit() == true) {
		kdDebug() << "Audiodevs loaded" << endl;
	}  else  {
		kdWarning() << "aumix exited with status" << proc->exitStatus() << endl;
		kdWarning() << "aumix exited abnormal" << endl;
	}
}


/*****************************************************************
 * HWProfiles
 *****************************************************************/

void Prefs::loadHWProfileChooser()
{
	m_HWProfileChooser->clear();
	QStringList profiles = m_hwprofile->readDir();
	m_HWProfileChooser->insertStringList( profiles, -1);
	kdDebug() << "Hardware profiles loaded" << endl;

	QString profile = Settings::hwprofile();
	if (! ( profile.isEmpty() ) ) {
		slotSetHWProfile( profile );
		return;
	}

	QString filename = kcfg_hwprofile->text();
	QString basename = filename;
	kdDebug() << "profile = " << basename << endl;
	if (! basename.isEmpty())  {
		basename.remove(QRegExp("^.*/"));
		QListBoxItem* i = m_HWProfileChooser->findItem( basename );
		kdDebug() << "in loadHWProfileChooser " << endl;
		kdDebug() << "item = " << i << endl;
		m_HWProfileChooser->setCurrentItem((QListBoxItem*)i);
	}
}

void Prefs::slotSetHWProfile(const QString & profile)
{
	if ( profile.isEmpty() )  {
		kcfg_hwprofile->clear();
		m_hwprofilefield->clear();
		return;
	}
	if ( ! ( m_hwprofile->read( profile ) ) ) {
		return;
	}
	kcfg_hwprofile->setText( m_hwprofile->getFilename() );
	m_hwprofilefield->setText( profile );

//   QListBoxItem* i = m_HWProfileChooser->findItem( profile );
	QListBoxItem* i = m_HWProfileChooser->findItem( profile );
	kdDebug() << "in slotSetHWProfile " << endl;
	kdDebug() << "profile = " << profile << endl;
	kdDebug() << "item = " << i << endl;
//   m_QProfileChooser->setCurrentItem((QListBoxItem*)i);

	QString val;
	int valInt;
	double valDouble;
//	float valFloat;
	bool valBoolean;

	val = m_hwprofile->getValueString( "comment" );
	val.replace("\\n", "\n");
	kcfg_hwprofile_comment->setText( val );

        val = m_hwprofile->getValueString( "driver" );
	kcfg_driver->setText( val );
	m_driver->setCurrentItem( val );

	val = m_hwprofile->getValueString( "norm" );
	kcfg_norm->setText( val );
	m_norm->setCurrentItem( val );

	val = m_hwprofile->getValueString( "videodev" );
	kcfg_videodev->setText( val );
	m_videodev->setCurrentItem( val );

//!!!!!!!!!!!!
	val = m_hwprofile->getValueString( "vbidev" );
	kcfg_vbidev->setText( val );
	m_vbidev->setCurrentItem( val );
	kdDebug() << "vbidev = " << val << endl;

	valInt = m_hwprofile->getValueInt( "input" );
	kcfg_input->setValue( valInt );

	val = m_hwprofile->getValueString( "freqtable" );
	kcfg_freq_table->setText( val );
	m_freq_table->setCurrentItem( val );

	valBoolean = m_hwprofile->getValueBoolean( "usefrq" );
	kcfg_use_frq->setChecked( valBoolean );

//!!!!!!!!!!!!
	val = m_hwprofile->getValueString( "audiodev" );
	kcfg_audiodev->setText( val );
	m_audiodev->setCurrentItem( val );
	kdDebug() << "audiodev = " << val << endl;

	valInt = m_hwprofile->getValueInt( "audiodev_volume" );
	kcfg_audiodev_volume->setValue( valInt );

	valInt = m_hwprofile->getValueInt( "igain_volume" );
	kcfg_igain_volume->setValue( valInt );

	valInt = m_hwprofile->getValueInt( "brightness" );
	kcfg_brightness->setValue( valInt );

	valInt = m_hwprofile->getValueInt( "hue" );
	kcfg_hue->setValue( valInt );

	valInt = m_hwprofile->getValueInt( "saturation" );
	kcfg_saturation->setValue( valInt );

	valInt = m_hwprofile->getValueInt( "contrast" );
	kcfg_contrast->setValue( valInt );

	valDouble = m_hwprofile->getValueDouble( "factor" );
	kcfg_overscan->setValue( valDouble );

	valBoolean = m_hwprofile->getValueBoolean( "usekeyint" );
	kcfg_use_keyint->setChecked( valBoolean );
	kdDebug() << "usekeyint = " << valBoolean << endl;

	valInt = m_hwprofile->getValueInt( "keyint" );
	kcfg_keyint->setValue( valInt );

	valInt = m_hwprofile->getValueInt( "MaxBitrate" );
	kcfg_MaxBitrate->setValue( valInt );

	valBoolean = m_hwprofile->getValueBoolean( "testBitrate" );
	kcfg_testBitrate->setChecked( valBoolean );

	valBoolean = m_hwprofile->getValueBoolean( "BitrateWarnOnly" );
	kcfg_bitrateWarnOnly->setChecked( valBoolean );

	valBoolean = m_hwprofile->getValueBoolean( "convert_mpg2_to_divx" );
	kcfg_convert_mpg2_to_divx->setChecked( valBoolean );

	return;
}

void Prefs::slotUpdHWProfile(const QString & profile)
{
   if ( profile.isEmpty() )  {
      m_hwprofilefield->clear();
      kcfg_hwprofile->clear();
      return;
   }
   QString myProfile = profile;
   myProfile.remove( m_hwprofiles_dir );
   myProfile.remove( "/" );
   QListBoxItem* i = m_HWProfileChooser->findItem( myProfile );
   //kdDebug() << "in slotUpdHWProfile " << endl;
   //kdDebug() << "profile = " << myProfile << endl;
   //kdDebug() << "item = " << i << endl;
   m_HWProfileChooser->setCurrentItem((QListBoxItem*)i);
}

void Prefs::slotLoadHWProfileChooser( const QString &path )
{
   kdDebug() << i18n("Content of %1 has changed").arg(path) << endl;
   loadHWProfileChooser();
}

void Prefs::slotSaveHWProfile()
{
    QString basename = m_hwprofilefield->text();
    QString filename = basename;
    filename.prepend( m_hwprofiles_dir );
    kdDebug() << "try to write hardware profile as " << filename << endl;
    QFile file( filename );
    if (file.open(IO_WriteOnly) == false)
    {
        kdDebug() << i18n("could not open hardware profile %1 for writing")
                          .arg( file.name() ) << endl;
        return;
    }
   QString profile = "[hwprofile]\n";
   QString comment = kcfg_hwprofile_comment->text();
   comment.replace ("\n", "\\n");
   profile.append( QString("comment=%1\n")
                          .arg( comment ) );
   profile.append( "[video]\n" );
   profile.append( QString("driver=%1\n").arg(     kcfg_driver->text()      ) );
   profile.append( QString("norm=%1\n").arg(       kcfg_norm->text()        ) );
   profile.append( QString("videodev=%1\n").arg(   kcfg_videodev->text()    ) );
   profile.append( QString("vbidev=%1\n").arg(     kcfg_vbidev->text()      ) );
   profile.append( QString("input=%1\n").arg(      kcfg_input->value()      ) );
   profile.append( QString("freqtable=%1\n").arg(  kcfg_freq_table->text()  ) );
   if (kcfg_use_frq->isChecked() ) {
      profile.append("usefrq=true\n");
   }  else  {
      profile.append("usefrq=false\n");
   }
   profile.append( "[audio]\n" );
   profile.append( QString("audiodev=%1\n").arg(   kcfg_audiodev->text()    ) );
   profile.append( QString("audiodev_volume=%1\n")
                          .arg(      kcfg_audiodev_volume->value()));
   profile.append( QString("igain_volume=%1\n")
                          .arg( kcfg_igain_volume->value() ) );
   profile.append( "[image equalizer]\n" );
   profile.append( QString("brightness=%1\n").arg( kcfg_brightness->value() ) );
   profile.append( QString("hue=%1\n").arg(        kcfg_hue->value()        ) );
   profile.append( QString("saturation=%1\n").arg( kcfg_saturation->value() ) );
   profile.append( QString("contrast=%1\n").arg(   kcfg_contrast->value()   ) );
   profile.append( "[overscan]\n" );
   profile.append( QString("factor=%1\n").arg( kcfg_overscan->value() ) );
   profile.append( "[others]\n" );
   if ( kcfg_use_keyint->isChecked() ) {
      profile.append("usekeyint=true\n");
   }  else  {
      profile.append("usekeyint=false\n");
   }
   profile.append( QString("keyint=%1\n")
                          .arg(   kcfg_keyint->value() ) );

   profile.append( QString("MaxBitrate=%1\n")
                          .arg(   kcfg_MaxBitrate->value() ) );
   if ( kcfg_testBitrate->isChecked() ) {
      profile.append("testBitrate=true\n");
   }  else  {
      profile.append("testBitrate=false\n");
   }
   if ( kcfg_testBitrate->isChecked() ) {
      profile.append("BitrateWarnOnly=true\n");
   }  else  {
      profile.append("BitrateWarnOnly=false\n");
   }
   if ( kcfg_convert_mpg2_to_divx->isChecked() ) {
      profile.append("convert_mpg2_to_divx=true\n");
   }  else  {
      profile.append("convert_mpg2_to_divx=false\n");
   }
   QTextStream profileForFile(&file);
   profileForFile << profile;
   file.close();
   kcfg_hwprofile->setText (filename);
}

void Prefs::slotDeleteHWProfile()
{
    QString filename(kcfg_hwprofile->text());
    QFile file(filename);
    QString msg = i18n("This can not be undone.\n"
                       "Do You realy want to delete the hardware profile %1?" 
                      ).arg(filename);
#ifdef KDE_3_3_FEATURES
    switch( KMessageBox::warningYesNo( this, msg, QString::null,
                           KStdGuiItem::del(), KStdGuiItem::discard() ) )
#else
    switch( KMessageBox::warningYesNo( this, msg, QString::null,
                           KStdGuiItem::yes(), KStdGuiItem::discard() ) )
#endif
    {
      case KMessageBox::Yes:
      {
         kdDebug() << "deleting " << filename << endl;
         KConfigGroup knsConfig(KGlobal::config(), "KNewStuffStatus");
         QString profile = filename.section("/",-1);
         kdDebug() << "deleting " << profile << " from config" << endl;
	 knsConfig.deleteEntry( profile );
         KGlobal::config()->sync();
         file.remove();
         slotUpdHWProfile( QString::null );
	 return;
      }
      case KMessageBox::No: // Don't save and don't close.
	return;
    }
}

void Prefs::slotDownloadHWProfile()
{
#ifdef KDE_3_3_FEATURES
   if ( !m_newHWProfiles )
        m_newHWProfiles = new KalvaNewStuff(
              "kalva//hwprofile",
              "http://download.kde.org/khotnewstuff/kalva-hwprofile-providers.xml",
              this );
    m_newHWProfiles->download();
#else
   KMessageBox::detailedSorry   (
      this,
      i18n("Your KDE is too old for this functionality."), 
      i18n("Kalva has been compiled without KNewStuff. You should consider to update your KDE to at least 3.3 and recompile Kalva."), 
          i18n("Functionality not provided")
       );

#endif
}

void Prefs::slotUploadHWProfile()
{
//    if ( !m_newHWProfiles )
//        m_newHWProfiles = new KalvaNewStuff(
//            "kalva//hwprofile",
//            "http://download.kde.org/khotnewstuff/kalva-hwprofile-providers.xml",
//            this );
//     QString chlst = kcfg_channellist->text();
//     m_newHWProfiles->upload( chlst, chlst );
    int ret = KMessageBox::warningContinueCancel (
       this,
       i18n(
"Upload can only be done via the web interface on www.kde-files.org.\nShall I open this site in konqueror?"), 
          i18n("Open www.kde-files.org in konq?")
       );
    if ( ret == KMessageBox::Continue ) {
       KURL url("http://www.kde-files.org/index.php?xcontentmode=657");
       KRun::runCommand("kfmclient openURL \""+url.prettyURL()+"\"", "kfmclient", "konqueror");
    }
}


/*****************************************************************
 * QProfiles
 *****************************************************************/

void Prefs::loadQProfileChooser()
{
	m_QProfileChooser->clear();
	QStringList profiles = m_qprofile->readDir();
	m_QProfileChooser->insertStringList( profiles, -1 );
	kdDebug() << "Quality profiles loaded" << endl;
	QString filename = kcfg_qprofile->text();
	QString basename = filename;
	kdDebug() << "profile = " << basename << endl;
	if (! basename.isEmpty())  {
		basename.remove(QRegExp("^.*/"));
		QListBoxItem* i = m_QProfileChooser->findItem( basename );
		kdDebug() << "in loadQProfileChooser " << endl;
		kdDebug() << "item = " << i << endl;
		m_QProfileChooser->setCurrentItem((QListBoxItem*)i);
	}
}

void Prefs::slotSetQProfile(const QString & profile)
{
	if ( profile.isEmpty() )  {
		kcfg_qprofile->clear();
		m_qprofilefield->clear();
		return;
	}

	if ( ! ( m_qprofile->read( profile ) ) ) {
		return;
	}
	kcfg_qprofile->setText( m_qprofile->getFilename() );
	m_qprofilefield->clear();
	m_qprofilefield->setText( profile );

	QString val;
	int valInt;
//	double valDouble;
//	float valFloat;
	bool valBoolean;

	val = m_qprofile->getValueString( "comment" );
	val.replace("\\n", "\n");
	kcfg_qprofile_comment->setText( val );

	val = m_qprofile->getValueString( "tvscale" );
	kcfg_tv_scale->setText( val );
	m_TvScale->setCurrentItem( val );

	val = m_qprofile->getValueString( "targetedAspect" );
	kcfg_targeted_aspect->setText( val );
	m_targetedAspect->setCurrentItem( val );

	val = m_qprofile->getValueString( "filterscale" );
	kcfg_filter_scale->setText( val );
	m_FilterScale->setCurrentItem( val );

	val = m_qprofile->getValueString( "denoiser" );
	kcfg_denoiser->setText( val );
	m_denoiser->setCurrentItem( val );

	valInt = m_qprofile->getValueInt( "chroma" );
	kcfg_denoise3d_chroma->setValue( valInt );

	valInt = m_qprofile->getValueInt( "luma" );
	kcfg_denoise3d_luma->setValue( valInt );

	valInt = m_qprofile->getValueInt( "time" );
	kcfg_denoise3d_time->setValue( valInt );

	valInt = m_qprofile->getValueInt( "precmp" );
	kcfg_precmp->setValue( valInt );

	valInt = m_qprofile->getValueInt( "cmp" );
	kcfg_cmp->setValue( valInt );

	valInt = m_qprofile->getValueInt( "subcmp" );
	kcfg_subcmp->setValue( valInt );

	val = m_qprofile->getValueString( "postcodingpars" );
	kcfg_postcodingpars->setText( val );

	val = m_qprofile->getValueString( "postlavcopts" );
	kcfg_postlavcopts->setText( val );

	val = m_qprofile->getValueString( "pp" );
	kcfg_pp->setText( val );

	val = m_qprofile->getValueString( "prefilter" );
	kcfg_prefilter->setText( val );

	val = m_qprofile->getValueString( "postfilter" );
	kcfg_postfilter->setText( val );

	valInt = m_qprofile->getValueInt( "vratetol" );
	kcfg_vratetol->setValue( valInt );

	valInt = m_qprofile->getValueInt( "bitrate" );
	kcfg_Bitrate->setValue( valInt );

	valInt = m_qprofile->getValueInt( "mbd" );
	kcfg_mbd->setValue( valInt );

	valBoolean = m_qprofile->getValueBoolean( "grey" );
	kcfg_grey->setChecked(valBoolean);

	return;
}

void Prefs::slotUpdQProfile(const QString & profile)
{
   if ( profile.isEmpty() )  {
      m_qprofilefield->clear();
      kcfg_qprofile->clear();
      return;
   }
   QString myProfile = profile;
   myProfile.remove( m_qprofiles_dir );
   myProfile.remove( "/" );
   QListBoxItem* i = m_QProfileChooser->findItem( myProfile );
   //kdDebug() << "in slotUpdQProfile " << endl;
   //kdDebug() << "profile = " << myProfile << endl;
   //kdDebug() << "item = " << i << endl;
   m_QProfileChooser->setCurrentItem((QListBoxItem*)i);
}

void Prefs::slotLoadQProfileChooser( const QString &path )
{
   kdDebug() << i18n("Content of %1 has changed").arg(path) << endl;
   loadQProfileChooser();
}

void Prefs::slotSaveQProfile()
{
    QString basename = m_qprofilefield->text();
    QString filename = basename;
    filename.prepend( m_qprofiles_dir );
    kdDebug() << "try to write quality profile as " << filename << endl;
    QFile file( filename );
    if (file.open(IO_WriteOnly) == false)
    {
        kdDebug() << i18n("could not open quality profile %1 for writing")
                          .arg( file.name() ) << endl;
        return;
    }
   QString profile = "[qprofile]\n";
   QString comment = kcfg_qprofile_comment->text();
   comment.replace ("\n", "\\n");
   profile.append( QString("comment=%1\n")
                          .arg( comment ) );
   profile.append( "[scale]\n" );
   profile.append( QString("tvscale=%1\n")
                          .arg( kcfg_tv_scale->text() ) );
   profile.append( QString("targetedAspect=%1\n")
                          .arg( kcfg_targeted_aspect->text() ) );
   profile.append( QString("filterscale=%1\n")
                          .arg( kcfg_filter_scale->text() ) );
   profile.append( "[denoise]\n" );
   profile.append( QString("denoiser=%1\n")
                          .arg( kcfg_denoiser->text() ) );
   profile.append( QString("chroma=%1\n").arg(
      kcfg_denoise3d_chroma->value() ) );
   profile.append( QString("luma=%1\n")
                          .arg( kcfg_denoise3d_luma->value() ) );
   profile.append( QString("time=%1\n")
                          .arg( kcfg_denoise3d_time->value() ) );
   profile.append( "[comparison]\n" );
   profile.append( QString("precmp=%1\n")
                          .arg( kcfg_precmp->value() ) );
   profile.append( QString("cmp=%1\n")
                          .arg( kcfg_cmp->value() ) );
   profile.append( QString("subcmp=%1\n")
                          .arg( kcfg_subcmp->value() ) );
   profile.append( "[expert]\n" );
   profile.append( QString("postcodingpars=%1\n")
                          .arg( kcfg_postcodingpars->text() ) );
   profile.append( QString("postlavcopts=%1\n")
                          .arg( kcfg_postlavcopts->text() ) );
   profile.append( QString("pp=%1\n")
                          .arg( kcfg_pp->text() ) );
   profile.append( QString("prefilter=%1\n")
                          .arg(    kcfg_prefilter->text() ) );
   profile.append( QString("postfilter=%1\n")
                          .arg( kcfg_postfilter->text() ) );
   profile.append( "[other]\n" );
   profile.append( QString("vratetol=%1\n")
                          .arg( kcfg_vratetol->value() ) );
   profile.append( QString("bitrate=%1\n")
                          .arg( kcfg_Bitrate->value() ) );
   profile.append( QString("mbd=%1\n")
                          .arg( kcfg_mbd->value() ) );
   profile.append( "[specialfx]\n" );
   if ( kcfg_grey->isChecked() ) {
      profile.append("grey=true\n");
   }  else  {
      profile.append("grey=false\n");
   }
   QTextStream profileForFile(&file);
   profileForFile << profile;
   file.close();
   kcfg_qprofile->setText (filename);
}

void Prefs::slotDeleteQProfile()
{
    QString filename(kcfg_qprofile->text());
    QFile file(filename);
    QString msg = i18n("This can not be undone.\n"
                       "Do You realy want to delete the quality profile %1?" 
                      ).arg(filename);
#ifdef KDE_3_3_FEATURES
    switch( KMessageBox::warningYesNo( this, msg, QString::null,
                           KStdGuiItem::del(), KStdGuiItem::discard() ) )
#else
    switch( KMessageBox::warningYesNo( this, msg, QString::null,
                           KStdGuiItem::yes(), KStdGuiItem::discard() ) )
#endif
    {
      case KMessageBox::Yes:
      {
         kdDebug() << "deleting " << filename << endl;
         KConfigGroup knsConfig(KGlobal::config(), "KNewStuffStatus");
         QString profile = filename.section("/",-1);
         kdDebug() << "deleting " << profile << " from config" << endl;
	 knsConfig.deleteEntry( profile );
         KGlobal::config()->sync();
         file.remove();
         slotUpdQProfile( QString::null );
	 return;
      }
      case KMessageBox::No: // Don't save and don't close.
	return;
    }
}

void Prefs::slotDownloadQProfile()
{
#ifdef KDE_3_3_FEATURES
   if ( !m_newQProfiles )
        m_newQProfiles = new KalvaNewStuff(
            "kalva//qprofile",
            "http://download.kde.org/khotnewstuff/kalva-qprofile-providers.xml",
            this );
    m_newQProfiles->download();
#else
   KMessageBox::detailedSorry   (
      this,
      i18n("Your KDE is too old for this functionality."), 
      i18n("Kalva has been compiled without KNewStuff. You should consider to update your KDE to at least 3.3 and recompile Kalva."), 
          i18n("Functionality not provided")
       );

#endif
}

void Prefs::slotUploadQProfile()
{
//    if ( !m_newStuff )
//         m_newStuff = new KalvaNewStuff(
//            "kalva//qprofile",
//            "http://download.kde.org/khotnewstuff/kalva-qprofile-providers.xml",
//            this );
//     QString chlst = kcfg_channellist->text();
//     m_newStuff->upload( chlst, chlst );
    int ret = KMessageBox::warningContinueCancel (
       this,
       i18n(
"Upload can only be done via the web interface on www.kde-files.org.\nShall I open this site in konqueror?"), 
          i18n("Open www.kde-files.org in konq?")
       );
    if ( ret == KMessageBox::Continue ) {
       KURL url("http://www.kde-files.org/index.php?xcontentmode=656");
       KRun::runCommand("kfmclient openURL \""+url.prettyURL()+"\"", "kfmclient", "konqueror");
    }
}


/*****************************************************************
 * Channellists
 *****************************************************************/

void Prefs::loadChlstChooser()
{
	m_chlstChooser->clear();
	QStringList profiles = m_chlst->readDir();
	m_chlstChooser->insertStringList( profiles ,-1);
	kdDebug() << "Channelllists loaded" << endl;
	QString filename = kcfg_channellist->text();
	QString basename = filename;
	kdDebug() << "profile = " << basename << endl;
	if (! basename.isEmpty())  {
		basename.remove(QRegExp("^.*/"));
		QListBoxItem* i = m_chlstChooser->findItem( basename );
		kdDebug() << "in loadChlstChooser " << endl;
		kdDebug() << "item = " << i << endl;
		m_chlstChooser->setCurrentItem((QListBoxItem*)i);
	}
}

void Prefs::slotSetChannellist(const QString & chlst)
{
   if ( chlst == kcfg_chlst->text() )
   {
       return;
   }
   kcfg_channellist->clear();
   m_chlstLocation->clear();
   if ( chlst.isEmpty() )  {
      return;
   }
   QString chlstWithPath = QString("%1/%2").arg(m_chlsts_dir).arg(chlst);
   kcfg_channellist->setText(chlstWithPath);
   m_chlstLocation->setText(chlst.section(".",0,0));
   m_chlstTvType->setCurrentItem(chlst.section(".",1,1));
}

void Prefs::slotOnLocationChanged(const QString &location)
{
   if ( location == m_chlstLocation->text() )
   {
       return;
   }
   QString chlst = QString("%1.%2")
                           .arg( location )
                           .arg(m_chlstTvType->currentText());
   kcfg_chlst->clear();
   kcfg_channellist->clear();
   kcfg_chlst->setText(chlst);

   kdDebug() << "slotSetChlst(): set kcfg_hannelllist" << endl;
   kcfg_channellist->setText(QString("%1/%2").arg(m_chlsts_dir).arg(chlst));
}

void Prefs::slotOnTvTypeChanged(const QString &tvtype)
{
   if ( tvtype == m_chlstTvType->currentText() )
   {
       return;
   }
   QString chlst = QString("%1.%2")
                           .arg( m_chlstLocation->text() )
                           .arg( tvtype );
   kcfg_chlst->clear();
   kcfg_channellist->clear();
   kcfg_chlst->setText(chlst);

   kdDebug() << "slotSetChlst(): set kcfg_hannelllist" << endl;
   kcfg_channellist->setText(QString("%1/%2").arg(m_chlsts_dir).arg(chlst));
}

void Prefs::slotUpdChlst(const QString & chlst)
{
   kcfg_chlst->clear();
   m_chlstLocation->clear();
   if ( chlst.isEmpty() )  {
      kcfg_channellist->clear();
      return;
   }
   //kdDebug() << "slotUpdChlst(): kcfg_channellist->text() = " << kcfg_channellist->text() << endl;
   //kdDebug() << "slotUpdChlst(): chlst = " << chlst << endl;
   QString myProfile = chlst;
   myProfile.remove( m_chlsts_dir );
   myProfile.remove( "/" );
   kdDebug() << "slotUpdChlst(): set m_chstLocation and m_chlstTvType" << endl;
   m_chlstLocation->setText(myProfile.section(".",0,0));
   m_chlstTvType->setCurrentItem(myProfile.section(".",1,1));
   QListBoxItem* i = m_chlstChooser->findItem( myProfile );
   //kdDebug() << "in slotUpdChlst " << endl;
   //kdDebug() << "profile = " << myProfile << endl;
   //kdDebug() << "item = " << i << endl;
   m_chlstChooser->setCurrentItem((QListBoxItem*)i);
   slotLoadChlst(chlst);
}

void Prefs::slotSetChlstChanged()
{
    kcfg_chlst_changed->setChecked(true);
}

void Prefs::slotLoadChlstChooser( const QString &path )
{
   kdDebug() << i18n("Content of %1 has changed").arg(path) << endl;
   loadChlstChooser();
}

void Prefs::slotDeleteChlst()
{
    QString filename(kcfg_channellist->text());
    QFile file(filename);
    QString msg = i18n("This can not be undone.\n"
                       "Do You realy want to delete the channellist %1?"
                       ).arg(filename);
#ifdef KDE_3_3_FEATURES
    switch( KMessageBox::warningYesNo( this, msg, QString::null,
                           KStdGuiItem::del(), KStdGuiItem::discard() ) )
#else
    switch( KMessageBox::warningYesNo( this, msg, QString::null,
                           KStdGuiItem::yes(), KStdGuiItem::discard() ) )
#endif
    {
      case KMessageBox::Yes:
      {
         KConfigGroup knsConfig(KGlobal::config(), "KNewStuffStatus");
         QString profile = filename.section("/",-1);
         kdDebug() << "deleting " << profile << " from config" << endl;
	 knsConfig.deleteEntry( profile );
         KGlobal::config()->sync();
         kdDebug() << "deleting " << filename << endl;
         file.remove();
         slotUpdChlst ( QString::null );
	 return;
      }
      case KMessageBox::No: // Don't save and don't close.
	return;
    }
}

void Prefs::slotDownloadChlst()
{
#ifdef KDE_3_3_FEATURES
   if ( !m_newChlsts )
        m_newChlsts = new KalvaNewStuff(
            "kalva//chlst",
            "http://download.kde.org/khotnewstuff/kalva-providers.xml",
            this );
    m_newChlsts->download();
#else
   KMessageBox::detailedSorry   (
      this,
      i18n("Your KDE is too old for this functionality."), 
      i18n("Kalva has been compiled without KNewStuff. You should consider to update your KDE to at least 3.3 and recompile Kalva."), 
          i18n("Functionality not provided")
       );

#endif
}

void Prefs::slotUploadChlst()
{
    int ret = KMessageBox::warningContinueCancel (
       this,
       i18n(
"Upload can only be done via the web interface on www.kde-files.org.\nShall I open this site in konqueror?"), 
          i18n("Open www.kde-files.org in konq?")
       );
    if ( ret == KMessageBox::Continue ) {
       KURL url("http://www.kde-files.org/index.php?xcontentmode=655");
       KRun::runCommand("kfmclient openURL \""+url.prettyURL()+"\"", "kfmclient", "konqueror");
    }
}

void Prefs::slotLoadChlst(const QString & _chlst)
{
    QFile file( _chlst );
    if (file.open(IO_ReadOnly) == false)
    {
        kdDebug() << "could not open file " << file.name() << "for reading" << endl;
        return;
    }
    QTextStream chlstFromFile(&file);
    QStringList chlst = QStringList::split("\n",chlstFromFile.read(),false);
    file.close();

    QString str;
    signed int row    = -1;
    channellist->setCurrentCell(0,0);
    channellist->setNumRows(0);
    QStringList Channellist = chlst;
    KConfigGroup kalvaConfig(KGlobal::config(), "Kalva");
    QString lastStation = kalvaConfig.readEntry("lastStation");

    for ( QStringList::Iterator it = Channellist.begin();
          it != Channellist.end();
          ++it
        ) {
        str = *it;
        if (str.contains("[", false))  {
           str = str.remove("[");
           str = str.remove("]");
           row++;
           channellist->insertRows(row, 1);
           channellist->setText(row,0,str);
           if ( str == lastStation )  {
              channellist->clearSelection( );
              channellist->selectRow( row );
           }
        }
        if (str.contains("channel=", false))  {
           str = str.remove("channel=");
           channellist->setText(row,1,str);
        }
        if (str.contains("freq=", false))  {
           str = str.remove("freq=");
           channellist->setText(row,2,str);
        }
    }
    kcfg_chlst_changed->setChecked(false);
}

void Prefs::slotSaveChlst()
{
    QString filename = kcfg_channellist->text();
    //QString basename = filename;
    //basename.remove(QRegExp("^.*/"));
    QFile file(filename);
    if (file.open(IO_WriteOnly) == false)
    {
        kdDebug() << "could not open file " << file.name() << "for writing" << endl;
        return;
    }

    QString str             = "";
    QStringList Channellist = "";

    for ( int row = 0; row < channellist->numRows(); row++ ) {
        str = channellist->text(row, 0);
        Channellist.append(QString("[%1]").arg(str));
        str = channellist->text(row, 1);
        if (!(str.isEmpty()))  {
           Channellist.append(QString("channel=%1").arg(str));
        }
        str = channellist->text(row, 2);
        if (!(str.isEmpty()))  {
           Channellist.append(QString("freq=%1").arg(str));
        }
    }

    QString chlst = Channellist.join("\n");
    QTextStream chlstForFile(&file);
    chlstForFile << chlst;
    file.close();
}
