#Copyright (c) 2019 <NAME>.
#Cura is released under the terms of the LGPLv3 or higher.

import collections
from PyQt5.QtCore import Qt, QTimer
from typing import TYPE_CHECKING, Optional, Dict
from cura.Machines.Models.IntentTranslations import intent_translations

from cura.Machines.Models.IntentModel import IntentModel
from cura.Settings.IntentManager import IntentManager
from UM.Qt.ListModel import ListModel
from UM.Settings.ContainerRegistry import ContainerRegistry #To update the list if anything changes.
from PyQt5.QtCore import pyqtProperty, pyqtSignal
import cura.CuraApplication
if TYPE_CHECKING:
    from UM.Settings.ContainerRegistry import ContainerInterface

from UM.i18n import i18nCatalog
catalog = i18nCatalog("cura")


##  Lists the intent categories that are available for the current printer
#   configuration.
class IntentCategoryModel(ListModel):
    NameRole = Qt.UserRole + 1
    IntentCategoryRole = Qt.UserRole + 2
    WeightRole = Qt.UserRole + 3
    QualitiesRole = Qt.UserRole + 4
    DescriptionRole = Qt.UserRole + 5

    modelUpdated = pyqtSignal()

    _translations = collections.OrderedDict()  # type: "collections.OrderedDict[str,Dict[str,Optional[str]]]"

    # Translations to user-visible string. Ordered by weight.
    # TODO: Create a solution for this name and weight to be used dynamically.
    @classmethod
    def _get_translations(cls):
        if len(cls._translations) == 0:
            cls._translations["default"] = {
                "name": catalog.i18nc("@label", "Default")
            }
            cls._translations["visual"] = {
                "name": catalog.i18nc("@label", "Visual"),
                "description": catalog.i18nc("@text", "The visual profile is designed to print visual prototypes and models with the intent of high visual and surface quality.")
            }
            cls._translations["engineering"] = {
                "name": catalog.i18nc("@label", "Engineering"),
                "description": catalog.i18nc("@text", "The engineering profile is designed to print functional prototypes and end-use parts with the intent of better accuracy and for closer tolerances.")
            }
            cls._translations["quick"] = {
                "name": catalog.i18nc("@label", "Draft"),
                "description": catalog.i18nc("@text", "The draft profile is designed to print initial prototypes and concept validation with the intent of significant print time reduction.")
            }
        return cls._translations

    ##  Creates a new model for a certain intent category.
    #   \param The category to list the intent profiles for.
    def __init__(self, intent_category: str) -> None:
        super().__init__()
        self._intent_category = intent_category

        self.addRoleName(self.NameRole, "name")
        self.addRoleName(self.IntentCategoryRole, "intent_category")
        self.addRoleName(self.WeightRole, "weight")
        self.addRoleName(self.QualitiesRole, "qualities")
        self.addRoleName(self.DescriptionRole, "description")

        application = cura.CuraApplication.CuraApplication.getInstance()

        ContainerRegistry.getInstance().containerAdded.connect(self._onContainerChange)
        ContainerRegistry.getInstance().containerRemoved.connect(self._onContainerChange)
        machine_manager = cura.CuraApplication.CuraApplication.getInstance().getMachineManager()
        machine_manager.activeMaterialChanged.connect(self.update)
        machine_manager.activeVariantChanged.connect(self.update)
        machine_manager.extruderChanged.connect(self.update)

        extruder_manager = application.getExtruderManager()
        extruder_manager.extrudersChanged.connect(self.update)

        self._update_timer = QTimer()
        self._update_timer.setInterval(500)
        self._update_timer.setSingleShot(True)
        self._update_timer.timeout.connect(self._update)

        self.update()

    ##  Updates the list of intents if an intent profile was added or removed.
    def _onContainerChange(self, container: "ContainerInterface") -> None:
        if container.getMetaDataEntry("type") == "intent":
            self.update()

    def update(self):
        self._update_timer.start()

    ##  Updates the list of intents.
    def _update(self) -> None:
        available_categories = IntentManager.getInstance().currentAvailableIntentCategories()
        result = []
        for category in available_categories:
            qualities = IntentModel()
            qualities.setIntentCategory(category)
            result.append({
                "name": IntentCategoryModel.translation(category, "name", catalog.i18nc("@label", "Unknown")),
                "description": IntentCategoryModel.translation(category, "description", None),
                "intent_category": category,
                "weight": list(IntentCategoryModel._get_translations().keys()).index(category),
                "qualities": qualities
            })
        result.sort(key = lambda k: k["weight"])
        self.setItems(result)

    ##  Get a display value for a category.
    ##  for categories and keys
    @staticmethod
    def translation(category: str, key: str, default: Optional[str] = None):
        display_strings = IntentCategoryModel._get_translations().get(category, {})
        return display_strings.get(key, default)

#Copyright (c) 2019 <NAME>.
#Cura is released under the terms of the LGPLv3 or higher.

import collections
from PyQt5.QtCore import Qt, QTimer
from typing import TYPE_CHECKING, Optional, Dict
from cura.Machines.Models.IntentTranslations import intent_translations

