// -*- c++ -*-
/***************************************************************************
                           channeldb.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 <qdom.h>
#include <qbuffer.h>

#include <kdebug.h>
#include <klocale.h>
#include <kio/jobclasses.h>
#include <kio/jobuidelegate.h>

#include "channelsuitedb.h"
#include "channelstore.h"
#include "channelio.h"

ChannelSuiteDb::ChannelSuiteDb()
{
    _entries.setAutoDelete(true);
}

ChannelSuiteDb::~ChannelSuiteDb()
{
}

void ChannelSuiteDb::loadIndex(const KUrl& url)
{
    _indexBuf = new QBuffer();
    _indexBuf->open(QIODevice::ReadWrite);

    KIO::TransferJob* job = KIO::get(url, KIO::Reload, KIO::DefaultFlags);
    connect(job, SIGNAL( data(KIO::Job*, const QByteArray&) ),
            this, SLOT( indexDataArrived(KIO::Job*, const QByteArray&) ));
    connect(job, SIGNAL( result(KIO::Job*) ),
            this, SLOT( indexDataResult(KIO::Job*) ));
}

void ChannelSuiteDb::indexDataArrived(KIO::Job*, const QByteArray& data)
{
    _indexBuf->write(data);
}

void ChannelSuiteDb::indexDataResult(KIO::Job* job)
{
    if(job->error()) {
        job->ui()->showErrorMessage();
        emit loadDone(false);
        return;
    }

    _indexBuf->reset();

    QDomDocument doc;

    int rc = doc.setContent(_indexBuf);
    delete _indexBuf;
    
    if(!rc) {
        kWarning() << "ChannelSuiteDb: Unable to parse index file.";
        emit loadDone(false);
        return;
    }

    QDomElement root = doc.documentElement();
    if (root.tagName() != "tv-channelsuites") {
        kWarning() << "ChannelSuiteDb: File is not a channelsuites listing.";
        emit loadDone(false);
        return;
    }    

    QDomNode channelsuites = root.namedItem("tvregions");
    if (channelsuites.isNull()) {
        kWarning() << "ChannelSuiteDb: File does not contain channelsuites.";
        emit loadDone(false);
        return;
    }

    _entries.clear();

    for (QDomNode c = channelsuites.firstChild();
         !c.isNull() && c.isElement();
         c = c.nextSibling()) {
        QDomElement e = c.toElement();
        if(e.tagName() != "tvregion") {
            continue;
        }

        ChannelSuiteDbEntry* entry = new ChannelSuiteDbEntry();

        for (QDomNode n = e.firstChild();
             !n.isNull() && n.isElement();
             n = n.nextSibling()) {
            QDomElement node = n.toElement();
            
            if (node.tagName() == "region") {
                if(!_regions.contains(node.text())) {
                    _regions.append(node.text());
                }
                entry->_region = node.text();
            } else if (node.tagName() == "country") {
                if(!_countries.contains(node.text())) {
                    _countries.append(node.text());
                }
                entry->_country = node.text();
            } else if (node.tagName() == "type") {
                if(!_types.contains(node.text())) {
                    _types.append(node.text());
                }
                entry->_type = node.text();
            } else if (node.tagName() == "url") {
                entry->_url = node.text();
            } else if (node.tagName() == "comment") {
                entry->_comment = node.text();
            }
        }

        _entries.append(entry);
    }

    _countries.sort();
    _regions.sort();
    _types.sort();

    emit loadDone(true);
}

ChannelSuiteDbEntryList* ChannelSuiteDb::getEntries(const QString& country, const QString& region, const QString& type)
{
    ChannelSuiteDbEntryList* l = new ChannelSuiteDbEntryList();

    bool filterCountry = !country.isEmpty();
    bool filterRegion  = !region.isEmpty();
    bool filterType    = !type.isEmpty();

    for(Q3PtrListIterator<ChannelSuiteDbEntry> it(_entries);
        *it != NULL;
        ++it) {
        ChannelSuiteDbEntry* e = *it;
        
        if(filterCountry && (e->_country != country)) {
            continue;
        }
        if(filterRegion && (e->_region != region)) {
            continue;
        }
        if(filterType && (e->_type != type)) {
            continue;
        }

        l->append(e);
    }
    return l;
}

void ChannelSuiteDb::importList(ChannelStore& store, ChannelSuiteDbEntry& e)
{
    _importStore = &store;

    _importBuf = new QBuffer();
    _importBuf->open(QIODevice::ReadWrite);

    KIO::TransferJob* job = KIO::get(e._url, KIO::Reload, KIO::DefaultFlags);
    connect(job, SIGNAL( data(KIO::Job*, const QByteArray&) ),
            this, SLOT( importDataArrived(KIO::Job*, const QByteArray&) ));
    connect(job, SIGNAL( result(KIO::Job*) ),
            this, SLOT( importDataResult(KIO::Job*) ));
}

void ChannelSuiteDb::importDataArrived(KIO::Job*, const QByteArray& data)
{
    _importBuf->write(data);
}

void ChannelSuiteDb::importDataResult(KIO::Job* job)
{
    if(job->error()) {
        job->ui()->showErrorMessage();
        emit importDone(false);
        return;
    }

    _importBuf->reset();

    _importStore->load(_importBuf, "xml");
    _importStore->renumber();
    emit importDone(true);
    delete _importBuf;
}


ChannelSuiteDbEntry::ChannelSuiteDbEntry()
    : _country(QString::null),
      _region(QString::null),
      _type(QString::null),
      _comment(QString::null),
      _url(QString::null)
{
}

#include "channelsuitedb.moc"

// vim: ts=4 sw=4 et
