/* 
 * This file is part of DesktopBSD, see the README file.
 *
 * Author: Peter Hofer <ph@desktopbsd.net>
 *         (C) 2004, 2005
 *
 * Copyright: BSD, see the COPYING file included in this distribution
 *
 */

#include <dbsdglobal.h>
#include <netinterface.h>
#include <wirelessinterface.h>
#include <ipv4netmask.h>
#include <executor.h>
#include <dialogs.h>
#include <pppconnectionmanager.h>
#include <dialogs.h>

/* Qt */
#include <qprocess.h>
#include <qpopupmenu.h>
#include <qapplication.h>

/* KDE */
#include <kpassivepopup.h>
#include <dcopclient.h>
#include <kapplication.h>

#include "nettray.h"

#define  DESKTOPBSDRC "/usr/X11R6/etc/settings/desktopbsdrc"

NetworkTray::NetworkTray() : DCOPObject(K_DCOP_OBJID)
{
	DCOPClient  *dcl = kapp->dcopClient();
	if(!dcl->isRegistered())
		dcl->registerAs(K_DCOP_OBJID);
	dcl->setDefaultObject(K_DCOP_OBJID);

	setIcon(getIcon());

	menu = new QPopupMenu();
	menu->insertItem(DBSDGlobal::getIconLoader()->loadIcon("configure", DBSDIconLoader::Size16x16),
	                          tr("Configure..."), this, SLOT(openConfigDlg()));

	QPopupMenu *pppmenu = new QPopupMenu(menu);
	pppmenu->insertItem(DBSDGlobal::getIconLoader()->loadIcon("connect_established", DBSDIconLoader::Size16x16), tr("Connect"), this, SLOT(openPPPConnection()));

	pppmenu->insertItem(DBSDGlobal::getIconLoader()->loadIcon("connect_creating", DBSDIconLoader::Size16x16), tr("Disconnect"), this, SLOT(closePPPConnection()));

	menu->insertItem(DBSDGlobal::getIconLoader()->loadIcon("connect_no", DBSDIconLoader::Size16x16), tr("DSL Connection"), pppmenu);
	menu->insertItem(DBSDGlobal::getIconLoader()->loadIcon("exit", DBSDIconLoader::Size16x16), tr("Quit"), qApp, SLOT(quit()));

	setPopup(menu);
}

NetworkTray::~NetworkTray()
{
	if (menu != NULL)
	{
		delete menu;
	}
}

void NetworkTray::linkStatusChanged(const QString & devname)
{
	NetInterface nic(devname);
	KPassivePopup::message(nic.getDesc(),
								  tr("Link status changed to <i>%1</i>.").arg(statusToStr(nic.getStatus())),
								  getIcon(),
								  winId());
}

void NetworkTray::addressChanged(const QString & devname)
{
	NetInterface nic(devname);
	IPv4Addr addr = nic.getIP();
	QString text;

	if(addr.isValid())
		text = tr("IP Address changed to <i>%1</i>.").arg(addr.toString());
	else
		text = tr("IP Address removed.");
	
	KPassivePopup::message(nic.getDesc(),
								  text,
								  getIcon(),
								  winId());
}

void NetworkTray::openPPPConnection()
{
	QString command = "egrep -q '^accountid=.+$' %1";

	// if there's already a connection configured
	if(Executor::exec(command.arg(DESKTOPBSDRC)) == Executor::NoError)
	{
		// Deletes the default router, sets the DNS servers and starts mpd
		Executor::exec("/usr/local/bin/kdesu '/sbin/route delete default; " 
							"fgrep -q \"customdnsenabled=true\" 	/usr/X11R6/etc/settings/desktopbsdrc && " 
							"sort /usr/X11R6/etc/settings/desktopbsdrc | "
							"sed -n " "\"s|[a-z]*dns=\\(.*\\)|nameserver \\1|p\" > /etc/resolv.conf; " +
							QString(MPD_RCSCRIPT_START) + "'");
	}
	else		// if there doesn't exist a connection
	{
		Dialogs::infoDlg(tr("You have to configure a connection first."));
	}
}

void NetworkTray::closePPPConnection()
{
	Executor::exec("/usr/local/bin/kdesu " + QString(MPD_RCSCRIPT_STOP));
}

void NetworkTray::mouseDoubleClickEvent(QMouseEvent *e) {
	if(e != NULL) {
		openConfigDlg();
	}
}

QPixmap  NetworkTray::getIcon() {
	return  DBSDGlobal::getIconLoader()->loadIcon("dbsd-nettray", DBSDIconLoader::Size22x22);
}

void  NetworkTray::openConfigDlg() {
	QProcess  process(QStringList::split(' ', "/usr/local/bin/kdesu /usr/local/bin/kcmshell dbsdnetworking"));
	if(!process.start())
		Dialogs::critDlg(tr("Cannot start DesktopBSD Networking configuration."));
}

QString  NetworkTray::statusToStr(NetInterface::Status  status) {
	switch(status) {
		case  NetInterface::Active:
		return  tr("Active");

		case  NetInterface::NoCarrier:
		return  tr("No Carrier");

		case  NetInterface::Associated:
		return  tr("Associated", "Wireless device associated to an access point");

		default:
		return  tr("(Error)");
	}
}


QString NetworkTray::toolTipRequested()
{
	QStringList tooltipStr;

	QPtrList<NetInterface>  ifList =  NetInterface::getIfs(true, false);
	NetInterface  *iface;
	for(iface = ifList.first(); iface != NULL; iface = ifList.next())
	{
		QString desc = iface->getDesc();
		if(desc.length() >= 28)
		{
			desc.truncate(28);
			desc += "...";
		}

		NetInterface::Status  status = iface->getStatus();
		tooltipStr << QString(tr("<b>%1</b><br>Status: <i>%2</i>%3"))
				.arg(desc)
				.arg(statusToStr(status))
				.arg((status == NetInterface::Active || status == NetInterface::Associated) ?
				tr("<br>%1IP Address: <i>%4</i><br>Netmask: <i>%5</i>")
				.arg(iface->isWireless() ? tr("Network (SSID): <i>%1</i><br>").arg(((WirelessInterface *) iface)->getSSID()) : "")
				.arg(iface->getIP().toString())
				.arg(iface->getNetmask().toString()) : "");
	}
	
	return tooltipStr.join("<br><br>");
}

