/***************************************************************************
 *   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.                                   *
 ***************************************************************************/
#define USE_SCIM_KDE_SETTINGS
#define Uses_SCIM_CONFIG_PATH
#include "src/skimpluginmanager.h"
#include "scimsetupwindow.h"

#include "src/skimglobalactions.h"

#include <sys/time.h>

#include <qlayout.h>
#include <klocale.h>
#include <kiconloader.h>
#include <kparts/componentfactory.h>
#include <kplugininfo.h>
#include <kcmoduleinfo.h> 

#include <ksettings/dispatcher.h>
#include <kgenericfactory.h>
#include <kapplication.h>

class ScimSetupWindowPrivate
{
public:
    scim::SocketServerThread *inputServer;
    bool scim_backend_need_update;
};

ScimSetupWindow::ScimSetupWindow(scim::SocketServerThread *parent, const char */*name*/, KConfigSkeleton */*config*/)
 : KCMultiDialog(KDialogBase::TreeList, i18n("Configure skim"), 0), d(new ScimSetupWindowPrivate)
{
    mc = SkimPluginManager::self();
    setIcon(KGlobal::iconLoader()->loadIcon("configure", KIcon::NoGroup));
    d->inputServer = parent;
    d->scim_backend_need_update = false;
    //setShowIconsInTreeList( true );
    connect( this, SIGNAL( configCommitted( const QCString & ) ),
      KSettings::Dispatcher::self(), SLOT( reparseConfiguration( const QCString & ) ) );
    connect( this, SIGNAL( configCommitted( const QCString & ) ), 
      SLOT(slotConfigurationChangedFor( const QCString & )));

    QValueList<KPluginInfo *> skimplugins = mc->availablePlugins();
    QValueList<KPluginInfo *>::ConstIterator pit;

    for ( pit = skimplugins.begin(); pit != skimplugins.end(); ++pit )
    {
        QStringList path;

        QValueList< KService::Ptr > services = 
          KTrader::self()->query( "Skim/KCModule", 
            "[X-KDE-PluginInfo-DisplayParent] == '" + (*pit)->pluginName() + "'" );

        if( services.size() > 1)
          path << (*pit)->name();
        for( QValueList<KService::Ptr>::ConstIterator it =
                services.begin();
                it != services.end(); ++it )
        {
//             if( !( *it )->noDisplay() )
            {
                KCModuleInfo moduleinfo( *it );
                addModule(moduleinfo, path);
            }
        }
    }
}

void ScimSetupWindow::hide()
{
    KCMultiDialog::hide();
    emit readyForUnload();
}

KActionCollection* ScimSetupWindow::actionCollection()
{
    return mc->getActionCollection();
}

ScimSetupWindow::~ScimSetupWindow()
{
}

void ScimSetupWindow::slotOk()
{
    KCMultiDialog::slotOk();
    slotApply();
}

void ScimSetupWindow::slotApply()
{
    kdDebug(18010) << "ScimSetupWindow::updateSettings()\n";

    KCMultiDialog::slotApply();

    {//update SCIM_CONFIG_UPDATE_TIMESTAMP to make config module emit "reload" signal
    timeval m_update_timestamp;
    gettimeofday (&m_update_timestamp, 0);

    char buf [128];
    snprintf (buf, 128, "%lu:%lu", m_update_timestamp.tv_sec, m_update_timestamp.tv_usec);
    
    ScimKdeSettings::self()->config()->writeEntry(QString::fromLatin1(SCIM_CONFIG_UPDATE_TIMESTAMP),
        QString::fromLatin1(buf));
    ScimKdeSettings::writeConfig();
//     ScimKdeSettings::self()->config()->sync();
    }

    if(d->scim_backend_need_update) {
      kapp->lock();
      d->inputServer->reloadScimConfig();
      kapp->unlock();
    }
    d->scim_backend_need_update = false;
}

void ScimSetupWindow::slotConfigurationChangedFor( const QCString & component)
{//TODO: the correctness of this slot behavior relys on the immediate invoke of 
 // slots in Qt3. Maybe need modification in Qt4
    if( component == "skimplugin_scim" )
        d->scim_backend_need_update = true;
}


typedef KGenericFactory<SkimConfigPlugin> SkimConfigPluginFactory;

K_EXPORT_COMPONENT_FACTORY( skimplugin_setupwindow,
  SkimConfigPluginFactory( "skimplugin_setupwindow" ) )

SkimConfigPlugin::SkimConfigPlugin( QObject *parent, const char *name, const QStringList & /*args*/ )
 : SkimPlugin(SkimConfigPluginFactory::instance(), parent, name)
{
     configdialog = new ScimSetupWindow(inputServer, 
       "SetupWindow", ScimKdeSettings::self());
     connect(configdialog, SIGNAL(readyForUnload()), this, SIGNAL(readyForUnload()));
}

void SkimConfigPlugin::SlotConfigure() {  configdialog->show(); }

SkimConfigPlugin::~SkimConfigPlugin()
{
    delete configdialog;
}

#include "scimsetupwindow.moc"
