/***************************************************************************
 *
 * knetworkmanager-accesspoint.cpp - A NetworkManager frontend for KDE 
 *
 * 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
 *
 **************************************************************************/

// Qt
#include <qguardedptr.h>

// QDBus includes
#include <dbus/qdbuserror.h>
#include <dbus/qdbusconnection.h>
#include <dbus/qdbuserror.h>

// NM includes
#include <NetworkManager.h>

// KNM includes
#include "knetworkmanager.h"
#include "knetworkmanager-accesspoint.h"
#include "dbus/accesspointproxy.h"

class AccessPointPrivate
{
public:
	AccessPointPrivate(QString objpath = QString::null, const DBus::AccessPointProxy* proxy = NULL)
		: nmAccessPoint(proxy)
		, objPath(objpath)
	{
	}

	~AccessPointPrivate() { }

	// pointer to the shared DBus proxy
	QGuardedPtr<const DBus::AccessPointProxy> nmAccessPoint;
	// DBus object path
	QString objPath;

	// Properties
	Q_UINT32 flags;
	Q_UINT32 wpaFlags;
	Q_UINT32 rsnFlags;
	QValueList<Q_UINT8> ssid;
	Q_UINT32 freq;
	QString  hwAddress;
	Q_INT32  mode;
	Q_UINT32 rate;
	Q_UINT8  strength;
};

Q_UINT32 AccessPoint::getFlags() const
{
	return d->flags;
}

Q_UINT32 AccessPoint::getWpaFlags() const
{
	return d->wpaFlags;
}

Q_UINT32 AccessPoint::getRsnFlags() const
{
	return d->rsnFlags;
}

QValueList<Q_UINT8> AccessPoint::getSsid() const
{
	return d->ssid;
}

Q_UINT32 AccessPoint::getFrequency() const
{
	return d->freq;
}

QString AccessPoint::getHwAddress() const
{
	return d->hwAddress;
}

Q_INT32 AccessPoint::getMode() const
{
	return d->mode;
}

Q_UINT32 AccessPoint::getRate() const
{
	return d->rate;
}

Q_UINT8 AccessPoint::getStrength() const
{
	return d->strength;
}

const QByteArray AccessPoint::getSsidByteArray() const
{
	// FIXME: Wow, thats ugly
	QValueList<Q_UINT8> ssid = d->ssid;
	QByteArray ret_ssid(ssid.count());
	QByteArray::Iterator byteit = ret_ssid.begin();
	for (QValueList<Q_UINT8>::iterator it = ssid.begin(); it != ssid.end(); ++it)
	{
		(*byteit) = (*it);
		++byteit;
	}
	return ret_ssid;
}

QString AccessPoint::getDisplaySsid() const
{
	return QString(getSsidByteArray());
}

bool AccessPoint::isEncrypted() const
{
	return (getFlags() && NM_802_11_AP_FLAGS_PRIVACY);
}

void AccessPoint::slotPropertiesChanged(const QMap<QString, QDBusVariant>& properties)
{
	updateProperties();
}

void AccessPoint::updateProperties()
{
	//TODO do this proper-like
	QDBusError err;
	if (d->nmAccessPoint.isNull())
		return;

	d->flags = d->nmAccessPoint->getFlags(err);
	d->wpaFlags = d->nmAccessPoint->getWpaFlags(err);
	d->rsnFlags = d->nmAccessPoint->getRsnFlags(err);
	d->ssid = d->nmAccessPoint->getSsid(err);
	d->freq = d->nmAccessPoint->getFrequency(err);
	d->hwAddress = d->nmAccessPoint->getHwAddress(err);
	d->mode = d->nmAccessPoint->getMode(err);
	d->rate = d->nmAccessPoint->getMaxBitrate(err);
	d->strength = d->nmAccessPoint->getStrength(err);
	emit strengthChanged(d->strength);
}

QString AccessPoint::getObjectPath() const
{
	return d->objPath;
}

bool AccessPoint::isValid() const
{
	return !(d->objPath.isEmpty());
}

bool AccessPoint::operator== (const AccessPoint& other) const
{
	return (other.getObjectPath() == getObjectPath());
}
#if 0
AccessPoint& AccessPoint::operator= (const AccessPoint& other)
{
	kdDebug() << "AccessPoint::operator=\n" << endl;
	d->objPath = other.d->objPath;
	d->nmAccessPoint = other.d->nmAccessPoint;
	connect(d->nmAccessPoint, SIGNAL(PropertiesChanged(const QMap<QString, QDBusVariant>&)), this, SLOT(slotPropertiesChanged(const QMap<QString, QDBusVariant>&)));

	updateProperties();

	return *this;
}
#endif
AccessPoint::AccessPoint(QString obj_path, QObject * parent, const char * name)
: QObject(parent, name)
{
	DBus::AccessPointProxy * proxy = new DBus::AccessPointProxy(NM_DBUS_SERVICE, obj_path);
	proxy->setConnection(QDBusConnection::systemBus());
	d = new AccessPointPrivate(obj_path, proxy);

	if (!d->nmAccessPoint.isNull())
		connect(d->nmAccessPoint, SIGNAL(PropertiesChanged(const QMap<QString, QDBusVariant>&)), this, SLOT(slotPropertiesChanged(const QMap<QString, QDBusVariant>&)));

	updateProperties();
}
#if 0
// copy constructor
AccessPoint::AccessPoint(const AccessPoint& other)
	: QObject()
{
	// just copy the private data from other
	d = new AccessPointPrivate(*other.d);

	if (!d->nmAccessPoint.isNull())
		connect(d->nmAccessPoint, SIGNAL(PropertiesChanged(const QMap<QString, QDBusVariant>&)), this, SLOT(slotPropertiesChanged(const QMap<QString, QDBusVariant>&)));

	updateProperties();
}
#endif
AccessPoint::~AccessPoint()
{
	delete d->nmAccessPoint;
	delete d;
}


#include "knetworkmanager-accesspoint.moc"
