#include "gui/locale.h"
#include "core/strings.h"

#include <QApplication>
#include <QDir>
#include <QLocale>
#include <QString>
#include <QTranslator>

#include <QtGlobal>

namespace Locale {

std::string GetLocaleFullName(const QLocale &locale)
{
	QString res = QLocale::languageToString(locale.language());
#if QT_VERSION >= QT_VERSION_CHECK(6, 2, 0)
	/* silence deprecation warning for locale.country() */
	if (locale.territory() != QLocale::AnyTerritory)
		res += " (" + QLocale::territoryToString(locale.territory()) + ")";
#else
	if (locale.country() != QLocale::AnyCountry)
		res += " (" + QLocale::countryToString(locale.country()) + ")";
#endif
	return Strings::ToUtf8String(res);
}

Locale::Locale()
{
	RefreshAvailableLocales();
	SetActiveLocale(QLocale("en_US"));
}

Locale::Locale(const std::string &name)
{
	RefreshAvailableLocales();
	SetActiveLocale(QLocale(Strings::ToQString(name)));
}

QLocale Locale::GetLocale() const
{
	return _locale;
}

std::vector<QLocale> Locale::GetAvailableLocales() const
{
	return _available_translations;
}

void Locale::RefreshAvailableLocales()
{
	_available_translations.clear();

	/* we will always have en_US */
	_available_translations.push_back(QLocale("en_US"));

	QDir dir(":/locale");
	if (!dir.exists())
		return;

	QStringList translations = dir.entryList({"*.qm"}, QDir::Files);

	_available_translations.reserve(translations.size());
	for (const QString &str : translations)
		_available_translations.push_back(QLocale(str.mid(0, str.lastIndexOf("."))));
}

bool Locale::IsLocaleAvailable(const QLocale &locale) const
{
	for (const QLocale &l : _available_translations)
		if (l == locale)
			return true;
	return false;
}

bool Locale::SetActiveLocale(const QLocale &locale)
{
	if (!IsLocaleAvailable(locale) || !qApp)
		return false;

	if (_locale == locale)
		return true; /* we're... already on this locale :) */

	_locale = locale;
	QLocale::setDefault(_locale);

	/* we can still do stuff even if one thing fails! */
	bool return_value = true;

	const QString name = _locale.name();
	if (!SwitchTranslator(_translator, QString(":/locale/%1.qm").arg(name)))
		return_value = false;

	const QString path = qApp->applicationDirPath();
	if (!SwitchTranslator(_translator_qt, path + QString("/translations/qt_%1.qm").arg(name))) {
		/* Sometimes Qt will have proper translations for the language, but not the specific
		 * country. In that case, we still want to use that language. */
		const int underscore_index = name.lastIndexOf("_");
		if (!underscore_index)
			return false;

		const QString short_name = name.mid(0, underscore_index);
		if (!SwitchTranslator(_translator_qt, path + QString("/translations/qt_%1.qm").arg(short_name)))
			return_value = false;
	}

	return return_value;
}

bool Locale::SwitchTranslator(QTranslator &translator, const QString &path)
{
	qApp->removeTranslator(&translator);

	if (!translator.load(path))
		return false;

	qApp->installTranslator(&translator);
	return true;
}

} // namespace Locale
