/***************************************************************************
                          pluginwidgetimpl.cpp  -  description
                             -------------------
    begin                : Sat Jun 8 2002
    copyright            : (C) 2002 by Kevin Hessels <khessels@shaw.ca
                           (C) 2002 George Staikos <staikos@kde.org>
                           (C) 2003 Dirk Ziegelmeier <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 <klocale.h>
#include <kdebug.h>
#include <kconfig.h>
#include <kpushbutton.h>

#include <qlistview.h>

#include "cfgdata.h"
#include "kdetv.h"
#include "kdetvview.h"
#include "pluginfactory.h"
#include "pluginwidgetimpl.h"
#include "osdmanager.h"
#include "miscmanager.h"
#include "vbimanager.h"
#include "kdetvosdplugin.h"
#include "kdetvmiscplugin.h"
#include "kdetvvbiplugin.h"
#include "pluginconfigwidget.h"


class PluginListItem : public QCheckListItem
{
public:
    PluginListItem(QListView*, PluginDesc*);
    virtual ~PluginListItem();

    PluginDesc *pd;
};

PluginListItem::PluginListItem(QListView *parent, PluginDesc *d)
    :QCheckListItem(parent, d->name, QCheckListItem::CheckBox)
{
    setText(1, d->comment);
    setText(2, d->author);
    pd = d;
    setOn(pd->enabled);
}

PluginListItem::~PluginListItem()
{
}


/***************************************************************************/


PluginWidgetImpl::PluginWidgetImpl(QWidget* parent, Kdetv* ktv, ConfigData* cfg)
    : PluginWidget(parent),
      SettingsDialogPage(i18n("Plugins"),
                         i18n("Configure Plugins"),
                         "energy"),
      _ktv(ktv),
      _cfg(cfg)
{
    connect(_miscListView, SIGNAL(selectionChanged()),
            this, SLOT(miscSelectionChanged()));
    connect(_miscListView, SIGNAL(doubleClicked(QListViewItem *)),
            this, SLOT(configureMiscPlugin()));
    connect(_configureMisc, SIGNAL(clicked()),
            this, SLOT(configureMiscPlugin()));

    connect(_configureVbi, SIGNAL(clicked()),
            this, SLOT(configureVbiPlugin()));
    connect(_vbiListView, SIGNAL(doubleClicked(QListViewItem*)),
            this, SLOT(configureVbiPlugin()));
    connect(_vbiListView, SIGNAL(selectionChanged()),
            this, SLOT(vbiSelectionChanged()));
} // PluginWidgetImpl constructor


PluginWidgetImpl::~PluginWidgetImpl()
{
} // PluginWidgetImpl destructor


void PluginWidgetImpl::setup()
{
    _miscListView->clear();
    for (PluginDesc *plug = _ktv->pluginFactory()->osdPlugins().first();
         plug;
         plug = _ktv->pluginFactory()->osdPlugins().next()) {
        new PluginListItem(_miscListView, plug);
    } // for
    for (PluginDesc *plug = _ktv->pluginFactory()->miscPlugins().first();
         plug;
         plug = _ktv->pluginFactory()->miscPlugins().next()) {
        new PluginListItem(_miscListView, plug);
    } // for
    miscSelectionChanged();

    _vbiListView->clear();
    for (PluginDesc *p = _ktv->pluginFactory()->vbiPlugins().first();
         p;
         p = _ktv->pluginFactory()->vbiPlugins().next()) {
        new PluginListItem(_vbiListView, p);
    }
    vbiSelectionChanged();
}

void PluginWidgetImpl::apply()
{
    _cfg->pluginConfigHandle()->setGroup("Misc Plugins");

    bool rescanNecessary = false;
    QListViewItemIterator it(_miscListView);
    for ( ; it.current(); ++it) {
        PluginListItem *item = static_cast<PluginListItem *>(it.current());
        if (item->pd->enabled != item->isOn()) {
            rescanNecessary = true;
        }
        item->pd->enabled = item->isOn();
        _cfg->pluginConfigHandle()->writeEntry(item->pd->name+"-"+item->pd->author, item->pd->enabled);
    } // for

    if (rescanNecessary) {
        _ktv->miscManager()->scanPlugins();
        _ktv->osdManager()->scanPlugins();
    }

    rescanNecessary = false;
    _cfg->pluginConfigHandle()->setGroup("VBI Plugins");
    for (QListViewItemIterator it(_vbiListView);
         it.current();
         it++) {
        PluginListItem* item = static_cast<PluginListItem*>(it.current());
        if (item->pd->enabled != item->isOn()) {
            rescanNecessary = true;
        }
        item->pd->enabled = item->isOn();
        _cfg->pluginConfigHandle()->writeEntry(item->pd->name + "-" + item->pd->author, item->pd->enabled);
    }

    if (rescanNecessary) {
        _ktv->vbiManager()->scanPlugins();
    }
} // applyPlugins

void PluginWidgetImpl::defaults()
{
}

/***************************************************************************
 *
 * Private slots
 *
 ***************************************************************************/


void PluginWidgetImpl::configureMiscPlugin()
{
    PluginListItem *pli = static_cast<PluginListItem*>(_miscListView->selectedItem());
    if (!pli || !pli->pd->configurable)
        return;
    PluginDesc* pd = pli->pd;

    KdetvPluginBase* p;
    bool previousState = pd->enabled;
    pd->enabled        = true;
    if (pd->type == PluginDesc::MISC) {
        p = static_cast<KdetvPluginBase*>(_ktv->pluginFactory()->getMiscPlugin(pd, _ktv->screen()));
    } else {
        p = static_cast<KdetvPluginBase*>(_ktv->pluginFactory()->getOSDPlugin(pd, _ktv->screen()));
    }
    pd->enabled        = previousState;

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

    p->destroy();
} // slotConfigurePlugin

void PluginWidgetImpl::configureVbiPlugin()
{
    PluginListItem* i = static_cast<PluginListItem*>(_vbiListView->selectedItem());
    if (!i) return;
    PluginDesc* pd         = i->pd;
    if (!pd->configurable) return;

    bool previousState = pd->enabled;
    pd->enabled        = true;
    KdetvPluginBase* p = _ktv->pluginFactory()->getVbiPlugin(pd, this);
    pd->enabled        = previousState;

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

    p->destroy();
}

void PluginWidgetImpl::miscSelectionChanged()
{
    PluginListItem *item = static_cast<PluginListItem *>(_miscListView->selectedItem());
    if ( !item ) {
        _configureMisc->setEnabled( false );
        return;
    }
    _configureMisc->setEnabled(item->pd->configurable);
} // slotListItemClicked

void PluginWidgetImpl::vbiSelectionChanged()
{
    PluginListItem *item = static_cast<PluginListItem *>(_vbiListView->selectedItem());
    if ( !item ) {
        _configureVbi->setEnabled(false);
        return;
    }
    _configureVbi->setEnabled(item->pd->configurable);
}

#include "pluginwidgetimpl.moc"
