/*
 * Copyright (C) Psi Development Team
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 *
 */

#include <QtGlobal>

#if QT_VERSION < QT_VERSION_CHECK(5, 2, 0)
#include <QByteArray>
#include <QTime>
#ifdef Q_OS_UNIX
#include <time.h>
#endif
#ifdef Q_OS_WIN
#include <windows.h>
#endif
#else
#include <QTimeZone>
#endif

#include "timezone.h"

#if QT_VERSION < QT_VERSION_CHECK(5,2,0)
static bool inited = false;
static int timezone_offset_;
static QString timezone_str_;

static void init()
{
#if defined(Q_OS_UNIX)
	time_t x;
	time(&x);
	char str[256];
	char fmt[32];
	int size;
	strcpy(fmt, "%z");
	size = strftime(str, 256, fmt, localtime(&x));
	if(size && strncmp(fmt, str, size)) {
		timezone_offset_ = QByteArray::fromRawData(str + 1, 2).toInt() * 60 + QByteArray::fromRawData(str + 3, 2).toInt();
		if(str[0] == '-')
			timezone_offset_ = -timezone_offset_;
	}
	strcpy(fmt, "%Z");
	strftime(str, 256, fmt, localtime(&x));
	if(strcmp(fmt, str))
		timezone_str_ = str;

#elif defined(Q_OS_WIN)
	TIME_ZONE_INFORMATION i;
	memset(&i, 0, sizeof(i));
	bool inDST = (GetTimeZoneInformation(&i) == TIME_ZONE_ID_DAYLIGHT);
	int bias = i.Bias;
	if(inDST)
		bias += i.DaylightBias;
	timezone_offset_ = -bias;
	timezone_str_ = "";
	for(int n = 0; n < 32; ++n) {
		int w = inDST ? i.DaylightName[n] : i.StandardName[n];
		if(w == 0)
			break;
		timezone_str_ += QChar(w);
	}

#else
	qWarning("Failed to properly init timezone data. Use UTC offset instead");
	inited = true;
	timezone_offset_ = 0;
	timezone_str_ = QLatin1String("N/A");
#endif
}
#endif

int TimeZone::offsetFromUtc()
{
#if QT_VERSION < QT_VERSION_CHECK(5,2,0)
	if (!inited) {
		init();
	}
	return timezone_offset_;
#else
	return QTimeZone::systemTimeZone().offsetFromUtc(QDateTime::currentDateTime()) / 60;
#endif
}

QString TimeZone::abbreviation()
{
#if QT_VERSION < QT_VERSION_CHECK(5,2,0)
	return timezone_str_;
#else
	return QTimeZone::systemTimeZone().abbreviation(QDateTime::currentDateTime());
#endif
}

int TimeZone::tzdToInt(const QString &tzd)
{
	int tzoSign = 1;
	if (tzd.startsWith('Z')) {
		return 0;
	} else if (tzd.startsWith('+') || tzd.startsWith('-')) {
		QTime time = QTime::fromString(tzd.mid(1), "hh:mm");
		if (time.isValid()) {
			if (tzd[0] == '-') {
				tzoSign = -1;
			}
			return tzoSign * (time.hour() * 60 + time.second());
		}
	}
	return -1; /* we don't have -1 sec offset. and usually the value is common for errors */
}

/**
 * \fn int TimeZone::timezoneOffset()
 * \brief Local timezone offset in minutes.
 */

/**
 * \fn QString TimeZone::timezoneString()
 * \brief Local timezone name.
 */
