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

This is a tutorial node. It creates both an input and output attribute of some of the supported  tuple types. The values
are modified in a simple way so that the compute can be tested.
"""

import carb
import numpy

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



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

    Class Members:
        node: Node being evaluated

    Attribute Value Properties:
        Inputs:
            inputs.a_double2
            inputs.a_double3
            inputs.a_float2
            inputs.a_float3
            inputs.a_half2
            inputs.a_int2
        Outputs:
            outputs.a_double2
            outputs.a_double3
            outputs.a_float2
            outputs.a_float3
            outputs.a_half2
            outputs.a_int2
    """

    # 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:a_double2', 'double2', 0, None, 'This is an attribute with two double values', {ogn.MetadataKeys.DEFAULT: '[1.1, 2.2]'}, True, [1.1, 2.2], False, ''),
        ('inputs:a_double3', 'double3', 0, None, 'This is an attribute with three double values', {ogn.MetadataKeys.DEFAULT: '[1.1, 2.2, 3.3]'}, True, [1.1, 2.2, 3.3], False, ''),
        ('inputs:a_float2', 'float2', 0, None, 'This is an attribute with two float values', {ogn.MetadataKeys.DEFAULT: '[4.4, 5.5]'}, True, [4.4, 5.5], False, ''),
        ('inputs:a_float3', 'float3', 0, None, 'This is an attribute with three float values', {ogn.MetadataKeys.DEFAULT: '[6.6, 7.7, 8.8]'}, True, [6.6, 7.7, 8.8], False, ''),
        ('inputs:a_half2', 'half2', 0, None, 'This is an attribute with two 16-bit float values', {ogn.MetadataKeys.DEFAULT: '[7.0, 8.0]'}, True, [7.0, 8.0], False, ''),
        ('inputs:a_int2', 'int2', 0, None, 'This is an attribute with two 32-bit integer values', {ogn.MetadataKeys.DEFAULT: '[10, 11]'}, True, [10, 11], False, ''),
        ('outputs:a_double2', 'double2', 0, None, 'This is a computed attribute with two double values', {}, True, None, False, ''),
        ('outputs:a_double3', 'double3', 0, None, 'This is a computed attribute with three double values', {}, True, None, False, ''),
        ('outputs:a_float2', 'float2', 0, None, 'This is a computed attribute with two float values', {}, True, None, False, ''),
        ('outputs:a_float3', 'float3', 0, None, 'This is a computed attribute with three float values', {}, True, None, False, ''),
        ('outputs:a_half2', 'half2', 0, None, 'This is a computed attribute with two 16-bit float values', {}, True, None, False, ''),
        ('outputs:a_int2', 'int2', 0, None, 'This is a computed attribute with two 32-bit integer values', {}, 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 a_double2(self):
            data_view = og.AttributeValueHelper(self._attributes.a_double2)
            return data_view.get()

        @a_double2.setter
        def a_double2(self, value):
            if self._setting_locked:
                raise og.ReadOnlyError(self._attributes.a_double2)
            data_view = og.AttributeValueHelper(self._attributes.a_double2)
            data_view.set(value)

        @property
        def a_double3(self):
            data_view = og.AttributeValueHelper(self._attributes.a_double3)
            return data_view.get()

        @a_double3.setter
        def a_double3(self, value):
            if self._setting_locked:
                raise og.ReadOnlyError(self._attributes.a_double3)
            data_view = og.AttributeValueHelper(self._attributes.a_double3)
            data_view.set(value)

        @property
        def a_float2(self):
            data_view = og.AttributeValueHelper(self._attributes.a_float2)
            return data_view.get()

        @a_float2.setter
        def a_float2(self, value):
            if self._setting_locked:
                raise og.ReadOnlyError(self._attributes.a_float2)
            data_view = og.AttributeValueHelper(self._attributes.a_float2)
            data_view.set(value)

        @property
        def a_float3(self):
            data_view = og.AttributeValueHelper(self._attributes.a_float3)
            return data_view.get()

        @a_float3.setter
        def a_float3(self, value):
            if self._setting_locked:
                raise og.ReadOnlyError(self._attributes.a_float3)
            data_view = og.AttributeValueHelper(self._attributes.a_float3)
            data_view.set(value)

        @property
        def a_half2(self):
            data_view = og.AttributeValueHelper(self._attributes.a_half2)
            return data_view.get()

        @a_half2.setter
        def a_half2(self, value):
            if self._setting_locked:
                raise og.ReadOnlyError(self._attributes.a_half2)
            data_view = og.AttributeValueHelper(self._attributes.a_half2)
            data_view.set(value)

        @property
        def a_int2(self):
            data_view = og.AttributeValueHelper(self._attributes.a_int2)
            return data_view.get()

        @a_int2.setter
        def a_int2(self, value):
            if self._setting_locked:
                raise og.ReadOnlyError(self._attributes.a_int2)
            data_view = og.AttributeValueHelper(self._attributes.a_int2)
            data_view.set(value)

        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 a_double2(self):
            data_view = og.AttributeValueHelper(self._attributes.a_double2)
            return data_view.get()

        @a_double2.setter
        def a_double2(self, value):
            data_view = og.AttributeValueHelper(self._attributes.a_double2)
            data_view.set(value)

        @property
        def a_double3(self):
            data_view = og.AttributeValueHelper(self._attributes.a_double3)
            return data_view.get()

        @a_double3.setter
        def a_double3(self, value):
            data_view = og.AttributeValueHelper(self._attributes.a_double3)
            data_view.set(value)

        @property
        def a_float2(self):
            data_view = og.AttributeValueHelper(self._attributes.a_float2)
            return data_view.get()

        @a_float2.setter
        def a_float2(self, value):
            data_view = og.AttributeValueHelper(self._attributes.a_float2)
            data_view.set(value)

        @property
        def a_float3(self):
            data_view = og.AttributeValueHelper(self._attributes.a_float3)
            return data_view.get()

        @a_float3.setter
        def a_float3(self, value):
            data_view = og.AttributeValueHelper(self._attributes.a_float3)
            data_view.set(value)

        @property
        def a_half2(self):
            data_view = og.AttributeValueHelper(self._attributes.a_half2)
            return data_view.get()

        @a_half2.setter
        def a_half2(self, value):
            data_view = og.AttributeValueHelper(self._attributes.a_half2)
            data_view.set(value)

        @property
        def a_int2(self):
            data_view = og.AttributeValueHelper(self._attributes.a_int2)
            return data_view.get()

        @a_int2.setter
        def a_int2(self, value):
            data_view = og.AttributeValueHelper(self._attributes.a_int2)
            data_view.set(value)

        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 = OgnTutorialTupleDataDatabase.ValuesForInputs(node, self.attributes.inputs, dynamic_attributes)
        dynamic_attributes = self.dynamic_attribute_data(node, og.AttributePortType.ATTRIBUTE_PORT_TYPE_OUTPUT)
        self.outputs = OgnTutorialTupleDataDatabase.ValuesForOutputs(node, self.attributes.outputs, dynamic_attributes)
        dynamic_attributes = self.dynamic_attribute_data(node, og.AttributePortType.ATTRIBUTE_PORT_TYPE_STATE)
        self.state = OgnTutorialTupleDataDatabase.ValuesForState(node, self.attributes.state, dynamic_attributes)
