// -*- c++ -*-

/*
 *
 * Copyright (C) 2002 Richard Moore <rich@kde.org>
 *
 * 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., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

#include <qfile.h>
#include <kdebug.h>

#include "channelscannerregion.h"

ChannelScannerRegion::ChannelScannerRegion()
    : fmt( UNKNOWN )
{
}

ChannelScannerRegion::~ChannelScannerRegion()
{
}

bool ChannelScannerRegion::load( const QString &filename )
{
    kdDebug() << "ChannelScannerRegion::load() Loading file, " << filename << endl;

    if ( filename.isNull() )
	return false;

    QFile file( filename );
    if ( !file.open( IO_ReadOnly ) ) {
	kdWarning() << "ChannelScannerRegion::load() Cannot open file, " << filename << endl;
	return false;
    }

    bool parsedOk = doc.setContent( &file );
    file.close();
    if ( !parsedOk ) {
	kdWarning() << "ChannelScannerRegion::load() Invalid XML document, " << filename << endl;
	return false;
    }

    if ( !setup() ) {
	kdWarning() << "ChannelScannerRegion::load() Invalid region file structure, " << filename << endl;
	return false;
    }

    if ( !readInfo() ) {
	kdWarning() << "ChannelScannerRegion::load() Invalid region info structure, " << filename << endl;
	return false;
    }

    return true;
}

bool ChannelScannerRegion::setup()
{
    kdDebug() << "ChannelScannerRegion::setup() Checking file structure" << endl;

    // <kwintv>...</kwintv>
    QDomElement root = doc.documentElement();
    if ( root.tagName() != "kwintv" )
	return false;

    //  <tvregion>...</tvregion>
    QDomNode n = root.firstChild();
    if ( n.isNull() || (!n.isElement()) )
	return false;
    root = n.toElement();
    if ( root.tagName() != "tvregion" )
	return false;

    // First child is <info>...</info>
    n = root.firstChild();
    if ( n.isNull() || (!n.isElement()) )
	return false;
    info = n.toElement();
    if ( info.tagName() != "info" )
	return false;

    // Second child is <tunings>...</tunings>
    n = info.nextSibling();
    if ( n.isNull() || (!n.isElement()) )
	return false;
    tunings = n.toElement();
    if ( tunings.tagName() != "tunings" )
	return false;

    kdDebug() << "ChannelScannerRegion::setup() Structure is ok" << endl;
    return true;
}

bool ChannelScannerRegion::first()
{
    kdDebug() << "ChannelScannerRegion::first()" << endl;

    QDomNode n = tunings.firstChild();
    if ( n.isNull() || (!n.isElement() ) )
	return false;
    elem = n.toElement();

    return readTuning();
}

bool ChannelScannerRegion::next()
{
    QDomNode n = elem.nextSibling();
    if ( n.isNull() || (!n.isElement() ) )
	return false;

    elem = n.toElement();
    bool hasNext = readTuning();
    kdDebug() << "ChannelScannerRegion::next() returning " << hasNext << endl;
    return hasNext;
}

bool ChannelScannerRegion::readInfo()
{
    // Region name
    QDomNode n = info.firstChild();
    if ( n.isNull() || (!n.isElement()) )
	return false;
    regName = readText( n.toElement(), "name" );

    // Find format
    n = n.nextSibling();
    if ( n.isNull() || (!n.isElement()) )
	return false;
    QDomElement elem = n.toElement();
    if ( elem.tagName() != "format" )
	return false;

    // Get format id tag
    n = elem.firstChild();
    if ( n.isNull() || (!n.isElement()) )
	return false;
    elem = n.toElement();

    // Choose format
    if ( elem.tagName() == "pal" )
	fmt = PAL;
    else if ( elem.tagName() == "secam" )
	fmt = PAL;
    else if ( elem.tagName() == "ntsc" )
	fmt = PAL;
    else {
	fmt = UNKNOWN;
	return false;
    }

    return true;
}

bool ChannelScannerRegion::readTuning()
{
    if ( elem.tagName() != "tuning" )
	return false;

    QDomNode n = elem.firstChild();
    label = readText( n.toElement(), "name" );

    n = n.nextSibling();
    freq = readTextULong( n.toElement(), "frequency" );
    freq = 16*freq/1000;

    return true;
}

QDomElement ChannelScannerRegion::readElement( const QDomNode &n, const QString &tag )
{
    QDomElement elem;
    if ( n.isNull() || (!n.isElement()) )
	return elem;

    QDomNode nn( n );
    elem = nn.toElement();
    if ( elem.tagName() != tag )
	return QDomElement();

    return elem;
}

unsigned long ChannelScannerRegion::readTextULong( const QDomElement &elem, const QString &tag )
{
    QString val = readText( elem, tag );
    if ( val.isNull() )
	return 0;

    return val.toULong();
}

QString ChannelScannerRegion::readText( const QDomElement &elem, const QString &tag )
{
    if ( elem.tagName() != tag )
	return QString::null;

    return elem.text();
}


