# Created By: Virgil Dupras
# Created On: 2009-05-03
# Copyright 2015 Hardcoded Software (http://www.hardcoded.net)
#
# This software is licensed under the "GPLv3" License as described in the "LICENSE" file,
# which should be included with this package. The terms are also available at
# http://www.gnu.org/licenses/gpl-3.0.html

from PyQt5.QtCore import Qt, QSettings, QRect, QObject, pyqtSignal

from hscommon.trans import trget
from hscommon.util import tryint

tr = trget('qtlib')

def get_langnames():
    return {
        'en': tr("English"),
        'fr': tr("French"),
        'de': tr("German"),
        'el': tr("Greek"),
        'zh_CN': tr("Chinese (Simplified)"),
        'cs': tr("Czech"),
        'it': tr("Italian"),
        'hy': tr("Armenian"),
        'ko': tr("Korean"),
        'ru': tr("Russian"),
        'uk': tr("Ukrainian"),
        'nl': tr('Dutch'),
        'pl_PL': tr("Polish"),
        'pt_BR': tr("Brazilian"),
        'es': tr("Spanish"),
        'vi': tr("Vietnamese"),
    }

def normalize_for_serialization(v):
    # QSettings doesn't consider set/tuple as "native" typs for serialization, so if we don't
    # change them into a list, we get a weird serialized QVariant value which isn't a very
    # "portable" value.
    if isinstance(v, (set, tuple)):
        v = list(v)
    if isinstance(v, list):
        v = [normalize_for_serialization(item) for item in v]
    return v

def adjust_after_deserialization(v):
    # In some cases, when reading from prefs, we end up with strings that are supposed to be
    # bool or int. Convert these.
    if isinstance(v, list):
        return [adjust_after_deserialization(sub) for sub in v]
    if isinstance(v, str):
        # might be bool or int, try them
        if v == 'true':
            return True
        elif v == 'false':
            return False
        else:
            return tryint(v, v)
    return v

# About QRect conversion:
# I think Qt supports putting basic structures like QRect directly in QSettings, but I prefer not
# to rely on it and stay with generic structures.

class Preferences(QObject):
    prefsChanged = pyqtSignal()

    def __init__(self):
        QObject.__init__(self)
        self.reset()
        self._settings = QSettings()

    def _load_values(self, settings, get):
        pass

    def get_rect(self, name, default=None):
        r = self.get_value(name, default)
        if r is not None:
            return QRect(*r)
        else:
            return None

    def get_value(self, name, default=None):
        if self._settings.contains(name):
            result = adjust_after_deserialization(self._settings.value(name))
            if result is not None:
                return result
            else:
                # If result is None, but still present in self._settings, it usually means a value
                # like "@Invalid".
                return default
        else:
            return default

    def load(self):
        self.reset()
        self._load_values(self._settings)

    def reset(self):
        pass

    def _save_values(self, settings, set_):
        pass

    def save(self):
        self._save_values(self._settings)
        self._settings.sync()

    def set_rect(self, name, r):
        if isinstance(r, QRect):
            rectAsList = [r.x(), r.y(), r.width(), r.height()]
            self.set_value(name, rectAsList)

    def set_value(self, name, value):
        self._settings.setValue(name, normalize_for_serialization(value))

    def saveGeometry(self, name, widget):
        # We save geometry under a 5-sized int array: first item is a flag for whether the widget
        # is maximized and the other 4 are (x, y, w, h).
        m = 1 if widget.isMaximized() else 0
        r = widget.geometry()
        rectAsList = [r.x(), r.y(), r.width(), r.height()]
        self.set_value(name, [m] + rectAsList)

    def restoreGeometry(self, name, widget):
        l = self.get_value(name)
        if l and len(l) == 5:
            m, x, y, w, h = l
            if m:
                widget.setWindowState(Qt.WindowMaximized)
            else:
                r = QRect(x, y, w, h)
                widget.setGeometry(r)

