/***************************************************************************
                           soundwidgetimpl.cpp
                           -------------------
    begin                : Sun Sep 6 2003
    copyright            : (C) 2003 by Dirk Ziegelmeier
    email                : dziegel@gmx.de
 ***************************************************************************/

/*
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library 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 Steet, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

#include <kdebug.h>
#include <klocale.h>
#include <kconfig.h>

#include <qcombobox.h>
#include <qpushbutton.h>
#include <qlineedit.h>
#include <qspinbox.h>
#include <qcheckbox.h>
#include <qradiobutton.h>

#include "soundwidgetimpl.h"
#include "cfgdata.h"
#include "kdetvmixerplugin.h"
#include "kdetv.h"
#include "audiomanager.h"
#include "volumecontroller.h"
#include "pluginconfigwidget.h"


SoundWidgetImpl::SoundWidgetImpl(QWidget* parent, Kdetv* ktv, ConfigData* cfg)
    : SoundWidget(parent),
      SettingsDialogPage(i18n("Sound"),
                         i18n("Configure Sound Options"),
                         "kcmsound"),
      _ktv(ktv),
      _cfg(cfg)
{
    connect(_mixer, SIGNAL(highlighted(const QString&)),
            this, SLOT(mixerSelectionChanged(const QString&)));
    connect(_configure, SIGNAL(clicked()),
            this, SLOT(configurePlugin()));
}

SoundWidgetImpl::~SoundWidgetImpl()
{
}

void SoundWidgetImpl::setup()
{
    _mixer->clear();
    for (PluginDesc *p = _ktv->pluginFactory()->mixerPlugins().first();
         p;
         p = _ktv->pluginFactory()->mixerPlugins().next()) {
        _mixer->insertItem(p->name);
    }
    for (int i=0; i<_mixer->count(); i++) {
        if (_ktv->audioManager()->plugin()->pluginDescription() == getPluginDesc(_mixer->text(i))) {
            _mixer->setCurrentItem(i);
            break;
        }
    }
    mixerSelectionChanged(_mixer->currentText());

    _volumeIncrement->setValue(_cfg->volumeIncrement);
    _delayOnChange->setValue(_cfg->volumeRestoreDelay);
    _autoMute->setChecked(_cfg->autoMute);

    _soundCardMixer->setChecked(_cfg->volumeControlViaSoundCard);
    _soundCardVolume->setEnabled(!_cfg->volumeControlViaSoundCard);
    _soundCardVolume->setValue(_cfg->mixerVolume);
    _tvCardMixer->setChecked(!_cfg->volumeControlViaSoundCard);
    _tvVolume->setEnabled(_cfg->volumeControlViaSoundCard);
    _tvVolume->setValue(_cfg->tvCardVolume);

    _prevMixer = _mixer->currentText();
}

void SoundWidgetImpl::defaults()
{
    const ConfigData& def = ConfigData::getDefaultConfig();

    _volumeIncrement->setValue(def.volumeIncrement);
    _delayOnChange->setValue(def.volumeRestoreDelay);
    _autoMute->setChecked(def.autoMute);
    _soundCardMixer->setChecked(def.volumeControlViaSoundCard);
    _tvCardMixer->setChecked(!def.volumeControlViaSoundCard);
    _tvVolume->setValue(def.tvCardVolume);
    _soundCardVolume->setValue(def.mixerVolume);
}

void SoundWidgetImpl::mixerSelectionChanged(const QString& mixer)
{
    PluginDesc *p = getPluginDesc(mixer);
    if (!p) return;

    _author->setText(p->author);
    _author->home(false);
    _description->setText(p->comment);
    _description->home(false);
    _configure->setEnabled(p->configurable);
}

PluginDesc* SoundWidgetImpl::getPluginDesc(const QString& mixer)
{
    for (PluginDesc *p = _ktv->pluginFactory()->mixerPlugins().first();
         p;
         p = _ktv->pluginFactory()->mixerPlugins().next())
        {
            if (p->name == mixer) return p;
        }
    return 0L;
}

void SoundWidgetImpl::configurePlugin()
{
    PluginDesc*    pd  = getPluginDesc(_mixer->currentText());
    if (!pd || !pd->configurable) return;

    bool previousState  = pd->enabled;
    pd->enabled         = true;
    KdetvMixerPlugin* p = _ktv->pluginFactory()->getMixerPlugin(pd);
    pd->enabled         = previousState;

    PluginConfigWidget w(0L, "Mixer Plugin Config Dialog", true);
    w.setConfigWidget(pd->name, p->configWidget(&w, "Mixer Configuration Widget"));
    if (w.exec() == QDialog::Accepted) {
        p->saveConfig();
    }

    p->destroy();
}

void SoundWidgetImpl::apply()
{
    _cfg->autoMute                  = _autoMute->isChecked();
    _cfg->volumeRestoreDelay        = _delayOnChange->value();
    _cfg->volumeIncrement           = _volumeIncrement->value();
    _cfg->volumeControlViaSoundCard = _soundCardMixer->isChecked();
    _cfg->tvCardVolume              = _tvVolume->value();
    _cfg->mixerVolume               = _soundCardVolume->value();

    _ktv->volumeController()->setConfig(_cfg->volumeControlViaSoundCard,
                                        _cfg->mixerVolume, _cfg->tvCardVolume);

    _cfg->pluginConfigHandle()->setGroup("Mixer Plugins");
    for (PluginDesc* p = _ktv->pluginFactory()->mixerPlugins().first();
         p;
         p = _ktv->pluginFactory()->mixerPlugins().next())
        {
            if (p->name == _mixer->currentText()) {
                _cfg->pluginConfigHandle()->writeEntry(p->name + "-" + p->author, true);
                p->enabled = true;
            } else {
                _cfg->pluginConfigHandle()->writeEntry(p->name + "-" + p->author, false);
                p->enabled = false;
            }
        }

    if (_prevMixer != _mixer->currentText()) {
        _ktv->audioManager()->rescanPlugins();
    }
}

#include "soundwidgetimpl.moc"
