#include <tqpair.h>

#include <tdestandarddirs.h>
#include <kiconloader.h>
#include <kdebug.h>

#include "weather_icon.h"

WeatherIconPrivate* WeatherIconPrivate::s_instance = 0;

WeatherIconPrivate::WeatherIconPrivate()
{
	iconLoader = new TDEIconLoader("kweather");
}

WeatherIconPrivate::~WeatherIconPrivate()
{
	delete iconLoader;
}

WeatherIconPrivate* WeatherIconPrivate::instance()
{
	if ( s_instance == 0 )
		s_instance = new WeatherIconPrivate();

	return s_instance;
}

void WeatherIconPrivate::useIconTheme( bool use )
{
	m_useIconTheme = use;
}

bool WeatherIconPrivate::usingIconTheme()
{
	return m_useIconTheme;
}

/** Returns the name of the best matching icon, either from the icon theme or the KWeather icons */
struct WeatherSingleIconData WeatherIconPrivate::findIcon(TQStringList fallback, uint size)
{
	struct WeatherSingleIconData iconData;

	kdDebug(12006) << "[findIcon] Use icon theme? " << m_useIconTheme << endl;
	if (m_useIconTheme)
	{
		// Check in theme
		for (TQStringList::Iterator icon = fallback.begin(); icon != fallback.end(); ++icon)
		{
			kdDebug(12006) << "[findIcon] Searching for `" << *icon << "` in theme" << endl;
			TQString iPath = iconPath(*icon, size, true);
			if (!iPath.isNull())
			{
				kdDebug(12006) << "[findIcon] Found `" << *icon << "` in theme: " << iPath << endl;
				iconData = { *icon, iPath, true, size };
				return iconData;
			}
		}
	}

	// Check in kweather fallback
	for (TQStringList::Iterator icon = fallback.begin(); icon != fallback.end(); ++icon)
	{
		kdDebug(12006) << "[findIcon] Searching for `" << *icon << "` in kweather icons" << endl;
		TQString iPath = iconPath(*icon, size, false);
        if (!iPath.isEmpty())
		{
			kdDebug(12006) << "[findIcon] Found `" << *icon << "` in kweather icons: " << iPath << endl;
			iconData = { *icon, iPath, false, size };
			return iconData;
		}
	}

	return WeatherIcon::unknown(size);
}

TQString WeatherIconPrivate::iconPath( TQString icon, uint size, bool inTheme )
{
	TQString path = TQString::null;
	if (inTheme) {
		path = iconLoader->iconPath(icon, size, true);
		if (path.isEmpty()) {
			// maybe there is a scalable icon?
			path = iconLoader->iconPath(icon, 0, true);
		}
	}
	else {
		path = locate( "data", "kweather/" + icon + ".png" );
	}
	return path;
}

TQString WeatherIconPrivate::iconPath( TQString icon, uint size )
{
	return iconPath(icon, size, m_useIconTheme);
}

WeatherIcon::WeatherIcon( int condition, bool night )
{
	switch( condition )
	{
		case Sunny:
		{
			if( night )
			{
				fallback << "weather-clear-night"; //xdg, kweather
			}
			fallback << "weather-clear"; // xdg, kweather
			break;
		}

		case Fog:
		{
			if( night )
			{
				fallback << "weather-fog-night"; // themes, kweather
			}
			fallback << "weather-fog"; // xdg, kweather
			break;
		}

		case Mist:
		{
			if( night )
			{
				fallback << "weather-mist-night"; // themes, kweather
			}
			fallback << "weather-mist"; // themes, kweather

			if( night )
			{
				fallback << "weather-fog-night"; // themes, kweather
			}
			fallback << "weather-fog"; // xdg, kweather
			break;
		}

		case Overcast:
		{
			fallback << "weather-overcast"; // xdg, kweather
			break;
		}

		case Hail:
		{
			fallback << "weather-hail"; // themes
			fallback << "weather-freezing-rain"; // themes, kweather
			fallback << "weather-snow"; // xdg, kweather
			break;
		}

		case LightRain:
		{
			fallback << "weather-showers-scattered"; // xdg, kweather
			break;
		}

		case Sleet:
		{
			fallback << "weather-snow-rain"; // themes, kweather
			fallback << "weather-snow"; // xdg, kweather
			break;
		}
	}
}

