#include "displayMgrMDI.h"
#include "toplevel.h"

#include <unistd.h>

#include <assert.h>
#include <tqpopupmenu.h>
#include <twin.h>
#include <tdeaccel.h>
#include <tdeaction.h>
#include <tdeapplication.h>
#include <tdelocale.h>
#include <kdebug.h>

#include <tdemenubar.h>

DisplayMgrMDI::DisplayMgrMDI()
{
}

DisplayMgrMDI::~DisplayMgrMDI()
{
  kdDebug(5008) << "~DisplayMgrMDI in" << endl;
    if ( m_topLevel )
      delete static_cast<MDITopLevel *>( m_topLevel );
  kdDebug(5008) << "~DisplayMgrMDI out" << endl;
}

#define DMM_MDI_ID 2351
#define DMM_DEATCH_ID 50
#define DMM_MOVEL_ID 51
#define DMM_MOVER_ID 52

void DisplayMgrMDI::newTopLevel( TQWidget *w, bool show )
{
    topLevel()->addWidget( w, show );
    if(w->inherits("KSircTopLevel")){
        KSircTopLevel *t = static_cast<KSircTopLevel *>(w);
        connect(m_topLevel->tabWidget(), TQ_SIGNAL(currentChanged(TQWidget *)), t, TQ_SLOT(focusChange(TQWidget *)));
    }
    if(w->inherits("TDEMainWindow")){
        TDEMainWindow *t = static_cast<TDEMainWindow *>(w);

        TQMenuBar *cmenu = t->menuBar();
        if(cmenu){
            TQPopupMenu *m = new TQPopupMenu(t, TQCString(t->name()) + "_popup_MDI");
            m->setCheckable(true);
            m->insertItem(i18n("Detach Window"), this, TQ_SLOT(reparentReq()), 0, DMM_DEATCH_ID, 0);
            m->insertSeparator(0);
            m->insertItem(i18n("Move Tab Left"), this, TQ_SLOT(moveWindowLeft()), ALT+SHIFT+Key_Left, DMM_MOVEL_ID, 0);
	    m->insertItem(i18n("Move Tab Right"), this, TQ_SLOT(moveWindowRight()), ALT+SHIFT+Key_Right, DMM_MOVER_ID, 0);
	    /*
	     * By using an posisiton of 4 this works for KSircTopLevel
	     * and DCCTopLevel but will cause problems when we have
             * new top level windows with different menus.
	     * BEWARE THIS IS BAD, we should have a better way of doing this
             */
            cmenu->insertItem(i18n("&Window"), m, DMM_MDI_ID, 4);
            cmenu->setAccel(Key_M, DMM_MDI_ID);

            TQPopupMenu *sm = new TQPopupMenu(t, "settings" );
	    
	    TDEToggleAction *showmenu = KStdAction::showMenubar( 0, 0, t->actionCollection() );
	    showmenu->plug( sm );
	    connect( showmenu, TQ_SIGNAL(toggled(bool)), cmenu, TQ_SLOT(setShown(bool)) );

	    TDESelectAction *selectTabbar = new TDESelectAction(i18n("&Tab Bar"), 0, this, "tabbar" );
	    TQStringList tabbaritems;
	    tabbaritems << i18n("&Top") << i18n("&Bottom");
	    selectTabbar->setItems(tabbaritems);
	    selectTabbar->setCurrentItem(1);
	    selectTabbar->plug( sm );
	    connect( selectTabbar, TQ_SIGNAL(activated(int)), this, TQ_SLOT(setTabPosition(int)) );

	    TDEToggleAction *showfull = KStdAction::fullScreen( 0, 0, t->actionCollection(), t );
	    showfull->plug( sm );
	    connect( showfull, TQ_SIGNAL(toggled(bool)), this, TQ_SLOT(setFullScreen(bool)) );

	    cmenu->insertItem( i18n("&Settings"), sm, -1, 5 );
        }
    }
    topLevel()->show();
}

void DisplayMgrMDI::removeTopLevel(TQWidget *w )
{
    if ( !m_topLevel )
        return;

    assert( w );

    kdDebug(5008) << "DisplayMgrMDI: got removeToplevel" << endl;

    m_topLevel->removeWidget( w );

    if ( m_topLevel->widgets().count() == 0 ) {
      kdDebug(5008) << "DisplayMgrMDI: count == 0 nuking all" << endl;
      if ( !m_topLevel->closing() ) {
	kdDebug(5008) << "DisplayMgrMDI: delete m_topLevel" << endl;
	delete static_cast<MDITopLevel *>( m_topLevel );
      }
      m_topLevel = 0;
    }
    else if(m_topLevel->tabWidget()->count() == 0){
        m_topLevel->hide();
    }
}

void DisplayMgrMDI::show(TQWidget *w)
{
    if ( !m_topLevel )
        return;

    m_topLevel->showWidget(w);
    m_topLevel->show();
}

void DisplayMgrMDI::hide(TQWidget *w)
{
    if ( !m_topLevel )
        return;

    m_topLevel->hideWidget(w);
    if(m_topLevel->tabWidget()->count() == 0){
        m_topLevel->hide();
    }
}

