#include <tqguardedptr.h>

#include <tqtabbar.h>

#include <tdeapplication.h>
#include <kiconloader.h>
#include <tdeconfig.h>
#include <kdebug.h>
#include <tdepopupmenu.h>
#include <tdelocale.h>
#include <tdeaction.h>

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

#define ID_CLOSE 5

void KSTabWidget::mousePressEvent(TQMouseEvent *e)
{
    if(e->button() == TQt::RightButton){
        TQPoint p = tabBar()->mapFromParent(e->pos());
	TQTab *tab = tabBar()->selectTab(p);
	if(tab){
	    int id = tab->identifier();
            emit showContexMenu(page(id), tabBar()->mapToGlobal(p));
	}
    }
}

MDITopLevel::MDITopLevel(TQWidget *parent, const char *name)
    : TDEMainWindow(parent, name)
{
    m_closing = false;

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

    setCentralWidget( m_tab );

    connect( m_tab, TQ_SIGNAL( currentChanged( TQWidget * ) ),
             this, TQ_SLOT( slotCurrentChanged( TQWidget * ) ) );

    connect( m_tab, TQ_SIGNAL( showContexMenu(TQWidget *, const TQPoint &) ),
             this, TQ_SLOT( slotShowContexMenu(TQWidget *, const TQPoint &) ) );

    TDEConfig *config = tdeApp->config();
    config->setGroup("MDI");
    TQSize s( 600, 360 );
    resize(config->readSizeEntry( "TopLevelSize", &s ));

    m_dirtyIcon = UserIcon( "star" );
    m_addressedIcon = UserIcon( "application-vnd.tde.info" );

    m_pop = new TDEPopupMenu(m_tab, "");
    m_pop->insertItem( SmallIcon("window-close"), i18n("Close"), this, TQ_SLOT( slotCloseLastWid() ));

}

MDITopLevel::~MDITopLevel()
{
  kdDebug(5008) << "~MDITopLevel in" << endl;

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

    TQPtrListIterator<TQWidget> it( m_tabWidgets );
    for (; it.current(); ++it )
        it.current()->disconnect( this, 0 );
  kdDebug(5008) << "~MDITopLevel out" << endl;

}

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

    kdDebug(5008) << "In add widget" << endl;

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

    if(show == TRUE){
        showWidget(widget);
    }

    m_tabWidgets.append( widget );

    connect( widget, TQ_SIGNAL( destroyed() ) ,
             this, TQ_SLOT( slotWidgetDestroyed() ) );

    connect( widget, TQ_SIGNAL( changeChannel( const TQString &, const TQString & ) ),
             this, TQ_SLOT( slotChangeChannelName( const TQString &, const TQString & ) ) );

    widget->installEventFilter( this );

    connect( widget, TQ_SIGNAL( changed( bool, TQString ) ),
             this, TQ_SLOT( slotMarkPageDirty( bool ) ) );
}

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

void MDITopLevel::hideWidget( TQWidget *widget )
{
    m_tab->removePage( widget );
    widget->hide();
}

void MDITopLevel::showWidget( TQWidget *widget )
{
    if(m_tab->indexOf(widget) == -1){
        int space = widget->caption().find(" ");
        TQString cap = space < 1 ? widget->caption():widget->caption().left(space);
        m_tab->addTab( widget,  cap);
        m_tab->showPage( widget );
        m_tab->setCurrentPage( m_tab->indexOf(widget) );
    }
}

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( TQCloseEvent *ev )
{
    m_closing = true;
    // Don't use iterators on a list while deleting elements
    // from it (Antonio)
    int i = 0;
    kdDebug(5008) << "Mdi got close event " << endl;
    while ( m_tabWidgets.count() && (i++ < 100000)) {
        kdDebug(5008) << "MDITopLevel trying to close: " << m_tabWidgets.first()->name() << endl;
        TQGuardedPtr<TQWidget> w = m_tabWidgets.take(0);
        w->show();
        w->close( false );
        if(w)
            delete (TQWidget *)w;
    }

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

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

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

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

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

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

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

    return false;
}

void MDITopLevel::slotCurrentChanged( TQWidget *page )
{

    m_tab->setTabIconSet( page, TQIconSet() );
    removeFromAddressedList( page );

    setPlainCaption( page->TQWidget::caption() );

    KSircTopLevel *kst = dynamic_cast<KSircTopLevel *>( page );
    if ( !kst )
        return;
    kst->lineEdit()->setFocus();
}

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
    TDEMainWindow *window = dynamic_cast<TDEMainWindow *>( const_cast<TQObject*>( sender() ) );

    if ( !window )
        return;

    if ( window != m_tab->currentPage() )
    {
        if ( m_addressed.containsRef( window ) )
            addressed = true;
        else if ( addressed ) {
            m_addressed.append( window );
        }
        m_tab->setTabIconSet( window, addressed ? m_addressedIcon : m_dirtyIcon );
    }
}

void MDITopLevel::slotChangeChannelName( const TQString &, const TQString &channelName )
{
    TDEMainWindow *window = dynamic_cast<TDEMainWindow *>( const_cast<TQObject*>( sender() ) );

    if ( !window )
        return;

    TQString esc = channelName;
    esc.replace("&", "&&");
    m_tab->setTabLabel( window, esc );
    removeFromAddressedList( window );
}

void MDITopLevel::removeFromAddressedList( const TQWidget* 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).
    m_addressed.removeRef( w );
}

void MDITopLevel::slotShowContexMenu(TQWidget *w, const TQPoint &p)
{
    m_last_pop_wid = w;
    m_pop->popup(p);
}

void MDITopLevel::slotCloseLastWid()
{
	m_last_pop_wid->close();

}

#include "mditoplevel.moc"