// -*- c++ -*-
/***************************************************************************
                           channelsuitedialogimpl.cpp
                           --------------------------
    begin                : Sat Apr 10 2004
    copyright            : (C) 2004 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 <qstring.h>
#include <qcombobox.h>
#include <qlineedit.h>
#include <qtextedit.h>
#include <qtabwidget.h>
#include <qlayout.h>
#include <qlistview.h>
#include <qcheckbox.h>
#include <qpushbutton.h>
#include <qbuttongroup.h>
#include <qdatetime.h>
#include <qdir.h>
#include <qbuffer.h>
#include <qtextstream.h>

#include <kdebug.h>
#include <klocale.h>
#include <kfileitem.h>
#include <kurl.h>
#include <kconfig.h>
#include <kapplication.h>
#include <kmessagebox.h>
#include <kdatetimewidget.h>

#include "channel.h"
#include "channelstore.h"
#include "channelsuitewidgetimpl.h"
#include "kdetv.h"
#include "kdetvchannelplugin.h"
#include "sourcemanager.h"
#include "channelwidgetimpl.h"
#include "channelsuitedb.h"


class SuiteListItem : public QListViewItem
{
public:
    SuiteListItem(QListView* l, ChannelSuiteDbEntry* e)
        : QListViewItem(l, e->region(), e->type(), e->comment()),
          _e(e)
    {

    }
    virtual ~SuiteListItem()
    {
    }

    ChannelSuiteDbEntry* _e;
};


ChannelSuiteWidgetImpl::ChannelSuiteWidgetImpl( Kdetv* ktv, KConfig* cfg, QWidget* parent,
                                                const char* name, WFlags fl)
    : ChannelSuiteWidget(parent, name, fl),
      _ktv(ktv),
      _cfg(cfg)
{
    _db = new ChannelSuiteDb();
    connect(_db, SIGNAL( loadDone(bool) ),
            this, SLOT( loadDone(bool) ));
    connect(_db, SIGNAL( importDone(bool) ),
            this, SLOT( importDone(bool) ));

    ChannelWidgetImpl* cw = new ChannelWidgetImpl(_tabWidget->page(3), _ktv, ktv->config());
    _sdlg = static_cast<SettingsDialogPage*>(cw);
    _sdlg->setup();

    QHBoxLayout* hbox = new QHBoxLayout(_tabWidget->page(3));
    hbox->addWidget(cw);

    _importSuite->setEnabled(false);

    connect(_nowButton, SIGNAL( clicked() ),
            this, SLOT( nowClicked() ));
    connect(_importSuite, SIGNAL( clicked() ),
            this, SLOT( importClicked() ));
    connect(_contributeButton, SIGNAL( clicked() ),
            this, SLOT( contributeClicked() ));
    connect(_loadIndex, SIGNAL( clicked() ),
            this, SLOT( loadClicked() ));
    connect(_countrySelector, SIGNAL( activated(const QString&) ),
            this, SLOT( countrySelectionChanged() ));
    connect(_suiteSelector, SIGNAL( selectionChanged() ),
            this, SLOT( suiteSelectionChanged() ));

    _type->insertItem("air");
    _type->insertItem("cable");
    _type->insertItem("unspecified");

    SourceManager* srcm = ktv->sourceManager();
    _source->insertStringList(srcm->sourcesFor(srcm->device()));
    _source->setCurrentText(srcm->source());

    _encoding->insertStringList(srcm->encodingsFor(srcm->device()));
    _encoding->setCurrentText(srcm->encoding());

    // not yet
    //    _type->insertItem("dvb-s");
    //    _type->insertItem("dvb-c");
    //    _type->insertItem("dvb-t");

    _indexURL->setText(_cfg->readEntry("Index URL", "http://dziegel.free.fr/channelsuites/index.xml"));

    updateMetaInfo();
    //    loadClicked();
}

ChannelSuiteWidgetImpl::~ChannelSuiteWidgetImpl()
{
    delete _db;
}

void ChannelSuiteWidgetImpl::nowClicked()
{
    _lastUpdate->setDateTime(QDateTime::currentDateTime());
}

void ChannelSuiteWidgetImpl::updateMetaInfo()
{
    KdetvChannelPlugin::ChannelFileMetaInfo& i = _ktv->channels()->getMetaInfo();

    _contributor->setText(i._contributor);
    _country->setText(i._country);
    _region->setText(i._region);
    _lastUpdate->setDateTime(i._lastUpdate);
    _comment->setText(i._comment);
    
    if(i._type.isEmpty()) {
        i._type = "unspecified";
    }
    _type->setCurrentText(i._type);
}

void ChannelSuiteWidgetImpl::loadClicked()
{
    _db->loadIndex(_indexURL->text());

    _loadIndex->setEnabled(false);
    _countrySelector->setEnabled(false);
    _suiteSelector->setEnabled(false);
    _importSuite->setEnabled(false);
}

void ChannelSuiteWidgetImpl::loadDone(bool)
{
    _countrySelector->clear();
    _countrySelector->insertStringList(_db->getCountries());

    _loadIndex->setEnabled(true);
    _countrySelector->setEnabled(true);
    _suiteSelector->setEnabled(true);
    _importSuite->setEnabled(true);

    countrySelectionChanged();
}

void ChannelSuiteWidgetImpl::importClicked()
{
    SuiteListItem* i = (SuiteListItem*)_suiteSelector->currentItem();
    if(!i) {
        return;
    }

    int rc = KMessageBox::warningContinueCancel(0L,
                                                i18n("Are you sure you want to import?\nThis will overwrite your current channel file."),
                                                i18n("Continue Import?"));
    if (rc == KMessageBox::Cancel) {
        return;
    }

    _importSuite->setEnabled(false);
    _db->importList(*_ktv->channels(), *(i->_e));
}

void ChannelSuiteWidgetImpl::importDone(bool)
{
    _importSuite->setEnabled(true);
    updateMetaInfo();

    ChannelStore* cs = _ktv->channels();
    for(unsigned int i=0; i<cs->count(); i++) {
        cs->channelAt(i)->setChannelProperty("source", _source->currentText());
        cs->channelAt(i)->setChannelProperty("encoding", _encoding->currentText());
    }
}

void ChannelSuiteWidgetImpl::contributeClicked()
{
    apply();
    nowClicked();

    if(_contributor->text().isEmpty()) {
        KMessageBox::error(0L,
                           i18n("Mandatory field \"Contributor\" is empty."),
                           i18n("Mandatory Field: Contributor"));
        return;
    }

    if(_country->text().isEmpty()) {
        KMessageBox::error(0L,
                           i18n("Mandatory field \"Country\" is empty."),
                           i18n("Mandatory Field: Country"));
        return;
    }

    if(_region->text().isEmpty()) {
        KMessageBox::error(0L,
                           i18n("Mandatory field \"City/Region\" is empty."),
                           i18n("Mandatory Field: Region/City"));
        return;
    }

    if(_type->currentText() == i18n("unspecified")) {
        KMessageBox::error(0L,
                           i18n("Channelsuite type is unspecified."),
                           i18n("Mandatory Field: Type"));
        return;
    }
    
    if(_ktv->channels()->count() > 50) {
        int rc = KMessageBox::warningContinueCancel(0L,
                                                    i18n("Your channelsuite contains more than 50 stations.\n"
                                                         "Are you sure you removed all unused frequencies?"),
                                                    i18n("Too Many Channels?"));
        if (rc == KMessageBox::Cancel) {
            return;
        }
    }

    if((_ktv->channels()->count() > 10) && (_type->currentText() == i18n("air"))) {
        int rc = KMessageBox::warningContinueCancel(0L,
                                                    i18n("Your channelsuite contains more than 10 stations,\n"
                                                         "but the type is set to \"air\". Are you sure this is correct?"),
                                                    i18n("Wrong Suite Type?"));
        if (rc == KMessageBox::Cancel) {
            return;
        }
    }

    if((_ktv->channels()->count() < 10) && (_type->currentText() != i18n("air"))) {
        int rc = KMessageBox::warningContinueCancel(0L,
                                                    i18n("Your channelsuite contains less than 10 stations,\n"
                                                         "but the type is not set to \"air\". Are you sure this is correct?"),
                                                    i18n("Wrong Suite Type?"));
        if (rc == KMessageBox::Cancel) {
            return;
        }
    }

    QBuffer b;
    b.open(IO_ReadWrite);
    if(!_ktv->channels()->save(&b)) {
        kdWarning() << "ChannelsuiteWidgetImpl::contributeClicked(): Unable to save to buffer" << endl;
        return;
    }
    b.reset();

    QTextStream ts(&b);
    kapp->invokeMailer("dziegel@gmx.de",
                       QString::null,
                       QString::null,
                       "[kdetv suites] New channel suite!",
                       ts.read());
}

void ChannelSuiteWidgetImpl::countrySelectionChanged()
{
    _suiteSelector->clear();

    ChannelSuiteDbEntryList* entries;
    entries = _db->getEntries(_countrySelector->currentText());

    for(QPtrListIterator<ChannelSuiteDbEntry> it(*entries);
        *it != NULL;
        ++it) {
        ChannelSuiteDbEntry* e = *it;

        new SuiteListItem(_suiteSelector, e);
    }
    
    delete entries;
    suiteSelectionChanged();
}

void ChannelSuiteWidgetImpl::suiteSelectionChanged()
{
    QListViewItem* i = _suiteSelector->selectedItem();

    if(i) {
        _importSuite->setEnabled(true);
    } else {
        _importSuite->setEnabled(false);
    }
}

void ChannelSuiteWidgetImpl::apply()
{
    _cfg->writeEntry("Index URL", _indexURL->text());

    KdetvChannelPlugin::ChannelFileMetaInfo& i = _ktv->channels()->getMetaInfo();

    i._contributor = _contributor->text();
    i._country = _country->text();
    i._region = _region->text();
    i._type = _type->currentText();
    i._comment = _comment->text();
    i._lastUpdate = _lastUpdate->dateTime();

    _sdlg->apply();
}

void ChannelSuiteWidgetImpl::cancel()
{
    _sdlg->cancel();
}

#include "channelsuitewidgetimpl.moc"
