// A wrapper for KCharsets
// Copyright (C) 2004, 2006 Shintaro Matsuoka <shin@shoegazed.org>

/*
  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 "irccharsets.h"

#include <tqglobal.h>
#include <tqregexp.h>
#include <tqtextcodec.h>
#include <kcharsets.h>
#include <kdebug.h>
#include <tdeglobal.h>
#include <kstaticdeleter.h>

#include <tqlocale.h>


namespace Konversation
{

    IRCCharsets* IRCCharsets::s_self = 0;
    static KStaticDeleter<IRCCharsets> staticIRCCharsetDeleter;

    IRCCharsets *IRCCharsets::self()
    {
        if(!s_self)
            staticIRCCharsetDeleter.setObject(s_self, new IRCCharsets());
        return s_self;
    }

    TQStringList IRCCharsets::availableEncodingShortNames()
    {
        return m_shortNames;
    }

    TQStringList IRCCharsets::availableEncodingDescriptiveNames()
    {
        return m_descriptiveNames;
    }

    int IRCCharsets::availableEncodingsCount()
    {
        return m_shortNames.count();
    }

    TQString IRCCharsets::shortNameToDescriptiveName( const TQString& shortName )
    {
        return m_descriptiveNames[ shortNameToIndex( shortName ) ];
    }

    TQString descriptiveNameToShortName( const TQString& descriptiveName )
    {
        return TDEGlobal::charsets()->encodingForName( descriptiveName );
    }

    TQString IRCCharsets::ambiguousNameToShortName( const TQString& ambiguousName )
    {
        // simplify ambiguousName
        TQString simplifiedAmbiguousName( ambiguousName.lower() );
        simplifiedAmbiguousName.replace( TQRegExp( "[^a-z0-9]" ), "" );

        // search m_simplifiedShortNames
        int index = 0;
        for ( TQStringList::iterator it = m_simplifiedShortNames.begin() ; it != m_simplifiedShortNames.end() ; ++it )
        {
            if ( (*it) == simplifiedAmbiguousName )
                return m_shortNames[index];
            ++index;
        }

        // search m_shortNameAliases
        if ( m_shortNameAliases.contains( simplifiedAmbiguousName ) )
            return m_shortNameAliases[ simplifiedAmbiguousName ];

        // failed
        return TQString();
    }

    int IRCCharsets::shortNameToIndex( const TQString& shortName )
    {
        int index = 0;
        for ( TQStringList::iterator it = m_shortNames.begin() ; it != m_shortNames.end() ; ++it )
        {
            if ( (*it) == shortName )
                return index;
            ++index;
        }
        return -1;
    }

    bool IRCCharsets::isValidEncoding( const TQString& shortName )
    {
        return ( m_shortNames.contains( shortName ) > 0 );
    }

    TQString IRCCharsets::encodingForLocale()
    {
        TQString locale = TQLocale::system().name();

        // Special cases
        // don't add conditions for the languages for which TQTextCodec::codecForLocale() returns a correct codec.
        if ( locale == "ja_JP" )
            return "jis7";

        // it's a little hacky..
        for ( TQStringList::iterator it = m_shortNames.begin() ; it != m_shortNames.end() ; ++it )
            if ( TQTextCodec::codecForName( (*it).ascii() ) == TQTextCodec::codecForLocale() )
                return *it;

        return "utf8";
    }

    TQTextCodec* IRCCharsets::codecForName( const TQString& shortName )
    {
        if(shortName == "iso-2022-jp")
            return TQTextCodec::codecForName( "jis7" );
        else
            return TQTextCodec::codecForName( shortName.ascii() );
    }

    IRCCharsets::IRCCharsets()
    {
        s_self = this;

        // setup m_shortNameAliases
        // use only [a-z0-9] for keys!
        m_shortNameAliases["unicode"] = "utf8";
        m_shortNameAliases["latin1"] = "iso-8859-1";

        // setup m_shortNames, m_descriptiveNames, m_simplifiedShortNames
        TQRegExp reSimplify( "[^a-zA-Z0-9]" );
        m_descriptiveNames = TDEGlobal::charsets()->descriptiveEncodingNames();
        TQStringList::Iterator it = m_descriptiveNames.begin();
        while ( it != m_descriptiveNames.end() )
        {
            TQString encodingName = TDEGlobal::charsets()->encodingForName( *it );
            // exclude encodings which are not supported on IRC
            if ( encodingName == "iso-10646-ucs-2" ||
                 encodingName == "ucs2" ||
                 encodingName == "utf16" ||
                 encodingName == "utf7" )
            {
                it = m_descriptiveNames.remove( it );
            }
            else
            {
                m_shortNames.append( encodingName );
                m_simplifiedShortNames.append( encodingName.replace( reSimplify, "" ) );

                if(encodingName == "jis7")        // Add iso-2022-jp which is same as jis7 but not in TQt
                {
                    it = m_descriptiveNames.insert(it, "Japanese ( iso-2022-jp )");
                    m_shortNames.append( "iso-2022-jp" );
                    m_simplifiedShortNames.append( "ISO-2022-JP" );
                    ++it;
                }
                ++it;
            }

        }
    }

}
