# Copyright (c) 2018-2020, NVIDIA CORPORATION.  All rights reserved.
#
# NVIDIA CORPORATION and its licensors retain all intellectual property
# and proprietary rights in and to this software, related documentation
# and any modifications thereto.  Any use, reproduction, disclosure or
# distribution of this software and related documentation without an express
# license agreement from NVIDIA CORPORATION is strictly prohibited.
#
__all__ = ["PrimNameModel"]

import omni.ui as ui

from pxr import Sdf, Tf


class PrimNameModel(ui.AbstractValueModel):
    """The model that changes the prim name"""

    def __init__(self, stage_item):
        super().__init__()
        self.__stage_item = stage_item
        self.__label_on_begin = None
        self.__old_label = None
        self.__name_prefix = None
        self.__suffix_order = None
        self.rebuild()
        self.__refresh_name_prefix_and_suffix()

    def __refresh_name_prefix_and_suffix(self):
        parts = self.__stage_item.name.rpartition("_")
        self.__name_prefix = None
        self.__suffix_order = None
        if parts and len(parts) > 1:
            suffix_order = parts[-1]
            are_all_digits = True
            for c in suffix_order:
                if not c.isdigit():
                    are_all_digits = False
                    break

            if are_all_digits and suffix_order:
                self.__name_prefix = parts[0].lower()
                self.__suffix_order = int(suffix_order)

        if self.__suffix_order is None:
            self.__name_prefix = self.__stage_item.name.lower()
            self.__suffix_order = 0

    @property
    def _prim_path(self):
        """DEPRECATED: to ensure back-compatibility."""
        return self.path

    @property
    def _name_prefix(self):
        """Name prefix without suffix number, e.g, `abc_01` will return abc. It's used for column sort."""

        return self.__name_prefix

    @property
    def _suffix_order(self):
        """Number suffix, e.g, `abc_01` will return 01. It's used for column sort."""

        return self.__suffix_order

    @property
    def path(self):
        return self.__stage_item.path

    def destroy(self):
        self.__stage_item = None

    def get_value_as_string(self):
        """Reimplemented get string"""
        return self.__label

    def rebuild(self):
        if self.__stage_item.stage_model.flat:
            self.__label = str(self.__stage_item.path)
        else:
            if self.__stage_item.path == Sdf.Path.absoluteRootPath:
                self.__label = "Root:"
            elif self.__stage_item.stage_model.show_prim_displayname:
                self.__label = self.__stage_item.display_name
            else:
                self.__label = self.__stage_item.name

    def begin_edit(self):
        self.__old_label = self.__label
        self.__label_on_begin = self.__stage_item.name
        self.__label = self.__label_on_begin
        if self.__old_label != self.__label:
            self._value_changed()

    def set_value(self, value):
        """Reimplemented set"""

        try:
            value = str(value)
        except ValueError:
            value = ""
        if value != self.__label:
            self.__label = value
            self._value_changed()

    def end_edit(self):
        if self.__label_on_begin == self.__label:
            if self.__label != self.__old_label:
                self.__label = self.__old_label
                self._value_changed()
            return

        # Get the unique name
        # replacing invalid characters with '_' if it's to display path name.
        parent_path = self.__stage_item.path.GetParentPath()
        valid_label_identifier = Tf.MakeValidIdentifier(self.__label)
        new_prim_name = valid_label_identifier
        counter = 1
        while True:
            created_path = parent_path.AppendElementString(new_prim_name)
            if not self.__stage_item.stage.GetPrimAtPath(created_path):
                break

            new_prim_name = "{}_{:02d}".format(valid_label_identifier, counter)
            counter += 1

        stage_model = self.__stage_item.stage_model
        if stage_model.rename_prim(self.__stage_item.path, new_prim_name):
            self.__refresh_name_prefix_and_suffix()
            self._value_changed()

            if not stage_model.show_prim_displayname:
                self.__label = new_prim_name
