/***************************************************************************
 *   Copyright (C) 2003-2005 by liuspider                                  *
 *   liuspider@users.sourceforge.net                                       *
 *                                                                         *
 *   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 "config.h"

#define Uses_SCIM_GLOBAL_CONFIG
#define Uses_SCIM_CONFIG_PATH
#define Uses_SCIM_CONFIG_MODULE
#include <scim.h>

#include "scimglobalconfigplugin.h"

#include "scim_global.h"
#include <kgenericfactory.h>
#include <klocale.h>
#include <kstandarddirs.h> 
#include <kdialogbase.h>
#include <qvbox.h> 
#include <keditlistbox.h> 
#include <qlayout.h>
#include <qcheckbox.h>
#include <qcombobox.h>
#include <qlineedit.h>
#include <qpushbutton.h>
#include <qgroupbox.h>
#include <qerrormessage.h> 
#include <qspinbox.h>

typedef KGenericFactory<ScimGlobalConfigPlugin> ScimGlobalConfigPluginLoaderFactory;

K_EXPORT_COMPONENT_FACTORY( kcm_skimplugin_scim_global, 
    ScimGlobalConfigPluginLoaderFactory( "kcm_skimplugin_scim_global" ) )

class ScimGlobalConfigPlugin::ScimGlobalConfigPluginPrivate {
public:
    ScimGlobalSettingUI * ui;
    int panelProgramIndex;
    int configModuleIndex;
    QStringList utf8Locales;
    QString frontendAddress;
    QString iMEngineAddress;
    QString configAddress;
    QString panelAddress;
    int socketTimeout;
    bool warningBoxCleanup;
};

ScimGlobalConfigPlugin::ScimGlobalConfigPlugin(QWidget *parent, 
  const char */*name*/, const QStringList &args)
  : KCModule(ScimGlobalConfigPluginLoaderFactory::instance(), parent, args),
  d(new ScimGlobalConfigPluginPrivate)
{
    (new QVBoxLayout(this,0,0))->setAutoAdd(true);
    d->ui = new ScimGlobalSettingUI(this);
    d->ui->advSettings->hide();
    
    d->warningBoxCleanup = false;

    load();
    
    checkSettings();
    
    connect(d->ui->programCombo, SIGNAL(activated(int)), SLOT(widgetChanged()));
    connect(d->ui->ConfigCombo, SIGNAL(activated(int)), SLOT(widgetChanged()));
    
    //advanced settings
//     connect(d->ui->localesDeleteButton, SIGNAL(clicked()), SLOT(deleteLocale()) );
    connect(d->ui->localesEditButton, SIGNAL(clicked()), SLOT(editLocale()) );
//     connect(d->ui->unicodeLocaleCombo, SIGNAL(textChanged( const QString &)), SLOT(widgetChanged()) );
//     connect(d->ui->unicodeLocaleCombo, SIGNAL(activated(int)), SLOT(widgetChanged()) );
    
    connect(d->ui->frontendAddressEdit, SIGNAL(textChanged(const QString&)), SLOT(widgetChanged()));
    connect(d->ui->iMEngineAddressEdit, SIGNAL(textChanged(const QString&)), SLOT(widgetChanged()));
    connect(d->ui->configAddressEdit, SIGNAL(textChanged(const QString&)), SLOT(widgetChanged()));
    connect(d->ui->panelAddressEdit, SIGNAL(textChanged(const QString&)), SLOT(widgetChanged()));

    connect(d->ui->socketTimeoutSpinBox, SIGNAL(valueChanged(int)), SLOT(widgetChanged()));
}


ScimGlobalConfigPlugin::~ScimGlobalConfigPlugin()
{
    if(d->warningBoxCleanup)
        QErrorMessage::qtHandler ()->deleteLater();
}

void ScimGlobalConfigPlugin::editLocale()
{
    KDialogBase * editLocaleDlg = new KDialogBase(this,
        0, true, i18n("Edit Supported Locales"), KDialogBase::Ok|KDialogBase::Cancel);
    KEditListBox * localeList = new KEditListBox(editLocaleDlg->makeVBoxMainWidget(),
        0, false, KEditListBox ::Add | KEditListBox::Remove);

    for(int curl = 0; curl < d->ui->unicodeLocaleCombo->count(); curl++)
      localeList->insertItem(d->ui->unicodeLocaleCombo->text(curl));
    if(editLocaleDlg->exec() == QDialog::Accepted)
    {
      d->ui->unicodeLocaleCombo->clear();
      d->ui->unicodeLocaleCombo->insertStringList(localeList->items());
      widgetChanged();
    }
    delete editLocaleDlg;
}

