/***************************************************************************
 *   Copyright (C) 2005 by Raul Moratalla                                  *
 *   raul.moratalla@ono.com                                                *
 *                                                                         *
 *   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.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/
// Portions of this code are from KStart

#include "firefoxqs.h"

#include <fcntl.h>
#include <stdlib.h>


#include <kaboutdata.h>
#include <kaction.h>
#include <kapp.h>

#include <kglobal.h>
#include <khelpmenu.h>
#include <kiconloader.h>
#include <klocale.h>
#include <kpopupmenu.h>
#include <kprocess.h>
#include <ksimpleconfig.h>
#include <kwin.h>
#include <kwinmodule.h>
#include <kstartupinfo.h>
#include <kapplication.h>
#include <netwm.h>

#include <kstartupinfo.h>


static unsigned long state = 0;
static KWinModule* kwinmodule;
KProcess hide_instance;

FirefoxQs::FirefoxQs()
		: KSystemTray( 0, "firefox" )
{
	kwinmodule = new KWinModule;
	// connect to window add to get the firefox window
	connect(kwinmodule, SIGNAL(windowAdded(WId)), SLOT(hideFirefox(WId)));
	
	//Hide the first window that appears on screen with title Mozilla Firefox
	kwinmodule->doNotManage( "Mozilla Firefox" );
	fcntl(ConnectionNumber(qt_xdisplay()), F_SETFD, 1);
	
	
	KStartupInfoId id;
	id.initId( kapp->startupId());
	id.setupStartupEnv();

	hide_instance << "firefox";
	hide_instance.start(KProcess::DontCare);

	_config = KGlobal::config();

	//Set up the menu
	KPopupMenu* menu = contextMenu();

	( new KAction( i18n( "New navigator window" ),
	               "firefoxqs", 0, this,
	               SLOT( startWebBrowser() ), this ) ) ->plug( menu );


	menu->insertSeparator();

	_autostart = new KToggleAction(
	                 i18n( "Start automatically with KDE" ), 0,
	                 this, SLOT( toggleAutostart() ), this );
	_autostart->plug( menu );

	KHelpMenu* tempMenu =  new KHelpMenu( this, kapp->aboutData(), false );
	KPopupMenu* helpMenu = tempMenu->menu();

	menu->insertItem( i18n( "&Help" ), helpMenu );

	_config->setGroup( "General" );
	_autostart->setChecked( _config->readBoolEntry( "Autostart", true ) );
}

FirefoxQs::~FirefoxQs()
{
	if (hide_instance.isRunning())
		hide_instance.kill(SIGTERM); //kill the hidden window of firefox
}

//variable param is not used. In a future versio I should cleanup code and made some enhancements.
void FirefoxQs::start(const QString param) const
{
	KProcess process;
	process<<"firefox";
	//process<<param;
	process.start( KProcess::DontCare );
}
void FirefoxQs::startWebBrowser( void ) const
{
	start( "about:blank" );
}


void FirefoxQs::mousePressEvent( QMouseEvent* event )
{
	KSystemTray::mousePressEvent( event );
	if (event->button() == LeftButton)
	{
		startWebBrowser();
	}
}

void FirefoxQs::toggleAutostart( void )
{
	_config->setGroup( "General" );
	_config->writeEntry( "Autostart", _autostart->isChecked() );
	_config->sync();
}

//This function is from kstart
extern Atom qt_wm_state; // defined in qapplication_x11.cpp
static bool wstate_withdrawn( WId winid )
{
	Atom type;
	int format;
	unsigned long length, after;
	unsigned char *data;
	int r = XGetWindowProperty( qt_xdisplay(), winid, qt_wm_state, 0, 2,
	                            FALSE, AnyPropertyType, &type, &format,
	                            &length, &after, &data );
	bool withdrawn = TRUE;
	if ( r == Success && data && format == 32 )
	{
		Q_UINT32 *wstate = (Q_UINT32*)data;
		withdrawn  = (*wstate == WithdrawnState );
		XFree( (char *)data );
	}
	return withdrawn;
}

//This function hides firefox and refresh the desktop
void FirefoxQs::hideFirefox(WId w )
{

	XWithdrawWindow(qt_xdisplay(), w, qt_xscreen());
QApplication::flushX();
	while ( !wstate_withdrawn(w) );

	NETWinInfo info( qt_xdisplay(), w, qt_xrootwin(), NET::WMState );

	XWMHints * hints = XGetWMHints(qt_xdisplay(), w );
	if (hints)
	{
		hints->flags |= StateHint;
		hints->initial_state = IconicState;
		XSetWMHints( qt_xdisplay(), w, hints );
		XFree(hints);
	}

	state |= NET::SkipTaskbar;
	KWin::iconifyWindow(w);
	KWin::setState(w,state);

	kwinmodule->disconnect();
	setPixmap(loadIcon("firefoxqs"));
	QApplication::flushX();
}

#include "firefoxqs.moc"
