

#include <kapplication.h>
#include <kiconloader.h>
#include <kconfig.h>

#include "mditoplevel.h"
#include "toplevel.h"
#include "servercontroller.h"

MDITopLevel::MDITopLevel()
{
    m_closing = false;

    m_tab = new QTabWidget( this );
    m_tab->setTabPosition( QTabWidget::Bottom );

    setCentralWidget( m_tab );

    connect( m_tab, SIGNAL( currentChanged( QWidget * ) ),
             this, SLOT( slotCurrentChanged( QWidget * ) ) );

    KConfig *config = kapp->config();
    config->setGroup("MDI");
    QSize s( 600, 360 );
    resize(config->readSizeEntry( "TopLevelSize", &s ));

    m_dirtyIcon = UserIcon( "star" );
    m_addressedIcon = UserIcon( "info" );
}

MDITopLevel::~MDITopLevel()
{

    KConfig *config = kapp->config();
    config->setGroup( "MDI" );
    config->writeEntry( "TopLevelSize", this->size() );
    config->sync();

    QPtrListIterator<QWidget> it( m_tabWidgets );
    for (; it.current(); ++it )
        it.current()->disconnect( this, 0 );
}

void MDITopLevel::addWidget( QWidget *widget, bool show )
{
    if ( m_tabWidgets.containsRef( widget ) )
        return;

    widget->reparent( m_tab, 0, QPoint( 0, 0 ), show );

    int space = widget->caption().find(" ");
    m_tab->addTab( widget, space < 1 ? widget->caption():widget->caption().left(space) );
    m_tab->showPage( widget );

    m_tabWidgets.append( widget );

    connect( widget, SIGNAL( destroyed() ) ,
             this, SLOT( slotWidgetDestroyed() ) );

    connect( widget, SIGNAL( changeChannel( const QString &, const QString & ) ),
             this, SLOT( slotChangeChannelName( const QString &, const QString & ) ) );

    widget->installEventFilter( this );

    connect( widget, SIGNAL( changed( bool ) ),
             this, SLOT( slotMarkPageDirty( bool ) ) );
}

void MDITopLevel::removeWidget( QWidget *widget )
{
    if (m_closing)
        return;
    m_tabWidgets.removeRef( widget );
    removeFromAddressedList( widget );
    m_tab->removePage( widget );
    widget->removeEventFilter( this );
    widget->disconnect( this, 0 );
}

void MDITopLevel::next()
{
	if (m_tab->currentPageIndex() < m_tab->count() - 1)
		m_tab->setCurrentPage(m_tab->currentPageIndex() + 1);
	else
		m_tab->setCurrentPage(0);
}

void MDITopLevel::previous()
{
	if (m_tab->currentPageIndex() > 0)
		m_tab->setCurrentPage(m_tab->currentPageIndex() - 1);
	else
		m_tab->setCurrentPage(m_tab->count() - 1);
}

void MDITopLevel::closeEvent( QCloseEvent *ev )
{
    m_closing = true;
    // Don't use iterators on a list while deleting elements
    // from it (Antonio)
    while ( m_tabWidgets.count() ) {
        m_tabWidgets.first()->show();
        m_tabWidgets.first()->close( false );
    }

    KMainWindow::closeEvent( ev );
    m_closing = false;
}

void MDITopLevel::slotWidgetDestroyed()
{
    const QWidget *widget = static_cast<const QWidget *>( sender() );

    m_tabWidgets.removeRef( widget );
    removeFromAddressedList( widget );
}

bool MDITopLevel::eventFilter( QObject *obj, QEvent *ev )
{
    if ( ev->type() != QEvent::CaptionChange )
        return false;

    QWidget *widget = dynamic_cast<QWidget *>( obj );

    if ( !widget || !m_tabWidgets.containsRef( widget ) )
        return false;

    if ( m_tab->currentPage() == widget )
        setPlainCaption( widget->caption() );

    return false;
}

void MDITopLevel::slotCurrentChanged( QWidget *page )
{
    KSircTopLevel *window = dynamic_cast<KSircTopLevel *>( page );

    if ( !window )
        return;

    m_tab->setTabIconSet( window, QIconSet() );
    removeFromAddressedList( window );

    window->lineEdit()->setFocus();
    setPlainCaption( window->QWidget::caption() );
}

void MDITopLevel::slotMarkPageDirty( bool addressed )
{
    // This is called when a line appeared in this channel.
    // addressed is true if it was addressed to the user
    KSircTopLevel *window = dynamic_cast<KSircTopLevel *>( const_cast<QObject *>( sender() ) );

    if ( !window )
        return;

    if ( window != m_tab->currentPage() )
    {
        if ( m_addressed.containsRef( window ) )
            addressed = true;
        else if ( addressed ) {
            m_addressed.append( window );
            // Change docked icon
            servercontroller::self()->increaseNotificationCount();
        }
        m_tab->setTabIconSet( window, addressed ? m_addressedIcon : m_dirtyIcon );
    }
}

void MDITopLevel::slotChangeChannelName( const QString &, const QString &channelName )
{
    KSircTopLevel *window = dynamic_cast<KSircTopLevel *>( const_cast<QObject *>( sender() ) );

    if ( !window )
        return;

    m_tab->setTabLabel( window, channelName );
    removeFromAddressedList( window );
}

void MDITopLevel::removeFromAddressedList( const QWidget* w )
{
    // If this tab was showing a "you're being talked to" icon, remove it
    // and tell the servercontroller (so that it can update the docked icon).
    if ( m_addressed.removeRef( w ) )
        servercontroller::self()->decreaseNotificationCount();
}

#include "mditoplevel.moc"

// vim: ts=4 sw=4 et
