/* This file is part of the KDE project
   Copyright (C) 2004 Laurent Montel <montel@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., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
*/

#include "KoOasisSettings.h"
#include "KoXmlNS.h"
#include "KoDom.h"
#include <kdebug.h>

KoOasisSettings::KoOasisSettings( const TQDomDocument& doc )
    : m_settingsElement( KoDom::namedItemNS( doc.documentElement(), KoXmlNS::office, "settings" ) ),
      m_configNSURI( KoXmlNS::config )
{
    const TQDomElement contents = doc.documentElement();
    if ( m_settingsElement.isNull() )
        kdDebug() << " document doesn't have tag 'office:settings'\n";
}

KoOasisSettings::KoOasisSettings( const TQDomDocument& doc, const char* officeNSURI, const char* configNSURI )
    : m_settingsElement( KoDom::namedItemNS( doc.documentElement(), officeNSURI, "settings" ) ),
      m_configNSURI( configNSURI )
{
    const TQDomElement contents = doc.documentElement();
    if ( m_settingsElement.isNull() )
        kdDebug() << " document doesn't have tag 'office:settings'\n";
}

KoOasisSettings::Items KoOasisSettings::itemSet( const TQString& itemSetName ) const
{
    TQDomElement e;
    forEachElement( e, m_settingsElement )
    {
        if ( e.localName() == "config-item-set" &&
             e.namespaceURI() == m_configNSURI &&
             e.attributeNS( m_configNSURI, "name", TQString() ) == itemSetName )
        {
            return Items( e, this );
        }
    }

    return Items( TQDomElement(), this );
}

KoOasisSettings::IndexedMap KoOasisSettings::Items::indexedMap( const TQString& itemMapName ) const
{
    TQDomElement configItem;
    forEachElement( configItem, m_element )
    {
        if ( configItem.localName() == "config-item-map-indexed" &&
             configItem.namespaceURI() == m_settings->m_configNSURI &&
             configItem.attributeNS( m_settings->m_configNSURI, "name", TQString() ) == itemMapName )
        {
            return IndexedMap( configItem, m_settings );
        }
    }
    return IndexedMap( TQDomElement(), m_settings );
}

KoOasisSettings::NamedMap KoOasisSettings::Items::namedMap( const TQString& itemMapName ) const
{
    TQDomElement configItem;
    forEachElement( configItem, m_element )
    {
        if ( configItem.localName() == "config-item-map-named" &&
             configItem.namespaceURI() == m_settings->m_configNSURI &&
             configItem.attributeNS( m_settings->m_configNSURI, "name", TQString() ) == itemMapName )
        {
            return NamedMap( configItem, m_settings );
        }
    }
    return NamedMap( TQDomElement(), m_settings );
}

KoOasisSettings::Items KoOasisSettings::IndexedMap::entry( int entryIndex ) const
{
    int i = 0;
    TQDomElement entry;
    forEachElement( entry, m_element )
    {
        if ( entry.localName() == "config-item-map-entry" &&
             entry.namespaceURI() == m_settings->m_configNSURI )
        {
            if ( i == entryIndex )
                return Items( entry, m_settings );
            else
                ++i;
        }
    }
    return Items( TQDomElement(), m_settings );
}

KoOasisSettings::Items KoOasisSettings::NamedMap::entry( const TQString& entryName ) const
{
    TQDomElement entry;
    forEachElement( entry, m_element )
    {
        if ( entry.localName() == "config-item-map-entry" &&
             entry.namespaceURI() == m_settings->m_configNSURI &&
             entry.attributeNS( m_settings->m_configNSURI, "name", TQString() ) == entryName )
        {
            return Items( entry, m_settings );
        }
    }
    return Items( TQDomElement(), m_settings );
}

// helper method
TQString KoOasisSettings::Items::findConfigItem( const TQDomElement& element,
                                                const TQString& item, bool* ok ) const
{
    TQDomElement it;
    forEachElement( it, element )
    {
        if ( it.localName() == "config-item" &&
             it.namespaceURI() == m_settings->m_configNSURI &&
             it.attributeNS( m_settings->m_configNSURI, "name", TQString() ) == item )
        {
            *ok = true;
            return it.text();
        }
    }
    *ok = false;
    return TQString();
}


TQString KoOasisSettings::Items::findConfigItem( const TQString& item, bool* ok ) const
{
    return findConfigItem( m_element, item, ok );
}

#if 0 // does anyone need this one? passing a default value does the job, too
bool KoOasisSettings::Items::hasConfigItem( const TQString& configName ) const
{
    bool ok;
    (void)findConfigItem( configName, &ok );
    return ok;
}
#endif

TQString KoOasisSettings::Items::parseConfigItemString( const TQString& configName, const TQString& defValue ) const
{
    bool ok;
    const TQString str = findConfigItem( configName, &ok );
    return ok ? str : defValue;
}

int KoOasisSettings::Items::parseConfigItemInt( const TQString& configName, int defValue ) const
{
    bool ok;
    const TQString str = findConfigItem( configName, &ok );
    int value;
    if ( ok ) {
        value = str.toInt( &ok );
        if ( ok )
            return value;
    }
    return defValue;
}

double KoOasisSettings::Items::parseConfigItemDouble( const TQString& configName, double defValue ) const
{
    bool ok;
    const TQString str = findConfigItem( configName, &ok );
    double value;
    if ( ok ) {
        value = str.toDouble( &ok );
        if ( ok )
            return value;
    }
    return defValue;
}

bool KoOasisSettings::Items::parseConfigItemBool( const TQString& configName, bool defValue ) const
{
    bool ok;
    const TQString str = findConfigItem( configName, &ok );
    if ( str == "true" )
        return true;
    else if ( str == "false" )
        return false;
    return defValue;
}

short KoOasisSettings::Items::parseConfigItemShort( const TQString& configName, short defValue ) const
{
    bool ok;
    const TQString str = findConfigItem( configName, &ok );
    short value;
    if ( ok ) {
        value = str.toShort( &ok );
        if ( ok )
            return value;
    }
    return defValue;
}

long KoOasisSettings::Items::parseConfigItemLong( const TQString& configName, long defValue ) const
{
    bool ok;
    const TQString str = findConfigItem( configName, &ok );
    long value;
    if ( ok ) {
        value = str.toLong( &ok );
        if ( ok )
            return value;
    }
    return defValue;
}