void ScimGlobalConfigPlugin::widgetChanged()
{
    if( d->ui->programCombo->currentItem() != d->panelProgramIndex ||
        d->ui->ConfigCombo->currentItem() != d->configModuleIndex )
        emit changed(true);
    else if (checkLocales())
        emit changed(true);
    else if (d->frontendAddress != d->ui->frontendAddressEdit->text() ||
             d->iMEngineAddress != d->ui->iMEngineAddressEdit->text() ||
             d->configAddress != d->ui->configAddressEdit->text() ||
             d->panelAddress != d->ui->panelAddressEdit->text() ||
             d->socketTimeout != d->ui->socketTimeoutSpinBox->value())
        emit changed(true);
    else
        emit changed(false);
}

void ScimGlobalConfigPlugin::defaults()
{
//     KAutoCModule::defaults();
}

void ScimGlobalConfigPlugin::load()
{
    QString panelProgram = QString::fromUtf8(
      scim::scim_global_config_read(
        SCIM_GLOBAL_CONFIG_DEFAULT_PANEL_PROGRAM, scim::String ("scim-panel-kde")).c_str());
    d->panelProgramIndex = 0;
    if(panelProgram.contains("scim-panel-gtk"))
      d->panelProgramIndex = 1;
    d->ui->programCombo->setCurrentItem(d->panelProgramIndex);

    QString configModule = QString::fromUtf8(
      scim::scim_global_config_read(
        SCIM_GLOBAL_CONFIG_DEFAULT_CONFIG_MODULE, scim::String ("kconfig")).c_str());
        
    std::vector<scim::String>  config_list;
    scim::scim_get_config_module_list(config_list);
    if (std::find (config_list.begin (),
                   config_list.end (),
                   scim::String(configModule.latin1())) == config_list.end ())
        configModule = QString::fromUtf8(config_list[0].c_str());
    d->configModuleIndex = 0;
    d->ui->ConfigCombo->clear();
    for(uint i = 0; i < config_list.size(); i++) {
        QString item = QString::fromUtf8(config_list[i].c_str());
        d->ui->ConfigCombo->insertItem(item);
        if( item == configModule )
          d->configModuleIndex = i;
    }
    d->ui->ConfigCombo->setCurrentItem(d->configModuleIndex);
    
    //advanced settings
    QString utf8Locales = QString::fromUtf8(
      scim::scim_global_config_read(
        SCIM_GLOBAL_CONFIG_SUPPORTED_UNICODE_LOCALES, scim::String ("en_US.UTF-8")).c_str());
    d->utf8Locales = QStringList::split(",",utf8Locales);
    d->ui->unicodeLocaleCombo->clear();
    d->ui->unicodeLocaleCombo->insertStringList( d->utf8Locales );
    
    d->frontendAddress = QString::fromUtf8(
      scim::scim_global_config_read(
        SCIM_GLOBAL_CONFIG_DEFAULT_SOCKET_FRONTEND_ADDRESS, 
          scim::String ("local:/tmp/scim-socket-frontend")).c_str());
    d->ui->frontendAddressEdit->setText(d->frontendAddress);
      
    d->iMEngineAddress = QString::fromUtf8(
      scim::scim_global_config_read(
        SCIM_GLOBAL_CONFIG_DEFAULT_SOCKET_IMENGINE_ADDRESS, 
          scim::String ("local:/tmp/scim-socket-frontend")).c_str());
    d->ui->iMEngineAddressEdit->setText(d->iMEngineAddress);
    
    d->configAddress = QString::fromUtf8(
      scim::scim_global_config_read(
        SCIM_GLOBAL_CONFIG_DEFAULT_SOCKET_CONFIG_ADDRESS, 
          scim::String ("local:/tmp/scim-socket-frontend")).c_str());
    d->ui->configAddressEdit->setText(d->configAddress);
    
    d->panelAddress = QString::fromUtf8(
      scim::scim_global_config_read(
        SCIM_GLOBAL_CONFIG_DEFAULT_PANEL_SOCKET_ADDRESS, 
          scim::String ("local:/tmp/scim-panel-socket")).c_str());
    d->ui->panelAddressEdit->setText(d->panelAddress);
    
    d->socketTimeout = scim::scim_global_config_read(
      SCIM_GLOBAL_CONFIG_DEFAULT_SOCKET_TIMEOUT, 5000);
    d->ui->socketTimeoutSpinBox->setValue(d->socketTimeout);
}
void ScimGlobalConfigPlugin::checkSettings()
{
    if(d->ui->ConfigCombo->currentText() != ("kconfig")) {
        QErrorMessage * warningBox = QErrorMessage::qtHandler ();
        d->warningBoxCleanup = true;
        warningBox->message(i18n("If you want to use skim (scim-panel-kde) or scim-qtimm (Qt immodule support for SCIM), please select kconfig as the config module."));
    }
}
void ScimGlobalConfigPlugin::save()
{
    checkSettings();
    
    {
        scim::String newvalue("scim-panel-gtk");
        if( d->ui->programCombo->currentText() != "scim-panel-gtk" ) {
            QString path = KStandardDirs::findExe(d->ui->programCombo->currentText());
            if(!path.isNull())
                newvalue = scim::String(path.utf8());
        }   
        scim::scim_global_config_write(
              SCIM_GLOBAL_CONFIG_DEFAULT_PANEL_PROGRAM, newvalue);
    }
    
    {
        scim::String newvalue(d->ui->ConfigCombo->currentText().utf8());
        scim::scim_global_config_write(
              SCIM_GLOBAL_CONFIG_DEFAULT_CONFIG_MODULE, newvalue);
    }
    
    //advanced settings

    if(checkLocales()) {
      d->utf8Locales.clear();
      for(int i = 0; i < d->ui->unicodeLocaleCombo->count(); i++)
        d->utf8Locales << d->ui->unicodeLocaleCombo->text(i);
      scim::String newvalue(d->utf8Locales.join(",").utf8());
      scim::scim_global_config_write(
              SCIM_GLOBAL_CONFIG_SUPPORTED_UNICODE_LOCALES, newvalue);
    }
    
    if(d->frontendAddress != d->ui->frontendAddressEdit->text()) {
      scim::String newvalue(d->ui->frontendAddressEdit->text().utf8());
      scim::scim_global_config_write(
              SCIM_GLOBAL_CONFIG_DEFAULT_SOCKET_FRONTEND_ADDRESS, newvalue);
    }
    
    if(d->iMEngineAddress != d->ui->iMEngineAddressEdit->text()) {
      scim::String newvalue(d->ui->iMEngineAddressEdit->text().utf8());
      scim::scim_global_config_write(
              SCIM_GLOBAL_CONFIG_DEFAULT_SOCKET_IMENGINE_ADDRESS, newvalue);
    }
    
    if(d->configAddress != d->ui->configAddressEdit->text()) {
      scim::String newvalue(d->ui->configAddressEdit->text().utf8());
      scim::scim_global_config_write(
              SCIM_GLOBAL_CONFIG_DEFAULT_SOCKET_CONFIG_ADDRESS, newvalue);
    }
    
    if(d->panelAddress != d->ui->panelAddressEdit->text()) {
      scim::String newvalue(d->ui->panelAddressEdit->text().utf8());
      scim::scim_global_config_write(
              SCIM_GLOBAL_CONFIG_DEFAULT_PANEL_SOCKET_ADDRESS, newvalue);
    }
    
    if(d->socketTimeout != d->ui->socketTimeoutSpinBox->value())
      scim::scim_global_config_write(
              SCIM_GLOBAL_CONFIG_DEFAULT_SOCKET_TIMEOUT, d->ui->socketTimeoutSpinBox->value());

    scim::scim_global_config_flush();

    load();
}

bool ScimGlobalConfigPlugin::checkLocales()
{
    bool changed = ((int)d->utf8Locales.size() != d->ui->unicodeLocaleCombo->count());
    if(!changed) {
      for(uint i = 0; i < d->utf8Locales.size(); i++)
        if(d->utf8Locales[i] != d->ui->unicodeLocaleCombo->text(i)) {
          changed = true;
          break;
        }
    }
    return changed;
}
#include "scimglobalconfigplugin.moc"