WeatherIcon::WeatherIcon( int condition, bool night, unsigned int strength )
{
	switch ( condition )
	{
		case Cloudy:
		{
			switch ( strength )
			{
				case 1:
				{
					if( night )
					{
						fallback << "weather-few-clouds-night"; // xdg, kweather
					}
					fallback << "weather-few-clouds"; // xdg, kweather
					break;
				}

				case 2:
				{
					if( night )
					{
						fallback << "weather-moderate-clouds-night"; // kweather
					}
					fallback << "weather-moderate-clouds"; // kweather

					if( night )
					{
						fallback << "weather-few-clouds-night"; // xdg, kweather
					}
					fallback << "weather-few-clouds"; // xdg, kweather
					break;
				}

				case 3: {
					if( night )
					{
						fallback << "weather-clouds-night"; // themes, kweather
					}
					fallback << "weather-clouds"; // themes, kweather

					if( night )
					{
						fallback << "weather-few-clouds-night"; // xdg, kweather
					}
					fallback << "weather-few-clouds"; // xdg, kweather
					break;
				}

				case 4:
				{
					if( night )
					{
						fallback << "weather-ample-clouds-night"; // kweather
					}
					fallback << "weather-ample-clouds"; // kweather
					fallback << "weather-many-clouds"; // themes, kweather
					fallback << "weather-overcast"; // xdg, kweather
					break;
				}

				case 5:  {
					fallback << "weather-many-clouds"; // themes, kweather
					fallback << "weather-overcast"; // xdg, kweather
					break;
				}

				default: {
					fallback << "weather-clouds"; // themes, kweather
					fallback << "weather-few-clouds"; // xdg, kweather
					break;
				}
			}
			break;
		}

		case Showers:
		{
			switch ( strength )
			{
				case 1:
				{
					if( night )
					{
						fallback << "weather-showers-scattered-night"; // themes, kweather
					}
					else
					{
						fallback << "weather-showers-scattered-day"; // themes, kweather
					}
					fallback << "weather-showers-scattered"; // xdg, kweather
					break;
				}

				case 2:
				{
					if( night )
					{
						fallback << "weather-showers-night"; // themes, kweather
					}
					else
					{
						fallback << "weather-showers-day"; // themes, kweather
					}
					fallback << "weather-showers"; // xdg, kweather
					break;
				}

				case 3:
				default:
				{
					fallback << "weather-showers"; // xdg, kweather
					break;
				}
			}

			break;
		}

		case Snow:
		{
			switch( strength )
			{
				case 1:
				{
					if( night )
					{
						fallback << "weather-snow-scattered-night"; // themes, kweather
					}
					else
					{
						fallback << "weather-snow-scattered-day"; // themes, kweather
					}

					fallback << "weather-snow-scattered"; // xdg, kweather
					fallback << "weather-snow"; // workaround for some themes
					break;
				}
				case 2:
				{
					if( night )
					{
						fallback << "weather-snow-moderate-night"; // kweather
					}
					else
					{
						fallback << "weather-snow-moderate-day"; // kweather
					}

					fallback << "weather-snow-moderate"; // kweather

					if( night )
					{
						fallback << "weather-snow-scattered-night"; // themes, kweather
					}
					else
					{
						fallback << "weather-snow-scattered-day"; // themes, kweather
					}

					fallback << "weather-snow-scattered"; // xdg, kweather
					fallback << "weather-snow"; // workaround for some themes
					break;
				}

				case 3:
				{
					if( night )
					{
						fallback << "weather-snow-ample-night"; // kweather
					}
					else
					{
						fallback << "weather-snow-ample-day"; // kweather
					}
					fallback << "weather-snow-ample"; // kweather
					fallback << "weather-snow"; // xdg, kweather
					break;
				}

				case 4:
				{
					fallback << "weather-snow-scattered"; // xdg, kweather
					fallback << "weather-snow"; // workaround for some themes
					break;
				}

				case 5:
				default:
				{
					fallback << "weather-snow"; // xdg, kweather
					break;
				}
			}

			break;
		}

		case Thunderstorm:
			switch ( strength )
			{
				case 1:
				{
					if( night )
					{
						fallback << "weather-storm-night"; // themes, kweather
					}
					else
					{
						fallback << "weather-storm-day"; // themes, kweather
					}
					fallback << "weather-storm"; // xdg, kweather
					break;
				}

				case 2:
				{
					if( night )
					{
						fallback << "weather-storm-moderate-night"; // kweather
					}
					else
					{
						fallback << "weather-storm-moderate-day"; // kweather
					}
					fallback << "weather-storm-moderate"; // kweather

					if( night )
					{
						fallback << "weather-storm-night"; // themes, kweather
					}
					else
					{
						fallback << "weather-storm-day"; // themes, kweather
					}
					fallback << "weather-storm"; // xdg, kweather
					break;
				}
				case 3:
				default:
				{
					fallback << "weather-storm"; // xdg, kweather
					break;
				}
			}
			break;
	}
}

// Unknown weather conditions
WeatherIcon::WeatherIcon() {
	fallback << "weather-none-available";
}

WeatherIcon::~WeatherIcon()
{
}

struct WeatherSingleIconData WeatherIcon::iconData(uint size) {
	return WeatherIconPrivate::instance()->findIcon(fallback, size);
}

struct WeatherSingleIconData WeatherIcon::unknown(uint size) {
	WeatherIcon *unknown = new WeatherIcon();
	struct WeatherSingleIconData unknownData = unknown->iconData(size);
	delete unknown;
	return unknownData;
}

// convenience functions
TQString WeatherIcon::name(uint size) {
	return iconData(size).name;
}

TQString WeatherIcon::path(uint size) {
	return iconData(size).path;
}