void DisplayMgrMDI::raise(TQWidget *w, bool takefocus)
{
    assert( m_topLevel );
    if(takefocus){
	KWin::setCurrentDesktop(KWin::KWin::windowInfo(m_topLevel->winId()).desktop());

	m_topLevel->show();
	m_topLevel->raise();
	m_topLevel->setActiveWindow();
#if KDE_IS_VERSION(3,1,92)
	KWin::activateWindow(m_topLevel->winId());
#else
	KWin::setActiveWindow(m_topLevel->winId());
#endif
    }
    m_topLevel->tabWidget()->showPage( w );
}


void DisplayMgrMDI::setCaption(TQWidget *w, const TQString& cap)
{
    assert( m_topLevel );

    w->setCaption(cap);

    TQString esc = cap;
    esc.replace("&", "&&");
    kdDebug(5008) << "Set caption: " << esc << endl;

    m_topLevel->tabWidget()->setTabLabel( w, esc );
}

void DisplayMgrMDI::slotCycleTabsLeft()
{

    assert( m_topLevel );

    m_topLevel->previous();
}

void DisplayMgrMDI::slotCycleTabsRight()
{

    assert( m_topLevel );

    m_topLevel->next();
}

void DisplayMgrMDI::reparentReq()
{
    kdDebug(5008) << "got reparent" << endl;

    TQWidget *o = kapp->focusWidget();
    TQWidget *s;

    if(o == NULL){
        kdDebug(5008) << "Kapp says no widget has focus!" << endl;
        o = kapp->activeWindow();

        if(o->inherits("TDEMainWindow") == false)
            return;

        s = o;
    }
    else {

        kdDebug(5008) << "TQWidget is: " << o->className() << " name: " << o->name("none give") << endl;


        s = o;
        while(s->parentWidget()){
            kdDebug(5008) << "Got a: " << s->className() << endl;
            s = s->parentWidget();
            if(s->inherits("TDEMainWindow"))
                break;

        }
    }


//    TQWidget *s = m_topLevel->tabWidget()->currentPage(); can't do this since you can never reattach
    if(s){
        TDEMainWindow *kst = static_cast<TDEMainWindow *>(s);
        kdDebug(5008) << "Top is: " << kst->name("none give") <<endl;

        TQMenuData *tmenu = kst->menuBar();
        if(tmenu){
            TQMenuItem *menui = tmenu->findItem(DMM_MDI_ID);
            if(menui){
                TQMenuData *cmenu = menui->popup();
                if(cmenu->findItem(DMM_DEATCH_ID) && cmenu->isItemChecked(DMM_DEATCH_ID)){
                    kst->reparent( topLevel()->tabWidget(), 0, TQPoint( 0, 0 ), true );
                    show(kst);
                    cmenu->setItemChecked(DMM_DEATCH_ID, false);
                }
                else {
                    hide(kst);
                    kst->reparent( 0, TQPoint(0,0), true );
                    cmenu->setItemChecked(DMM_DEATCH_ID, true);
                }
            }
        }
    }
}

MDITopLevel *DisplayMgrMDI::topLevel()
{
    if ( !m_topLevel )
    {
        m_topLevel = new MDITopLevel(0x0, "MDITopLevel");
        m_topLevel->show();

        TDEAccel *a = new TDEAccel( m_topLevel );
        a->insert( "cycle left", i18n("Cycle left"), TQString(), ALT+Key_Left, ALT+Key_Left, this, TQ_SLOT(slotCycleTabsLeft()) );
        a->insert( "cycle right", i18n("Cycle right"), TQString(), ALT+Key_Right, ALT+Key_Right, this, TQ_SLOT(slotCycleTabsRight()) );
    }

    return m_topLevel;
}

void DisplayMgrMDI::setTabPosition( int idx ) {

    switch ( idx ) {
	case 0:
	    m_topLevel->tabWidget()->setTabPosition(TQTabWidget::Top);
	    break;
	case 1:
	    m_topLevel->tabWidget()->setTabPosition(TQTabWidget::Bottom);
	    break;
    }
}


void DisplayMgrMDI::setFullScreen( bool full ) {
    if ( full )
	m_topLevel->showFullScreen();
    else
	m_topLevel->showNormal();
}



void DisplayMgrMDI::moveWindowLeft() {
    moveWindow(-1);
}

void DisplayMgrMDI::moveWindowRight() {
    moveWindow(1);
}

void DisplayMgrMDI::moveWindow(int step)
{
    if(m_topLevel->tabWidget()->count() == 0){
        return;
    }

    TQWidget *w = m_topLevel->tabWidget()->currentPage();
    if(w != 0x0){
        int index = m_topLevel->tabWidget()->currentPageIndex();
        index += step;
        if(index < 0)
            return;
        if(index >= m_topLevel->tabWidget()->count())
            return;

        m_topLevel->setUpdatesEnabled(false);
        m_topLevel->hideWidget(w);
	int space = w->caption().find(" ");
	TQString esc = space < 1 ? w->caption():w->caption().left(space);
	esc.replace("&", "&&");
	kdDebug(5008) << "Insert tab: " << esc << endl;
        m_topLevel->tabWidget()->insertTab( w, esc, index );
        m_topLevel->tabWidget()->showPage( w );
        m_topLevel->setUpdatesEnabled(true);
    }
}

#include "displayMgrMDI.moc"
