/***************************************************************************
 *
 * tdenetman-wireless_manager.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
 *
 **************************************************************************/

// other includes
#include <time.h>

// TDENM includes
#include "tdenetman-wireless_manager.h"

TQValueList<WirelessNetwork> WirelessManager::getWirelessNetworks(TDENetworkDevice* dev, TQ_UINT32 match)
{
	TQValueList<WirelessNetwork> nets;
	TQValueList<TDENetworkWiFiAPInfo*> aps;
	// fetch all APs
	aps = WirelessManager::getAccessPoints(dev);
	
	// now group the APs together according to their security settings
	for (TQValueList<TDENetworkWiFiAPInfo*>::Iterator apit = aps.begin(); apit != aps.end(); ++apit)
	{
		bool found = false;

		// no hidden APs
		TDENetworkWiFiAPInfo * ap = *apit;
		if ( ap ) {
			if (ap->SSID.count() == 0) {
				continue;
			}

			// check if we have a network matching this AP
			for (TQValueList<WirelessNetwork>::Iterator netIt = nets.begin(); netIt != nets.end(); ++netIt) {
				if ((*netIt).contains(ap->BSSID) ) {
					// we alread have a network where this AP belongs to
					found = true;

					// attach this ap to the network
					(*netIt).addAP(ap->BSSID, (dev)?dev->uniqueID():TQString::null);

					/*				// FIXME active?
									if (active_ap)
									{
					// here is the active_ap
					if (!(*net).getActive() && ((*ap) == *active_ap))
					(*net).setActive(true);
					}*/
					break;
				}
			}

			if (!found) {
				// create a new network-descriptor according to this ap
				WirelessNetwork net(match);
				net.addAP(ap->BSSID, (dev)?dev->uniqueID():TQString::null);
				nets.append(net);
			}
		}
	}
	return nets;
}

TQValueList<TDENetworkWiFiAPInfo*> internalGetAccessPoints(TDENetworkDevice* dev) {
	TQValueList<TDENetworkWiFiAPInfo*> list;
	if (dev) {
		TDENetworkConnectionManager* deviceConnMan = dev->connectionManager();
		if (deviceConnMan)
		{
			TDENetworkHWNeighbor* neighbor;
			TDENetworkHWNeighborList* neighbors = deviceConnMan->siteSurvey();
			for (neighbor = neighbors->first(); neighbor; neighbor = neighbors->next())
			{
				TDENetworkWiFiAPInfo* apInfo = dynamic_cast<TDENetworkWiFiAPInfo*>(neighbor);
				if (!apInfo)
				{
					continue;
				}
				list.append(apInfo);
			}
		}
	}
	return list;
}

TQValueList<TDENetworkWiFiAPInfo*> WirelessManager::getAccessPoints(TDENetworkDevice* dev)
{
	// build up AP list depending on one device or on all devices
	if (dev) {
		return internalGetAccessPoints(dev);
	}
	else {
		TQValueList<TDENetworkWiFiAPInfo *> aps;
		TDEHardwareDevices *hwdevices = TDEGlobal::hardwareDevices();
		if (hwdevices) {
			TDEGenericHardwareList devices = hwdevices->listByDeviceClass(TDEGenericDeviceType::Network);
			for (TDEGenericHardwareList::iterator it = devices.begin(); it != devices.end(); ++it) {
				TDENetworkDevice* wdev = dynamic_cast<TDENetworkDevice*>(*it);
				if (wdev) {
					aps += internalGetAccessPoints(wdev);
				}
			}
		}
		return aps;
	}
}

TQValueList<TDEWiFiConnection*> WirelessManager::getWirelessConnections()
{
	TQValueList<TDEWiFiConnection*> conns;

	TDEGlobalNetworkManager* nm = TDEGlobal::networkManager();
	if (nm) {
		// get all wireless connections
		TDENetworkConnectionList* allconmap = nm->connections();
		for (TDENetworkConnectionList::Iterator it = allconmap->begin(); it != allconmap->end(); ++it) {
			TDEWiFiConnection* wireless_conn = dynamic_cast<TDEWiFiConnection*>(*it);
			if (!wireless_conn) {
				continue;
			}
			conns.append(wireless_conn);
		}
	}

	return conns;
}

TQValueList<TDENetworkWiFiAPInfo*> internalGetAccessPointsWithESSID(TQByteArray essid, TDENetworkDevice* dev) {
	TQValueList<TDENetworkWiFiAPInfo*> list;
	if (dev) {
		TDENetworkConnectionManager* deviceConnMan = dev->connectionManager();
		if (deviceConnMan)
		{
			TDENetworkHWNeighbor* neighbor;
			TDENetworkHWNeighborList* neighbors = deviceConnMan->siteSurvey();
			for (neighbor = neighbors->first(); neighbor; neighbor = neighbors->next())
			{
				TDENetworkWiFiAPInfo* apInfo = dynamic_cast<TDENetworkWiFiAPInfo*>(neighbor);
				if (!apInfo)
				{
					continue;
				}
				if (apInfo->SSID == essid)
				{
					list.append(apInfo);
				}
			}
		}
	}
	return list;
}

TQValueList<TDENetworkWiFiAPInfo*> WirelessManager::getAccessPointsForEssid(TQByteArray essid, TDENetworkDevice* dev)
{
	// build up AP list depending on one device or on all devices
	if (dev) {
		return internalGetAccessPointsWithESSID(essid, dev);
	}
	else {
		TQValueList<TDENetworkWiFiAPInfo*> aps;
		TDEHardwareDevices *hwdevices = TDEGlobal::hardwareDevices();
		if (hwdevices) {
			TDEGenericHardwareList devices = hwdevices->listByDeviceClass(TDEGenericDeviceType::Network);
			for (TDEGenericHardwareList::iterator it = devices.begin(); it != devices.end(); ++it) {
				TDENetworkDevice* wdev = dynamic_cast<TDENetworkDevice*>(*it);
				if (wdev) {
					aps += internalGetAccessPointsWithESSID(essid, wdev);
				}
			}
		}
		return aps;
	}
}


