/* This file is part of the KDE project
   Copyright 2001-2004 Ian Geiser <geiseri@kde.org>
   Copyright 2002-2004 Nadeem Hasan <nhasan@kde.org>
   Copyright 2003-2004 John Ratke <jratke@comcast.net>

   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; see the file COPYING.  If not, write to
   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
   Boston, MA 02110-1301, USA.
*/

#include "weatherservice.h"
#include "weatherlib.h"
#include "stationdatabase.h"
#include "sun.h"
#include "serviceadaptor.h"

#include <kdebug.h>
#include <kconfig.h>
#include <kconfiggroup.h>
#include <kglobal.h>
#include <klocale.h>
#include <kstandarddirs.h>

#include <QtGui/QPixmap>
#include <QtGui/QApplication>


WeatherService::WeatherService(QObject *parent, const char *name)
: QObject (parent, name)
{
        (void) new ServiceAdaptor(this );
	QDBusConnection::sessionBus().registerObject("/Service", this);

	kDebug(12006) << "Starting new service... ";

	stationDB = new StationDatabase();

	m_weatherLib = new WeatherLib(stationDB, this, "WeatherLib");
	connect(m_weatherLib, SIGNAL(fileUpdating( const QString&)),
			SLOT(updating( const QString&)));
	connect(m_weatherLib, SIGNAL(fileUpdate( const QString&)),
			SLOT(updated( const QString&)));
	connect(m_weatherLib, SIGNAL(stationRemoved(const QString&)),
			SLOT(slotStationRemoved(const QString&)));

	KConfigGroup conf = KGlobal::config()->group("WEATHERSTATIONS");
	const QStringList stations =conf.readEntry("stations",QStringList());
	QStringList::ConstIterator it = stations.begin();
	for ( ; it != stations.end(); ++it )
		m_weatherLib->update(*it);
}

WeatherService::~WeatherService()
{
	kDebug(12006) << "Going away... ";
	// Don't need to call saveSettings() because WeatherService::exit
        // already does that. Plus it wouldn't work here anyway because
        // we can't get the config after calling qApp->quit();
	delete stationDB;
}

void WeatherService::updated(const QString &stationID)
{
	kDebug(12006) << "Sending update for " << stationID;
	emit fileUpdate( stationID );
}

void WeatherService::updateAll()
{
	kDebug(12006) << "Sending for all";
	QStringList stations =  m_weatherLib->stations();
       QStringList::ConstIterator end(stations.end());
       for  ( QStringList::ConstIterator it = stations.constBegin(); it != end; ++it ) {
		update(*it);
    	}

}

void WeatherService::updating(const QString &stationID)
{
	kDebug(12006) << "Sending updating for " << stationID;
	emit fileUpdating( stationID );
}

void WeatherService::slotStationRemoved(const QString &stationID)
{
  kDebug(12006) << "Sending stationRemoved for " << stationID;
  emit stationRemoved( stationID );
}

QString WeatherService::temperature(const QString &stationID)
{
	kDebug (12006) << "Returning " << stationID;
	return m_weatherLib->temperature(stationID);
}

QString WeatherService::dewPoint(const QString &stationID)
{
	return m_weatherLib->dewPoint(stationID);
}

QString WeatherService::relativeHumidity(const QString &stationID)
{
	return m_weatherLib->relHumidity(stationID);
}

QString WeatherService::heatIndex(const QString &stationID)
{
	return m_weatherLib->heatIndex(stationID);
}

QString WeatherService::windChill(const QString &stationID)
{
	return m_weatherLib->windChill(stationID);
}

QString WeatherService::wind(const QString &stationID)
{
	return m_weatherLib->wind(stationID);
}

QString WeatherService::pressure(const QString &stationID)
{
	return m_weatherLib->pressure(stationID);
}

QByteArray WeatherService::currentIcon(const QString &stationID)
{
    return icon( stationID );
}

QByteArray WeatherService::icon(const QString &stationID)
{
	kDebug(12006) << "Get the current weather icon..";
	QString icon  = iconFileName(stationID);
	QPixmap theIcon = QPixmap(icon);
	QByteArray pixmap;
	QDataStream in(pixmap);
	in << theIcon;

	return pixmap;
}

QString WeatherService::currentIconString(const QString &stationID)
{
	return m_weatherLib->iconName(stationID);
}

QString WeatherService::iconFileName(const QString &stationID)
{
	QString icon  = m_weatherLib->iconName(stationID);
	icon = KStandardDirs::locate( "data", "kweather/" + icon + ".png" );
	return icon;
}

