/* This file is part of the KDE project
   Copyright (C) 2001 David Faure <faure@kde.org>
   Copyright 2003 Nicolas GOUTTE <goutte@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 "config.h"
#include <KoGlobal.h>
#include <kdebug.h>
#include <tqfont.h>
#include <tqfontinfo.h>
#include <tdeglobalsettings.h>
#include <tdeglobal.h>
#include <tdelocale.h>
#include <ksimpleconfig.h>
#include <kstandarddirs.h>
#include <kstaticdeleter.h>
#include <kimageio.h>
#include <kiconloader.h>
#include <kstandarddirs.h>
#include <locale.h>

KoGlobal* KoGlobal::s_global = 0L;
static KStaticDeleter<KoGlobal> sdg;

KoGlobal* KoGlobal::self()
{
    if ( !s_global )
        sdg.setObject( s_global, new KoGlobal );
    return s_global;
}

KoGlobal::KoGlobal()
    : m_pointSize( -1 ), m_kofficeConfig( 0L )
{
    // Make sure that TQCString::setNum doesn't give us "," as decimal point, e.g. when saving to OpenDocument.
    setlocale( LC_NUMERIC, "C" );

    // Install the libkoffice* translations
    TDEGlobal::locale()->insertCatalogue("koffice");

    KImageIO::registerFormats();

    // Tell TDEStandardDirs about the koffice prefix
    TDEGlobal::dirs()->addPrefix(PREFIX);

    // Tell the iconloader about share/apps/koffice/icons
    TDEGlobal::iconLoader()->addAppDir("koffice");

    // Another way to get the DPI of the display would be TQPaintDeviceMetrics,
    // but we have no widget here (and moving this to KoView wouldn't allow
    // using this from the document easily).
#ifdef TQ_WS_X11
    m_dpiX = TQPaintDevice::x11AppDpiX();
    m_dpiY = TQPaintDevice::x11AppDpiY();
#else
    m_dpiX = 75;
    m_dpiY = 75;
#endif
}

KoGlobal::~KoGlobal()
{
    delete m_kofficeConfig;
}

TQFont KoGlobal::_defaultFont()
{
    TQFont font = TDEGlobalSettings::generalFont();
    // we have to use TQFontInfo, in case the font was specified with a pixel size
    if ( font.pointSize() == -1 )
    {
        // cache size into m_pointSize, since TQFontInfo loads the font -> slow
        if ( m_pointSize == -1 )
            m_pointSize = TQFontInfo(font).pointSize();
        Q_ASSERT( m_pointSize != -1 );
        font.setPointSize( m_pointSize );
    }
    //kdDebug()<<k_funcinfo<<"TQFontInfo(font).pointSize() :"<<TQFontInfo(font).pointSize()<<endl;
    //kdDebug()<<k_funcinfo<<"font.name() :"<<font.family ()<<endl;
    return font;
}

TQStringList KoGlobal::_listOfLanguageTags()
{
    if ( m_langMap.isEmpty() )
        createListOfLanguages();
    return m_langMap.values();
}

TQStringList KoGlobal::_listOfLanguages()
{
    if ( m_langMap.empty() )
        createListOfLanguages();
    return m_langMap.keys();
}

void KoGlobal::createListOfLanguages()
{
    TDEConfig config( "all_languages", true, false, "locale" );
    // Note that we could also use TDELocale::allLanguagesTwoAlpha

    TQMap<TQString, bool> seenLanguages;
    const TQStringList langlist = config.groupList();
    for ( TQStringList::ConstIterator itall = langlist.begin();
          itall != langlist.end(); ++itall )
    {
        const TQString tag = *itall;
        config.setGroup( tag );
        const TQString name = config.readEntry("Name", tag);
        // e.g. name is "French" and tag is "fr"

        // The TQMap does the sorting on the display-name, so that
        // comboboxes are sorted.
        m_langMap.insert( name, tag );

        seenLanguages.insert( tag, true );
    }

    // Also take a look at the installed translations.
    // Many of them are already in all_languages but all_languages doesn't
    // currently have en_GB or en_US etc.

    const TQStringList translationList = TDEGlobal::dirs()->findAllResources("locale",
                                                            TQString::fromLatin1("*/entry.desktop"));
    for ( TQStringList::ConstIterator it = translationList.begin();
          it != translationList.end(); ++it )
    {
        // Extract the language tag from the directory name
        TQString tag = *it;
        int index = tag.findRev('/');
        tag = tag.left(index);
        index = tag.findRev('/');
        tag = tag.mid(index+1);

        if ( seenLanguages.find( tag ) == seenLanguages.end() ) {
            KSimpleConfig entry(*it);
            entry.setGroup("KCM Locale");

            const TQString name = entry.readEntry("Name", tag);
            // e.g. name is "US English" and tag is "en_US"
            m_langMap.insert( name, tag );

            // enable this if writing a third way of finding languages below
            //seenLanguages.insert( tag, true );
        }

    }

    // #### We also might not have an entry for a language where spellchecking is supported,
    //      but no KDE translation is available, like fr_CA.
    // How to add them?
}

TQString KoGlobal::tagOfLanguage( const TQString & _lang)
{
    const LanguageMap& map = self()->m_langMap;
    TQMap<TQString,TQString>::ConstIterator it = map.find( _lang );
    if ( it != map.end() )
        return *it;
    return TQString();
}

TQString KoGlobal::languageFromTag( const TQString &langTag )
{
    const LanguageMap& map = self()->m_langMap;
    TQMap<TQString,TQString>::ConstIterator it = map.begin();
    const TQMap<TQString,TQString>::ConstIterator end = map.end();
    for ( ; it != end; ++it )
        if ( it.data() == langTag )
            return it.key();

    // Language code not found. Better return the code (tag) than nothing.
    return langTag;
}

TDEConfig* KoGlobal::_kofficeConfig()
{
    if ( !m_kofficeConfig ) {
        m_kofficeConfig = new TDEConfig( "kofficerc" );
    }
    return m_kofficeConfig;
}

void KoGlobal::setDPI( int x, int y )
{
    //kdDebug() << k_funcinfo << x << "," << y << endl;
    KoGlobal* s = self();
    s->m_dpiX = x;
    s->m_dpiY = y;
}
