/***************************************************************************
                           settingsdialog.cpp
                           ------------------
    begin                : Sun Sep 13 2003
    copyright            : (C) 2003 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 <kiconloader.h>
#include <klocale.h>
#include <qlayout.h>
#include <q3grid.h>
//Added by qt3to4:
#include <Q3GridLayout>
#include <QList>

#include "settingsdialog.h"
#include "settingsdialogpage.h"
#include "kdetv.h"
#include "cfgdata.h"

#include "channelwidgetimpl.h"
#include "generalwidgetimpl.h"
#include "pluginwidgetimpl.h"
#include "soundwidgetimpl.h"
#include "videowidgetimpl.h"
#include "filterwidgetimpl.h"

SettingsDialog::SettingsDialog(QWidget *parent, char *name, bool modal,
                               Kdetv *ktv, QList<SettingsDialogPage*>* externalPages, Qt::WFlags fl)
    : KPageDialog(parent),
      _ktv(ktv),
      _externalPageCount(0)
{
    kDebug() << "SettingsDialog: constructor";

    setFaceType(List);
    setModal(modal);
    setObjectName(name);
    setCaption(i18n("Settings"));
    setButtons(KDialog::Default | KDialog::Apply | KDialog::Ok | KDialog::Cancel);
    setModal(modal);
    setDefaultButton(KDialog::Ok);
    showButtonSeparator(true);
    setWindowFlags(fl);

    // Kdetv backend pages
    addDialogPage(static_cast<SettingsDialogPage*>(new GeneralWidgetImpl(0L, _ktv, _ktv->config())));
    addDialogPage(static_cast<SettingsDialogPage*>(new VideoWidgetImpl  (0L, _ktv, _ktv->config())));
    addDialogPage(static_cast<SettingsDialogPage*>(new SoundWidgetImpl  (0L, _ktv, _ktv->config())));
    addDialogPage(static_cast<SettingsDialogPage*>(new ChannelWidgetImpl(0L, _ktv, _ktv->config())));
    addDialogPage(static_cast<SettingsDialogPage*>(new PluginWidgetImpl (0L, _ktv, _ktv->config())));
    addDialogPage(static_cast<SettingsDialogPage*>(new FilterWidgetImpl (0L, _ktv, _ktv->config())));

    // Other pages (client, plugins)
    if (externalPages != 0) {
        for (QList<SettingsDialogPage*>::iterator it = externalPages->begin();
             it != externalPages->end();
             ++it) {
            addDialogPage(*it);
            _externalPageCount++;
        }
    }
    
    setInitialSize(QSize(702, 490));
} // SettingsDialog constructor

SettingsDialog::~SettingsDialog()
{
    kDebug() << "SettingsDialog: destructor";
} // SettingsDialog destructor


/***************************************************************************
 *
 * Private Functions
 *
 ***************************************************************************/

void SettingsDialog::addDialogPage(SettingsDialogPage* page)
{
    QWidget* pageWidget = dynamic_cast<QWidget*>(page);
    if (!pageWidget) {
        kWarning() << "Page does not have QWidget parent - cannot add page: " << page->pageName();
        // and we memleak here... if you see this message, fix it :-)
        return;
    }

    _pages.append(page);

    KPageWidgetItem *p = new KPageWidgetItem( pageWidget, page->pageName() );
    p->setHeader( page->header() );
    p->setIcon( KIcon( page->barIconName().toLocal8Bit() ));
    addPage(p);

    /* Q3Grid* p = addGridPage(1,
                           Qt::Horizontal,
                           page->pageName(),
                           page->header(),
                           BarIcon(page->barIconName().toLocal8Bit(), KIconLoader::SizeMedium));*/
    pageWidget->setParent(dynamic_cast<QWidget *>(p));
    page->setup();
}

/***************************************************************************
 *
 * Protected Slots
 *
 ***************************************************************************/

void SettingsDialog::slotCancel()
{
    for (QList<SettingsDialogPage*>::iterator it = _pages.begin();
         it != _pages.end();
         ++it) {
        (*it)->cancel();
    }

    QDialog::reject();
} // slotCancel

void SettingsDialog::doApply()
{
    /*
     * FIXME: Dirk: The settingsdialog pages are not independent
     *              of each other, so the apply order matters.
     * 
     * 1) Changing device/source after video plugin rescan does not always work
     * 2) Changing device/source before applying channel changes breaks channel file or crashes
     * 3) Rescanning source plugins before applying channel changes may break channel file or crash
     */

    for (int i=0; i<_externalPageCount; i++) {
        _pages.at(i+6)->apply();
    }

    _pages.at(5)->apply(); // Filter
    _pages.at(4)->apply(); // Plugins
    _pages.at(3)->apply(); // Channel
    _pages.at(0)->apply(); // Sound
    _pages.at(2)->apply(); // Video
    _pages.at(1)->apply(); // General

    //    for (QPtrListIterator<SettingsDialogPage>it(_pages);
    //    	 it.current() != 0;
    //    	 ++it) {
    //    	it.current()->apply();
    //    }

    emit optionsModified();
}

void SettingsDialog::slotApply()
{
    doApply();

    for (QList<SettingsDialogPage*>::iterator it = _pages.begin();
        it != _pages.end();
        ++it) {
        (*it)->setup();
    }
} // slotApply

void SettingsDialog::slotDefault()
{
    // hack around bug in KJanusWidget in KDE prior to KDE3.1.2 (returns invalid values)
    // only works if the settings page count remains constant
    // (which is given at the time of this writing) !!!
    // this was the offending code:
    // http://webcvs.kde.org/cgi-bin/cvsweb.cgi/kdelibs/kdeui/kjanuswidget.cpp.diff?r1=1.52.2.2&r2=1.52.2.3&f=h
    /*int i = activePageIndex() % _pages.count();
    _pages.at(i)->defaults();*/
} // slotDefault

void SettingsDialog::slotHelp()
{
    KPageDialog::helpClicked();
} // slotHelp

void SettingsDialog::slotOk()
{
    doApply();
    accept();
    _ktv->config()->save();    
} // slotOk

#include "settingsdialog.moc"
