/***************************************************************************
 *   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
#include "src/skimpluginmanager.h"
#include "mainwindow.h"

#include <qlayout.h>
#include <qevent.h>
#include <qtoolbutton.h>
#include <qpopupmenu.h>
#include <ktoolbar.h>
#include <kxmlguifactory.h>

#include "utils/scimtoolbar.h"
#include "utils/scimmovehandle.h"
#include "src/skimglobalactions.h"
#include "utils/scimxmlguibuilder.cpp"
#include "utils/scimactions.h"

// #include <ostream>
MainWindow::MainWindow( SkimPluginManager* is, QWidget* parent, const char* name, WFlags fl )
: ScimDragableFrame( parent, parent, name, fl ), ScimXMLGUIClient(is->getActionCollection())
, PanelTurnedOn( false ) {
    allModules = is;
    InputServer = allModules->getInputServer();
    ScimXMLGUIBuilder* guiBuilder = new ScimXMLGUIBuilder(this);
    guiFactory = new KXMLGUIFactory(guiBuilder, this);

    if ( !name )
        setName( i18n("Main Window") );
    setLineWidth(1);
    setMidLineWidth(0);
    setFrameStyle( QFrame::Box | QFrame::Sunken );

    serverAction = 
      dynamic_cast<ScimAction *>(allModules->getActionCollection()->action( "change_server" ));

    MainWindowLayout = new QHBoxLayout( this, 3, 0, "MainWindowLayout");

    moveHandle = new ScimMoveHandle( this, this );
    moveHandle->setKeepVisible( false );
    MainWindowLayout->addWidget( moveHandle );

    contextMenu = new QPopupMenu(this, "MainToolBar_RightClickMenu");

    createToolbar ();

    defaultActionCollection = allModules->getActionCollection();

    KToggleAction* StickAction =
        dynamic_cast<KToggleAction*>(allModules->getActionCollection()->action( "stick_inputwindow" ));
    if(StickAction)
        StickAction->plug(contextMenu);

//     QIconSet::setIconSize( QIconSet::Small, QSize( fontMetrics().height(), fontMetrics().height() ) );


    KAction* action = defaultActionCollection->action( "configure" );
    if(action)
        action->plug(contextMenu);

    KAction* helpAction = defaultActionCollection->action( "help" );
    if(helpAction)
        helpAction->plug(contextMenu);

    languageChange();

    clearWState( WState_Polished );

    connect( InputServer, SIGNAL( turnOnPanelReq() ), this, SLOT( show() ) );

    move( ScimKdeSettings::mainWindow_POS_X(), ScimKdeSettings::mainWindow_POS_Y());

    changeSetting();
    
    if( AlwaysShow && AutoHideTimeout > 0 ) {
        AutoHideTimeoutTimer = new QTimer(this);
        connect( AutoHideTimeoutTimer, SIGNAL( timeout() ), this, SLOT( hide() ) );
    } else {
        AutoHideTimeoutTimer = 0;
        connect( InputServer, SIGNAL( turnOffPanelReq() ), this, SLOT( hide() ) );
    }

    #if ENABLE_DEBUG
    KAction * reloadaction = new KAction( KGuiItem( i18n( "Reload" ), "reload" ),
                 "", this, SLOT(requestReloadSelf()), defaultActionCollection, "reload_wm");
    reloadaction->plug(toolbar);
    #endif

    connect(defaultActionCollection, SIGNAL(propertiesRegistered()), SLOT(updateFrontendProperties ()));
    connect(defaultActionCollection, SIGNAL(propertyChanged()), SLOT(updateFrontendProperties ()));
    
    #if ENABLE_DEBUG
    show();
    #endif
}

MainWindow::~MainWindow() {
    ScimKdeSettings::setMainWindow_POS_X(x());
    ScimKdeSettings::setMainWindow_POS_Y(y());
    ScimKdeSettings::writeConfig();
//     std::cout << "Successfully exited.\n" << pos().x() << " " <<pos().y()  << "\n";
}

void MainWindow::createToolbar () {
      toolbar = new ScimToolBar( this, "MainToolBar" );
      toolbar->setEnableContextMenu(true);
      MainWindowLayout->addWidget( toolbar );
}

void MainWindow::updateFrontendProperties () {
    KActionPtrList exta = defaultActionCollection->propertyActions();
    if(exta.size()) {
      QPtrList<KAction> extaptr;
      for(uint i=0; i<exta.size(); i++) {
        bool visible = true;
        if(ScimAction * action = dynamic_cast<ScimAction *>(exta[i]))
          if(!action->visible() || !action->currentShown())
            visible = false;
        if(visible)
          extaptr.append(exta[i]);
      }
      if(extaptr != insertedActions) {
        insertedActions = extaptr;
        unplugActionList("Frontend Properties");
        plugActionList("Frontend Properties", insertedActions);
        //FIXME: ugly hack: at this point, the toolbar has not been changed,
        // so if call adjustSize here will take no effect
        // This is a work around although may be not feasible in some old/slow
        // or heavily loaded machines. IMPROVEMENT for this work around: implement
        // a check in adjustSize, if 100 ms is not long enough, just start 
        // another singleShot
        QTimer::singleShot( 100, this, SLOT( adjustSize() ) );
      }
    }
}

void MainWindow::requestReloadSelf () {
      setUpdatesEnabled( FALSE );
      guiFactory->removeClient(this);
      if(serverAction)
        serverAction->setOption(
          ScimKdeSettings::show_Factory_Text()? 
          scim_kde::ToolBarIconUseText : scim_kde::ToolBarPreferIcon);
      setXMLFile("mainwindowui.rc");
      setXMLGUIBuildDocument( QDomDocument() );
      guiFactory->addClient(this);
      insertedActions.clear();
      updateFrontendProperties ();
      setUpdatesEnabled( TRUE );
      adjustSize();
}

void MainWindow::adjustSize() {
    ScimDragableFrame::adjustSize();
    if(autoSnap && !mousePressed) {
        //     std::cout << "Successfully exited.\n" << screen.x() << " " <<screen.height()  << " " << x() << "\n";
        if(screen.width() - x() - width() < x())
            move(screen.width() - width(), y());
        else
            move(0, y());
    }
}
void MainWindow::contextMenuEvent ( QContextMenuEvent * e) {
    contextMenu->popup(e->globalPos());
}

void MainWindow::show() {
    if( AutoHideTimeoutTimer )
        AutoHideTimeoutTimer->start( AutoHideTimeout, true );
    QWidget::show();
    PanelTurnedOn = true;
}

void MainWindow::hide() {
    if( PanelTurnedOn ) {
        //         if( AutoHideTimeoutTimer && !AutoHideTimeoutTimer->isActive())
        //             toolbar->hide();
        //         else
        QWidget::hide();
    }
    //     serverListMenu->hide();
    PanelTurnedOn = false;
}

void MainWindow::languageChange() {}

void MainWindow::changeSetting() {
    AutoHideTimeout = ScimKdeSettings::hide_Timeout() * 1000;
    //FIXME
    AlwaysShow = false;//ScimKdeSettings::always_Show();
    autoSnap = ScimKdeSettings::auto_Snap();
    requestReloadSelf();
}

#include <kgenericfactory.h>
typedef KGenericFactory<MainWindowPlugin> MainWindowPluginFactory;

K_EXPORT_COMPONENT_FACTORY( skimplugin_mainwindow,
  MainWindowPluginFactory( "skimplugin_mainwindow" ) )
                              
MainWindowPlugin::MainWindowPlugin( QObject *parent, const char *name, const QStringList & /*args*/ )
 : SkimPlugin(MainWindowPluginFactory::instance(), parent, name)
{
     mainwindow = new MainWindow(static_cast<SkimPluginManager *>(parent), 0,0,
            Qt::WStyle_Customize|Qt::WStyle_NoBorder|Qt::WStyle_StaysOnTop|Qt::WX11BypassWM|Qt::WStyle_Tool );
     connect( this, SIGNAL(settingsChanged()), mainwindow, SLOT(changeSetting()));
}


MainWindowPlugin::~MainWindowPlugin()
{
    delete mainwindow;
}

#include "mainwindow.moc"