from cura.Machines.Models.IntentModel import IntentModel
from cura.Settings.IntentManager import IntentManager
from UM.Qt.ListModel import ListModel
from UM.Settings.ContainerRegistry import ContainerRegistry #To update the list if anything changes.
from PyQt5.QtCore import pyqtProperty, pyqtSignal
import cura.CuraApplication
if TYPE_CHECKING:
    from UM.Settings.ContainerRegistry import ContainerInterface

from UM.i18n import i18nCatalog
catalog = i18nCatalog("cura")


##  Lists the intent categories that are available for the current printer
#   configuration.
class IntentCategoryModel(ListModel):
    NameRole = Qt.UserRole + 1
    IntentCategoryRole = Qt.UserRole + 2
    WeightRole = Qt.UserRole + 3
    QualitiesRole = Qt.UserRole + 4
    DescriptionRole = Qt.UserRole + 5

    modelUpdated = pyqtSignal()

    _translations = collections.OrderedDict()  # type: "collections.OrderedDict[str,Dict[str,Optional[str]]]"

    # Translations to user-visible string. Ordered by weight.
    # TODO: Create a solution for this name and weight to be used dynamically.
    @classmethod
    def _get_translations(cls):
        if len(cls._translations) == 0:
            cls._translations["default"] = {
                "name": catalog.i18nc("@label", "Default")
            }
            cls._translations["visual"] = {
                "name": catalog.i18nc("@label", "Visual"),
                "description": catalog.i18nc("@text", "The visual profile is designed to print visual prototypes and models with the intent of high visual and surface quality.")
            }
            cls._translations["engineering"] = {
                "name": catalog.i18nc("@label", "Engineering"),
                "description": catalog.i18nc("@text", "The engineering profile is designed to print functional prototypes and end-use parts with the intent of better accuracy and for closer tolerances.")
            }
            cls._translations["quick"] = {
                "name": catalog.i18nc("@label", "Draft"),
                "description": catalog.i18nc("@text", "The draft profile is designed to print initial prototypes and concept validation with the intent of significant print time reduction.")
            }
        return cls._translations

    ##  Creates a new model for a certain intent category.
    #   \param The category to list the intent profiles for.
    def __init__(self, intent_category: str) -> None:
        super().__init__()
        self._intent_category = intent_category

        self.addRoleName(self.NameRole, "name")
        self.addRoleName(self.IntentCategoryRole, "intent_category")
        self.addRoleName(self.WeightRole, "weight")
        self.addRoleName(self.QualitiesRole, "qualities")
        self.addRoleName(self.DescriptionRole, "description")

        application = cura.CuraApplication.CuraApplication.getInstance()

        ContainerRegistry.getInstance().containerAdded.connect(self._onContainerChange)
        ContainerRegistry.getInstance().containerRemoved.connect(self._onContainerChange)
        machine_manager = cura.CuraApplication.CuraApplication.getInstance().getMachineManager()
        machine_manager.activeMaterialChanged.connect(self.update)
        machine_manager.activeVariantChanged.connect(self.update)
        machine_manager.extruderChanged.connect(self.update)

        extruder_manager = application.getExtruderManager()
        extruder_manager.extrudersChanged.connect(self.update)

        self._update_timer = QTimer()
        self._update_timer.setInterval(500)
        self._update_timer.setSingleShot(True)
        self._update_timer.timeout.connect(self._update)

        self.update()

    ##  Updates the list of intents if an intent profile was added or removed.
    def _onContainerChange(self, container: "ContainerInterface") -> None:
        if container.getMetaDataEntry("type") == "intent":
            self.update()

    def update(self):
        self._update_timer.start()

    ##  Updates the list of intents.
    def _update(self) -> None:
        available_categories = IntentManager.getInstance().currentAvailableIntentCategories()
        result = []
        for category in available_categories:
            qualities = IntentModel()
            qualities.setIntentCategory(category)
            result.append({
                "name": IntentCategoryModel.translation(category, "name", catalog.i18nc("@label", "Unknown")),
                "description": IntentCategoryModel.translation(category, "description", None),
                "intent_category": category,
                "weight": list(IntentCategoryModel._get_translations().keys()).index(category),
                "qualities": qualities
            })
        result.sort(key = lambda k: k["weight"])
        self.setItems(result)

    ##  Get a display value for a category.
    ##  for categories and keys
    @staticmethod
    def translation(category: str, key: str, default: Optional[str] = None):
        display_strings = IntentCategoryModel._get_translations().get(category, {})
        return display_strings.get(key, default)

#Copyright (c) 2019 <NAME>. #Cura is released under the terms of the LGPLv3 or higher. #To update the list if anything changes. ##  Lists the intent categories that are available for the current printer #   configuration. # type: "collections.OrderedDict[str,Dict[str,Optional[str]]]" # Translations to user-visible string. Ordered by weight. # TODO: Create a solution for this name and weight to be used dynamically. ##  Creates a new model for a certain intent category. #   \param The category to list the intent profiles for. ##  Updates the list of intents if an intent profile was added or removed. ##  Updates the list of intents. ##  Get a display value for a category. ##  for categories and keys