QString WeatherService::date(const QString &stationID)
{
	return m_weatherLib->date(stationID);
}

QString WeatherService::visibility(const QString &stationID)
{
	return m_weatherLib->visibility(stationID);
}

QStringList WeatherService::cover(const QString &stationID)
{
	return m_weatherLib->cover(stationID);
}

QStringList WeatherService::weather(const QString &stationID)
{
	return m_weatherLib->weather(stationID);
}

bool WeatherService::stationNeedsMaintenance(const QString &stationID)
{
	return m_weatherLib->stationNeedsMaintenance(stationID);
}

void WeatherService::update(const QString &stationID)
{
	m_weatherLib->update(stationID);
}

void WeatherService::forceUpdate(const QString &stationID)
{
	m_weatherLib->forceUpdate(stationID);
}

void WeatherService::removeStation(const QString &stationID)
{
	m_weatherLib->remove(stationID);
	saveSettings();
}

void WeatherService::addStation(const QString &stationID)
{
	m_weatherLib->update(stationID);
	saveSettings();
}

void WeatherService::exit()
{
	saveSettings();
	qApp->quit();
}

QStringList WeatherService::listStations()
{
	return m_weatherLib->stations();
}

void WeatherService::saveSettings()
{
	KConfigGroup conf(KGlobal::config(), "WEATHERSTATIONS");
	conf.writeEntry( "stations", m_weatherLib->stations());
	conf.sync();
}

QString WeatherService::stationName(const QString &stationID)
{
	if ( stationDB )
	{
		QString upperStationID = stationID.toUpper();
		return stationDB->stationNameFromID(upperStationID);
	}
	else
		return stationID;
}
QString WeatherService::stationCode( const QString &stationName )
{
	if ( stationDB )
	{
		return stationDB->stationIDfromName(stationName);
	}
	else
		return stationName;
}

QString WeatherService::stationCountry(const QString &stationID)
{

	if ( stationDB )
	{
		QString upperStationID = stationID.toUpper();
		return stationDB->stationCountryFromID(upperStationID);
	}
	else
		return stationID;
}
QString WeatherService::longitude(const QString &stationID)
{
	if ( stationDB )
	{
		QString upperStationID = stationID.toUpper();
		return stationDB->stationLongitudeFromID(upperStationID);
	}
	else
		return "None";
}
QString WeatherService::latitude(const QString &stationID)
{
	if ( stationDB )
	{
		QString upperStationID = stationID.toUpper();
		return stationDB->stationLatitudeFromID(upperStationID);
	}
	else
		return "None";
}

QStringList WeatherService::findStations(float lon, float lat)
{
	Q_UNUSED(lon)
	Q_UNUSED(lat)

	QStringList stationList;
	stationList << "KMKE" << "KPNE" << "KTPW";
	return stationList;
}

QString WeatherService::getTime(const QString &stationID, TimeType timeType)
{
	QString upperStationID = stationID.toUpper();

	QString latitude  = stationDB->stationLatitudeFromID(upperStationID);
	QString longitude = stationDB->stationLongitudeFromID(upperStationID);

	if ( latitude.compare(  i18n("Unknown Station" ) ) == 0  ||
	     longitude.compare( i18n("Unknown Station" ) ) == 0 )
	{
		return i18n( "Unknown Station" );
	}
	else
	{
		Sun theSun( latitude, longitude );

		QTime time;
		switch ( timeType )
		{
			case RISE:
				time = theSun.computeRiseTime();
				break;
			case SET:
				time = theSun.computeSetTime();
				break;
			case CIVIL_START:
				time = theSun.computeCivilTwilightStart();
				break;
			case CIVIL_END:
				time = theSun.computeCivilTwilightEnd();
				break;
		}

		kDebug(12006) << "station, lat, lon, time: " << upperStationID << " " <<
			latitude << " " << longitude << " " << time << endl;

		return KGlobal::locale()->formatTime(time);
	}
}

QString WeatherService::sunRiseTime(const QString &stationID)
{
	return getTime(stationID, RISE);
}

QString WeatherService::sunSetTime(const QString &stationID)
{
	return getTime(stationID, SET);
}

QString WeatherService::civilTwilightStart(const QString &stationID)
{
	return getTime(stationID, CIVIL_START);
}

QString WeatherService::civilTwilightEnd(const QString &stationID)
{
	return getTime(stationID, CIVIL_END);
}



#include "weatherservice.moc"
