/***************************************************************************
 *
 * vpn_tray_componenet.cpp - A NetworkManager frontend for TDE
 *
 * Copyright (C) 2005, 2006 Novell, Inc.
 *
 * Author: Helmut Schaa       <hschaa@suse.de>, <helmut.schaa@gmx.de>
 *
 * 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
 *
 **************************************************************************/

// TDE includes
#include <kdebug.h>
#include <tdelocale.h>
#include <kiconloader.h>
#include <knotifyclient.h>
#include <knotifydialog.h>

// TDENM includes
#include "vpn_tray_component.h"
#include "tdenetman-menuitem.h"
#include "tdenetman-menu_subhead.h"

#include "tdenetman-connection_settings_dialog.h"
#include <stdio.h>

extern unsigned int tdenetworkmanager_editor_dialog_count;

using namespace ConnectionSettings;

void VPNTrayComponent::slotShowNewConnectionDialog()
{
	TDEGlobalNetworkManager* nm = TDEGlobal::networkManager();
	if (!nm)
	{
		return;
	}

	// create a new VPN connection
	TDEVPNConnection* conn = new TDEVPNConnection();
	nm->loadConnectionAllowedValues(conn);

	// edit the new connection
	ConnectionSettingsDialogImpl* dlg = new ConnectionSettingsDialogImpl(conn, true, TQByteArray(), tray(), "connect_something", false, TQt::WDestructiveClose);
	dlg->show();
}


void VPNTrayComponent::addMenuItems(TDEPopupMenu* menu)
{
	int inactive_vpn_connections = 0;
	char vpn_found = 0;
	char any_vpn_found = 0;

	// Get all active connections
	TDEGlobalNetworkManager* nm = TDEGlobal::networkManager();
	if (!nm)
	{
		return;
	}

	if (tdenetworkmanager_editor_dialog_count == 0) nm->loadConnectionInformation();

	// get all available VPN Connections
	TQPopupMenu* popup = NULL;
	TDENetworkConnectionList* allconmap = nm->connections();
	for (TDENetworkConnectionList::Iterator it = allconmap->begin(); it != allconmap->end(); ++it) {
		TDEVPNConnection* conn = dynamic_cast<TDEVPNConnection*>(*it);
		if (!conn) {
			continue;
		}

		if (!popup) {
			popup = new TQPopupMenu(menu);
		}

		TQString title = conn->friendlyName;
	
		NetworkMenuItem* item = new NetworkMenuItem(NULL, conn->UUID, menu);

		vpn_found = 0;
		TDENetworkConnectionStatus::TDENetworkConnectionStatus connStatus = nm->checkConnectionStatus(conn->UUID);
		if ((connStatus & TDENetworkConnectionStatus::Connected)
			|| (connStatus & TDENetworkConnectionStatus::EstablishingLink)
			|| (connStatus & TDENetworkConnectionStatus::ConfiguringProtocols)
			|| (connStatus & TDENetworkConnectionStatus::Reconnecting)
			|| (connStatus & TDENetworkConnectionStatus::VerifyingProtocols)
			|| (connStatus & TDENetworkConnectionStatus::NeedAuthorization)
			|| (connStatus & TDENetworkConnectionStatus::DependencyWait)) {
			// This VPN connection is active!
			vpn_found = 1;
		}
		any_vpn_found = 1;

		if (vpn_found == 1) {
			printf("Active VPN connection found\n");
		}
		else {
			popup->insertItem(SmallIcon ("encrypted",  TQIconSet::Automatic), title, item, TQ_SLOT(slotActivate()));
			inactive_vpn_connections++;
		}

		//menu->setItemChecked(id, ((*it) == active_conn));
	}

	if (popup) {
		if (!any_vpn_found) {
			inactive_vpn_connections = 0;
		}

#if 0
		// FIXME
		// NetworkManager is rather stupid and won't let us activate a VPN connection if it doesn't manage the backend connection (!?!?!?)
		// When/if this limitation is removed, uncomment the following code block!
		TDENetworkGlobalManagerFlags::TDENetworkGlobalManagerFlags backendStatus = nm->backendStatus();
		if ((backendStatus & TDENetworkGlobalManagerFlags::Connected)
			|| (backendStatus & TDENetworkGlobalManagerFlags::LinkLocalAccess)
			|| (backendStatus & TDENetworkGlobalManagerFlags::SiteLocalAccess)
			|| (backendStatus & TDENetworkGlobalManagerFlags::GlobalAccess)) {
			// We have network access of some kind
		}
		else {
			inactive_vpn_connections = 0;
		}
#else
// 		TQStringList defaultNetworkDevices = nm->defaultNetworkDevices();
// 		if (defaultNetworkDevices.count() <= 0) {
// 			inactive_vpn_connections = 0;
// 		}

		// See if any connections are active
		bool found_any_active_connection = false;
		TDENetworkConnectionList* allconmap = nm->connections();
		for (TDENetworkConnectionList::Iterator it = allconmap->begin(); it != allconmap->end(); ++it) {
			TDENetworkConnection* conn = (*it);
	
			if (!conn) {
				continue;
			}
	
			if ((nm->checkConnectionStatus(conn->UUID) & TDENetworkConnectionStatus::Disconnected)
				|| (nm->checkConnectionStatus(conn->UUID) & TDENetworkConnectionStatus::Invalid)) {
				continue;
			}
	
			// Found an active connection
			found_any_active_connection = true;
		}

		if (!found_any_active_connection) {
			inactive_vpn_connections = 0;
		}
#endif
		if (inactive_vpn_connections > 0) {
			menu->insertItem(SmallIcon ("encrypted",  TQIconSet::Automatic), i18n("Start VPN connection"), popup);
			menu->insertSeparator();
		}
	}
}

void VPNTrayComponent::vpnEventHandler(TDENetworkVPNEventType::TDENetworkVPNEventType event, TQString message) {
	kdDebug() << "Tray::vpnEventHandler" << endl;

	if (event == TDENetworkVPNEventType::Failure) {
		KNotifyClient::event( tray()->winId(), "tdenm-nm-vpn-connection-attempt-failed", i18n(message.utf8()) );
	}
}

VPNTrayComponent::VPNTrayComponent (KSystemTray * parent, const char * name )
	: TrayComponent (parent, name)
{
	TDEGlobalNetworkManager* nm = TDEGlobal::networkManager();

	// Monitor VPN messages
	connect(nm, TQ_SIGNAL(vpnEvent(TDENetworkVPNEventType::TDENetworkVPNEventType, TQString)), this, TQ_SLOT(vpnEventHandler(TDENetworkVPNEventType::TDENetworkVPNEventType, TQString)));

	//Actions used for plugging into the menu
	new TDEAction (i18n ("New connection ..."),
					     SmallIcon ("encrypted",  TQIconSet::Automatic), 0,
					     this, TQ_SLOT (slotShowNewConnectionDialog()), parent->actionCollection (), "create_new_vpn_connection");
}

VPNTrayComponent::~VPNTrayComponent ()
{

}


#include "vpn_tray_component.moc"
