"""Support for simplified access to data on nodes of type omni.graph.tutorials.ExtendedTypes

This is a tutorial node. It exercises functionality for the manipulation of the extended attribute types.
"""

from typing import Any
import carb

import omni.graph.core as og
import omni.graph.core._omni_graph_core as _og
import omni.graph.tools.ogn as ogn



class OgnTutorialExtendedTypesDatabase(og.Database):
    """Helper class providing simplified access to data on nodes of type omni.graph.tutorials.ExtendedTypes

    Class Members:
        node: Node being evaluated

    Attribute Value Properties:
        Inputs:
            inputs.flexible
            inputs.floatOrToken
            inputs.toNegate
            inputs.tuple
        Outputs:
            outputs.doubledResult
            outputs.flexible
            outputs.negatedResult
            outputs.tuple
    """

    # Imprint the generator and target ABI versions in the file for JIT generation
    GENERATOR_VERSION = (1, 41, 3)
    TARGET_VERSION = (2, 139, 12)

    # This is an internal object that provides per-class storage of a per-node data dictionary
    PER_NODE_DATA = {}

    # This is an internal object that describes unchanging attributes in a generic way
    # The values in this list are in no particular order, as a per-attribute tuple
    #     Name, Type, ExtendedTypeIndex, UiName, Description, Metadata,
    #     Is_Required, DefaultValue, Is_Deprecated, DeprecationMsg
    # You should not need to access any of this data directly, use the defined database interfaces
    INTERFACE = og.Database._get_interface([
        ('inputs:flexible', 'float[3][],token', 1, 'Flexible Values', 'Flexible data type input', {}, True, None, False, ''),
        ('inputs:floatOrToken', 'float,token', 1, 'Float Or Token', 'Attribute that can either be a float value or a token value', {}, True, None, False, ''),
        ('inputs:toNegate', 'bool[],float[]', 1, 'To Negate', 'Attribute that can either be an array of booleans or an array of floats', {}, True, None, False, ''),
        ('inputs:tuple', 'any', 2, 'Tuple Values', 'Variable size/type tuple values', {}, True, None, False, ''),
        ('outputs:doubledResult', 'any', 2, 'Doubled Input Value', "If the input 'simpleInput' is a float this is 2x the value.\nIf it is a token this contains the input token repeated twice.", {}, True, None, False, ''),
        ('outputs:flexible', 'float[3][],token', 1, 'Inverted Flexible Values', 'Flexible data type output', {}, True, None, False, ''),
        ('outputs:negatedResult', 'bool[],float[]', 1, 'Negated Array Values', "Result of negating the data from the 'toNegate' input", {}, True, None, False, ''),
        ('outputs:tuple', 'any', 2, 'Negative Tuple Values', 'Negated values of the tuple input', {}, True, None, False, ''),
    ])

    class ValuesForInputs(og.DynamicAttributeAccess):
        LOCAL_PROPERTY_NAMES = { }
        """Helper class that creates natural hierarchical access to input attributes"""
        def __init__(self, node: og.Node, attributes, dynamic_attributes: og.DynamicAttributeInterface):
            """Initialize simplified access for the attribute data"""
            context = node.get_graph().get_default_graph_context()
            super().__init__(context, node, attributes, dynamic_attributes)
            self._batchedReadAttributes = []
            self._batchedReadValues = []

        @property
        def flexible(self) -> og.RuntimeAttribute:
            """Get the runtime wrapper class for the attribute inputs.flexible"""
            return og.RuntimeAttribute(self._attributes.flexible.get_attribute_data(), self._context, True)

        @flexible.setter
        def flexible(self, value_to_set: Any):
            """Assign another attribute's value to outputs.flexible"""
            if isinstance(value_to_set, og.RuntimeAttribute):
                self.flexible.value = value_to_set.value
            else:
                self.flexible.value = value_to_set

        @property
        def floatOrToken(self) -> og.RuntimeAttribute:
            """Get the runtime wrapper class for the attribute inputs.floatOrToken"""
            return og.RuntimeAttribute(self._attributes.floatOrToken.get_attribute_data(), self._context, True)

        @floatOrToken.setter
        def floatOrToken(self, value_to_set: Any):
            """Assign another attribute's value to outputs.floatOrToken"""
            if isinstance(value_to_set, og.RuntimeAttribute):
                self.floatOrToken.value = value_to_set.value
            else:
                self.floatOrToken.value = value_to_set

        @property
        def toNegate(self) -> og.RuntimeAttribute:
            """Get the runtime wrapper class for the attribute inputs.toNegate"""
            return og.RuntimeAttribute(self._attributes.toNegate.get_attribute_data(), self._context, True)

        @toNegate.setter
        def toNegate(self, value_to_set: Any):
            """Assign another attribute's value to outputs.toNegate"""
            if isinstance(value_to_set, og.RuntimeAttribute):
                self.toNegate.value = value_to_set.value
            else:
                self.toNegate.value = value_to_set

        @property
        def tuple(self) -> og.RuntimeAttribute:
            """Get the runtime wrapper class for the attribute inputs.tuple"""
            return og.RuntimeAttribute(self._attributes.tuple.get_attribute_data(), self._context, True)

        @tuple.setter
        def tuple(self, value_to_set: Any):
            """Assign another attribute's value to outputs.tuple"""
            if isinstance(value_to_set, og.RuntimeAttribute):
                self.tuple.value = value_to_set.value
            else:
                self.tuple.value = value_to_set

        def _prefetch(self):
            readAttributes = self._batchedReadAttributes
            newValues = _og._prefetch_input_attributes_data(readAttributes)
            if len(readAttributes) == len(newValues):
                self._batchedReadValues = newValues

    class ValuesForOutputs(og.DynamicAttributeAccess):
        LOCAL_PROPERTY_NAMES = { }
        """Helper class that creates natural hierarchical access to output attributes"""
        def __init__(self, node: og.Node, attributes, dynamic_attributes: og.DynamicAttributeInterface):
            """Initialize simplified access for the attribute data"""
            context = node.get_graph().get_default_graph_context()
            super().__init__(context, node, attributes, dynamic_attributes)
            self._batchedWriteValues = { }

        @property
        def doubledResult(self) -> og.RuntimeAttribute:
            """Get the runtime wrapper class for the attribute outputs.doubledResult"""
            return og.RuntimeAttribute(self._attributes.doubledResult.get_attribute_data(), self._context, False)

        @doubledResult.setter
        def doubledResult(self, value_to_set: Any):
            """Assign another attribute's value to outputs.doubledResult"""
            if isinstance(value_to_set, og.RuntimeAttribute):
                self.doubledResult.value = value_to_set.value
            else:
                self.doubledResult.value = value_to_set

        @property
        def flexible(self) -> og.RuntimeAttribute:
            """Get the runtime wrapper class for the attribute outputs.flexible"""
            return og.RuntimeAttribute(self._attributes.flexible.get_attribute_data(), self._context, False)

        @flexible.setter
        def flexible(self, value_to_set: Any):
            """Assign another attribute's value to outputs.flexible"""
            if isinstance(value_to_set, og.RuntimeAttribute):
                self.flexible.value = value_to_set.value
            else:
                self.flexible.value = value_to_set

        @property
        def negatedResult(self) -> og.RuntimeAttribute:
            """Get the runtime wrapper class for the attribute outputs.negatedResult"""
            return og.RuntimeAttribute(self._attributes.negatedResult.get_attribute_data(), self._context, False)

        @negatedResult.setter
        def negatedResult(self, value_to_set: Any):
            """Assign another attribute's value to outputs.negatedResult"""
            if isinstance(value_to_set, og.RuntimeAttribute):
                self.negatedResult.value = value_to_set.value
            else:
                self.negatedResult.value = value_to_set

        @property
        def tuple(self) -> og.RuntimeAttribute:
            """Get the runtime wrapper class for the attribute outputs.tuple"""
            return og.RuntimeAttribute(self._attributes.tuple.get_attribute_data(), self._context, False)

        @tuple.setter
        def tuple(self, value_to_set: Any):
            """Assign another attribute's value to outputs.tuple"""
            if isinstance(value_to_set, og.RuntimeAttribute):
                self.tuple.value = value_to_set.value
            else:
                self.tuple.value = value_to_set

        def _commit(self):
            _og._commit_output_attributes_data(self._batchedWriteValues)
            self._batchedWriteValues = { }

    class ValuesForState(og.DynamicAttributeAccess):
        """Helper class that creates natural hierarchical access to state attributes"""
        def __init__(self, node: og.Node, attributes, dynamic_attributes: og.DynamicAttributeInterface):
            """Initialize simplified access for the attribute data"""
            context = node.get_graph().get_default_graph_context()
            super().__init__(context, node, attributes, dynamic_attributes)

    def __init__(self, node):
        super().__init__(node)
        dynamic_attributes = self.dynamic_attribute_data(node, og.AttributePortType.ATTRIBUTE_PORT_TYPE_INPUT)
        self.inputs = OgnTutorialExtendedTypesDatabase.ValuesForInputs(node, self.attributes.inputs, dynamic_attributes)
        dynamic_attributes = self.dynamic_attribute_data(node, og.AttributePortType.ATTRIBUTE_PORT_TYPE_OUTPUT)
        self.outputs = OgnTutorialExtendedTypesDatabase.ValuesForOutputs(node, self.attributes.outputs, dynamic_attributes)
        dynamic_attributes = self.dynamic_attribute_data(node, og.AttributePortType.ATTRIBUTE_PORT_TYPE_STATE)
        self.state = OgnTutorialExtendedTypesDatabase.ValuesForState(node, self.attributes.state, dynamic_attributes)
