/***************************************************************************
 *   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 <kpopupmenu.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 ), updatePropertiesNeeded(false) {
    allModules = is;
    InputServer = allModules->getInputServer();
    ScimXMLGUIBuilder* guiBuilder = new ScimXMLGUIBuilder(this);
    guiFactory = new KXMLGUIFactory(guiBuilder, this);

    if ( !name )
        setName( i18n("Main Window") );

    setFrameStyle( QFrame::StyledPanel | QFrame::Raised );

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

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

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

    //FIXME:qpopupmenu will steal focus from current editing widget, however 
    //kpopupmenu won't. this should be a bug in Qt
    contextMenu = new KPopupMenu(this, "MainToolBar_RightClickMenu");
 
    createToolbar ();
    
    defaultActionCollection = allModules->getActionCollection();

    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;
    //we should remove the old one first if exist
    if(reloadaction = defaultActionCollection->action( "reload_wm" ))
        delete reloadaction;

    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

    connect(allModules->getActionCollection(), SIGNAL(standaloneHelperActionsChanged()),
        this, SLOT(initContextMenu()));
    initContextMenu();
}

MainWindow::~MainWindow() {
    ScimKdeSettings::setMainWindow_POS_X(x());
    ScimKdeSettings::setMainWindow_POS_Y(y());
    ScimKdeSettings::writeConfig();
    contextMenu->clear();
}

void MainWindow::initContextMenu() {
    contextMenu->clear();
    //load helper actions (copied from kdetraystatus.cpp, with slight modification)
    KActionCollection * helperActioncol = defaultActionCollection->helperActionCollection();
    if ( helperActioncol->count() ) {
        for(size_t i=0; i<helperActioncol->count();i++) {
            helperActioncol->action(i)->plug(contextMenu);
        }
        contextMenu->insertSeparator();
    }
    KToggleAction* StickAction =
        dynamic_cast<KToggleAction*>(allModules->getActionCollection()->action( "stick_inputwindow" ));
    if(StickAction)
        StickAction->plug(contextMenu);

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

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

void MainWindow::createToolbar () {
      toolbar = new ScimToolBar( this, "MainToolBar" );
      toolbar->setIconSize(fontMetrics().height() + 2);
      toolbar->setEnableContextMenu(true);
      toolbar->setFrameStyle( QFrame::NoFrame );
      MainWindowLayout->addWidget( toolbar );
}

void MainWindow::updateFrontendProperties () {
    KActionPtrList exta = defaultActionCollection->propertyActions();

    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) {
        updatePropertiesNeeded = true;
        insertedActions = extaptr;
        unplugActionList("Frontend Properties");
    }

    if(updatePropertiesNeeded && PanelTurnedOn)
        show();
}

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 );
    if (updatePropertiesNeeded) {
        plugActionList("Frontend Properties", insertedActions);
        updatePropertiesNeeded=false;
        //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() ) );
    }
    QWidget::show();

    //adjustSize immediately is not useful here, so we schedule
    //an adjustSize after all the events in the queue are processed
    QTimer::singleShot( 0, this, SLOT( adjustSize() ) );

    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::WX11BypassWM | Qt::WStyle_StaysOnTop);
     connect( this, SIGNAL(settingsChanged()), mainwindow, SLOT(changeSetting()));
}


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

#include "mainwindow.moc"

