/***************************************************************************
                          kbearsystemtraydock.cpp  -  description
                             -------------------
    begin                : mån maj 27 2002
    copyright            : (C) 2003 by Björn Sahlström
    email                : kbjorn@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.                                   *
 *                                                                         *
 ***************************************************************************/

//////////////////////////////////////////////////////
// Qt specific includes
#include <qtooltip.h>
#include <qapplication.h>
//////////////////////////////////////////////////////
// KDE specific includes
#include <klocale.h>
#include <kaction.h>
#include <kiconloader.h>
#include <kapplication.h>
#include "kpopupmenu.h"
#include <klocale.h>
#include <kconfig.h>
#include <kwin.h>
#include <kwinmodule.h>
#include <kparts/dockmainwindow.h>
#include <kiconloader.h>
#include <kdebug.h>
//////////////////////////////////////////////////////
// Application specific includes
#include "kbearsystemtraydock.h"
#include "kbearapi.h"
#include "kbearcore.h"
#include "transfermanager.h"

#ifndef Q_WS_QWS
#include <X11/Xlib.h>
const int XFocusOut = FocusOut;
const int XFocusIn = FocusIn;
#undef FocusOut
#undef FocusIn
#undef KeyPress
#undef KeyRelease
extern Time qt_x_time;
#endif

#include "kbearsystemtraydock.moc"

using namespace KBear;
//-----------------------------------------------
KBearSystemTrayDock::KBearSystemTrayDock( KBearAPI* api, QWidget* parent, const char* name )
	:	QLabel( parent,name,WType_TopLevel ),
		m_api( api )
{
#ifndef Q_WS_QWS
	KWin::setSystemTrayWindowFor( winId(), parent->topLevelWidget()->winId() );
	setBackgroundMode(X11ParentRelative);
#endif
	setPixmap( kapp->miniIcon() );
	m_menu = new KPopupMenu( this );
	move( -1000, -1000 );
	slotSetToolTip( 0, 0 );
}
//-----------------------------------------------
KBearSystemTrayDock::~KBearSystemTrayDock(){
}
//-----------------------------------------------
void KBearSystemTrayDock::enterEvent( QEvent* ) {
	slotSetToolTip( m_api->transferManager()->numOfActiveTransfers(), m_api->transferManager()->numOfQueuedTransfers() );
#ifndef Q_WS_QWS
	if ( !qApp->focusWidget() ) {
		XEvent ev;
		memset(&ev, 0, sizeof(ev));
		ev.xfocus.display = qt_xdisplay();
		ev.xfocus.type = XFocusIn;
		ev.xfocus.window = winId();
		ev.xfocus.mode = NotifyNormal;
		ev.xfocus.detail = NotifyAncestor;
		Time time = qt_x_time;
		qt_x_time = 1;
		qApp->x11ProcessEvent( &ev );
		qt_x_time = time;
	}
#endif
}
//-----------------------------------------------
void KBearSystemTrayDock::slotSetToolTip( int active, int queued ) {
	QString tooltip( i18n("Transfer status:\n%1 Active transfers\n%2 Queued transfers").arg(active,5).arg(queued,5) );
	QToolTip::remove( this );
	QToolTip::add( this, tooltip );
}
//-----------------------------------------------
void KBearSystemTrayDock::contextMenuAboutToShow() {
	m_menu->clear();
	m_menu->insertTitle( kapp->miniIcon(), kapp->caption() );
	m_menu->insertSeparator();
	m_api->core()->emitSystemTrayMenuNeeded( m_menu );
	if( m_menu->count() > 2 )
		m_menu->insertSeparator();
	if( parentWidget() ) {
		if( parentWidget()->isVisible() )
			m_menu->insertItem( i18n("Minimize"), this, SLOT( toggleMinimizeRestore() ) );
		else
			m_menu->insertItem( i18n("Restore"), this, SLOT( toggleMinimizeRestore() ) );
	}
	m_menu->insertSeparator();
	m_menu->insertItem(SmallIcon("exit"), i18n("&Quit"), parentWidget(), SLOT(close() ) );
}
//-----------------------------------------------
void KBearSystemTrayDock::mousePressEvent( QMouseEvent *e ) {
	if( ! rect().contains( e->pos() ) )
		return;

	switch ( e->button() ) {
		case LeftButton:
      	toggleMinimizeRestore();
			break;
		case MidButton:
			// fall through
		case RightButton:
			contextMenuAboutToShow();
			m_menu->popup( e->globalPos() );
			break;
		default:
			// nothing
			break;
	}
}
//-----------------------------------------------
void KBearSystemTrayDock::toggleMinimizeRestore() {
QWidget* pw = parentWidget();

	if( ! pw )
		return;

	KWin::Info info = KWin::info( pw->winId() );
	bool visible = (info.mappingState == NET::Visible);
	visible = visible && ( info.desktop == KWin::currentDesktop());
	if( visible && ( KWinModule().activeWindow() != pw->winId() )) {
		KWin::setActiveWindow( pw->winId() );
		return;
	}
	if( !visible ) {
#ifndef Q_WS_QWS //FIXME
		// TODO what to do with OnAllDesktops windows? (#32783)
		KWin::setOnDesktop( pw->winId(), KWin::currentDesktop());
		pw->move( info.geometry.topLeft() ); // avoid placement policies
		pw->show();
		KWin::setActiveWindow( pw->winId() );
#endif
	}
	else {
		pw->hide();
	}
}
//-----------------------------------------------
