/***************************************************************************
                          StationListXmlHandler.cpp  -  description
                             -------------------
    begin                : Son Jan 12 2003
    copyright            : (C) 2003 by Martin Witte
    email                : witte@kawo1.rwth-aachen.de
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/

#include "include/stationlistxmlhandler.h"
#include <tdelocale.h>

const char *TDERadioConfigElement         = "tderadiorc";

const char *StationListElement          = "stationlist";
const char *compatStationElement        = "station";

const char *StationListInfo             = "info";
const char *StationListInfoMaintainer   = "maintainer";
const char *StationListInfoCountry      = "country";
const char *StationListInfoCity         = "city";
const char *StationListInfoMedia        = "media";
const char *StationListInfoComments     = "comments";
const char *StationListInfoChanged      = "changed";
const char *StationListInfoCreator      = "creator";

const char *StationListFormat           = "format";


StationListXmlHandler::StationListXmlHandler (const IErrorLogClient &logger)
    : m_logger(logger),
      m_compatMode (false)
{
    m_newStation = NULL;
}


StationListXmlHandler::~StationListXmlHandler ()
{
}


bool StationListXmlHandler::startDocument ()
{
    m_status.clear();

    m_stations.clear();
    clearNewStation();

    return true;
}



#define START_ELEMENT_ERROR    m_logger.logError("StationListXmlHandler::startElement: " + \
                                        i18n("misplaced element %1") \
                                        .arg(qname));\
                               return false;

bool StationListXmlHandler::startElement (const TQString &/*ns*/, const TQString &/*localname*/,
                                          const TQString& _qname, const TQXmlAttributes &)
{
    TQString qname = _qname;
    if (qname == TDERadioConfigElement) {
        if (m_status.size()) { START_ELEMENT_ERROR }

    // station list
    } else if (qname == StationListElement) {
        if (!m_status.size() || m_status.back() != TDERadioConfigElement) { START_ELEMENT_ERROR }
        m_stations.clear();
        clearNewStation();

    } else if (qname == StationListFormat) {
        if (!m_status.size() || m_status.back() != StationListElement) { START_ELEMENT_ERROR }

    } else if (qname == StationListInfo) {
        if (!m_status.size() || m_status.back() != StationListElement) { START_ELEMENT_ERROR }

    } else if (qname == StationListInfoMaintainer ||
               qname == StationListInfoCountry ||
               qname == StationListInfoCity ||
               qname == StationListInfoMedia ||
               qname == StationListInfoComments ||
               qname == StationListInfoChanged ||
               qname == StationListInfoCreator
               )
    {
        if (!m_status.size() || m_status.back() != StationListInfo) { START_ELEMENT_ERROR }

    } else if (!m_newStation && m_status.size() && m_status.back() == StationListElement) {

        if (qname == compatStationElement) {
            qname = "FrequencyRadioStation";
            m_compatMode = true;
        }

        const RadioStation *x = RadioStation::getStationClass(qname);
        m_newStation = x ? x->copy() : NULL;

        if (!m_newStation) { START_ELEMENT_ERROR }

    } else if (m_newStation && m_status.size() && m_status.back() == m_newStation->getClassName()) {

        // check done later when characters arrive

    } else { // unknown
        m_logger.logWarning("StationListXmlHandler::startElement: " +
                   i18n("unknown or unexpected element %1").arg(qname));
    }

    m_status.push_back(qname);
    return true;
}


bool StationListXmlHandler::endElement (const TQString &/*ns*/, const TQString &/*localname*/,
                                        const TQString &_qname)
{
    TQString qname = _qname;
    if (qname == compatStationElement) {
        qname = "FrequencyRadioStation";
        m_compatMode = true;
    }

    if (m_status.size() && m_status.back() == qname) {

        if (m_newStation && qname == m_newStation->getClassName()) {
            m_stations.append(m_newStation);
            clearNewStation();
        }

        m_status.pop_back();

    } else {
        if (m_status.size()) {
            m_logger.logError("StationListXmlHandler::endElement: " +
                     i18n("expected element %1, but found %2")
                     .arg(m_status.back()).arg(qname));
        } else {
            m_logger.logError("StationListXmlHandler::endElement: " +
                     i18n("unexpected element %1").arg(qname));
        }
    }
    return true;
}


#define CHARACTERS_ERROR    m_logger.logError("StationListXmlHandler::characters: " + \
                                     i18n("invalid data for element %1") \
                                     .arg(stat)); \
                            return false;

bool StationListXmlHandler::characters (const TQString &ch)
{
    TQString stat = m_status.back();
    TQString str = ch.stripWhiteSpace();

    // Station parsing

    // information on list
    if (stat == StationListFormat) {

        if (str != STATION_LIST_FORMAT) {
            m_logger.logError(i18n("found a station list with unknown format %1").arg(str));
            return false;
        }

    } else if (stat == StationListInfo) {

    } else if (stat == StationListInfoMaintainer) {

        m_metaData.maintainer = str;

    } else if (stat == StationListInfoCountry) {

        m_metaData.country = str;

    } else if (stat == StationListInfoCity) {

        m_metaData.city = str;

    } else if (stat == StationListInfoMedia) {

        m_metaData.media = str;

    } else if (stat == StationListInfoComments) {

        m_metaData.comment = str;

    } else if (stat == StationListInfoChanged) {

        m_metaData.lastChange = TQDateTime::fromString(str, TQt::ISODate);

    } else if (stat == StationListInfoCreator) {

        // do nothing

    // stations

    } else if (m_newStation && m_newStation->getClassName() != stat) {

        if (!m_newStation->setProperty(stat, str)) {
            m_logger.logWarning("StationListXmlHandler::characters: " +
                       i18n("unknown property %1 for class %2")
                       .arg(stat)
                       .arg(m_newStation->getClassName()));
        }

    } else if (str.length()) {
        m_logger.logError("StationListXmlHandler::characters: " +
                 i18n("characters ignored for element %1").arg(stat));
    }
    return true;
}


void StationListXmlHandler::clearNewStation()
{
    if (m_newStation)
        delete m_newStation;
    m_newStation = NULL;
}
