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

This is a tutorial node. It will move the values of inputs to corresponding outputs. Inputs all have unspecified, and therefore
empty, default values.
"""

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 OgnTutorialDefaultsDatabase(og.Database):
    """Helper class providing simplified access to data on nodes of type omni.graph.tutorials.Defaults

    Class Members:
        node: Node being evaluated

    Attribute Value Properties:
        Inputs:
            inputs.a_array
            inputs.a_bool
            inputs.a_double
            inputs.a_float
            inputs.a_half
            inputs.a_int
            inputs.a_int2
            inputs.a_int64
            inputs.a_matrix
            inputs.a_string
            inputs.a_token
            inputs.a_uchar
            inputs.a_uint
            inputs.a_uint64
        Outputs:
            outputs.a_array
            outputs.a_bool
            outputs.a_double
            outputs.a_float
            outputs.a_half
            outputs.a_int
            outputs.a_int2
            outputs.a_int64
            outputs.a_matrix
            outputs.a_string
            outputs.a_token
            outputs.a_uchar
            outputs.a_uint
            outputs.a_uint64
    """

    # 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_array', 'float[]', 0, None, 'This is an attribute of type array of floats', {}, True, [], False, ''),
        ('inputs:a_bool', 'bool', 0, None, 'This is an attribute of type boolean', {}, True, False, False, ''),
        ('inputs:a_double', 'double', 0, None, 'This is an attribute of type 64 bit floating point', {}, True, 0.0, False, ''),
        ('inputs:a_float', 'float', 0, None, 'This is an attribute of type 32 bit floating point', {}, True, 0.0, False, ''),
        ('inputs:a_half', 'half', 0, None, 'This is an attribute of type 16 bit floating point', {}, True, 0.0, False, ''),
        ('inputs:a_int', 'int', 0, None, 'This is an attribute of type 32 bit integer', {}, True, 0, False, ''),
        ('inputs:a_int2', 'int2', 0, None, 'This is an attribute of type 2-tuple of integers', {}, True, [0, 0], False, ''),
        ('inputs:a_int64', 'int64', 0, None, 'This is an attribute of type 64 bit integer', {}, True, 0, False, ''),
        ('inputs:a_matrix', 'matrix2d', 0, None, 'This is an attribute of type 2x2 matrix', {}, True, [[1.0, 0.0], [0.0, 1.0]], False, ''),
        ('inputs:a_string', 'string', 0, None, 'This is an attribute of type string', {}, True, "", False, ''),
        ('inputs:a_token', 'token', 0, None, 'This is an attribute of type interned string with fast comparison and hashing', {}, True, "", False, ''),
        ('inputs:a_uchar', 'uchar', 0, None, 'This is an attribute of type unsigned 8 bit integer', {}, True, 0, False, ''),
        ('inputs:a_uint', 'uint', 0, None, 'This is an attribute of type unsigned 32 bit integer', {}, True, 0, False, ''),
        ('inputs:a_uint64', 'uint64', 0, None, 'This is an attribute of type unsigned 64 bit integer', {}, True, 0, False, ''),
        ('outputs:a_array', 'float[]', 0, None, 'This is a computed attribute of type array of floats', {}, True, None, False, ''),
        ('outputs:a_bool', 'bool', 0, None, 'This is a computed attribute of type boolean', {}, True, None, False, ''),
        ('outputs:a_double', 'double', 0, None, 'This is a computed attribute of type 64 bit floating point', {}, True, None, False, ''),
        ('outputs:a_float', 'float', 0, None, 'This is a computed attribute of type 32 bit floating point', {}, True, None, False, ''),
        ('outputs:a_half', 'half', 0, None, 'This is a computed attribute of type 16 bit floating point', {}, True, None, False, ''),
        ('outputs:a_int', 'int', 0, None, 'This is a computed attribute of type 32 bit integer', {}, True, None, False, ''),
        ('outputs:a_int2', 'int2', 0, None, 'This is a computed attribute of type 2-tuple of integers', {}, True, None, False, ''),
        ('outputs:a_int64', 'int64', 0, None, 'This is a computed attribute of type 64 bit integer', {}, True, None, False, ''),
        ('outputs:a_matrix', 'matrix2d', 0, None, 'This is a computed attribute of type 2x2 matrix', {}, True, None, False, ''),
        ('outputs:a_string', 'string', 0, None, 'This is a computed attribute of type string', {}, True, None, False, ''),
        ('outputs:a_token', 'token', 0, None, 'This is a computed attribute of type interned string with fast comparison and hashing', {}, True, None, False, ''),
        ('outputs:a_uchar', 'uchar', 0, None, 'This is a computed attribute of type unsigned 8 bit integer', {}, True, None, False, ''),
        ('outputs:a_uint', 'uint', 0, None, 'This is a computed attribute of type unsigned 32 bit integer', {}, True, None, False, ''),
        ('outputs:a_uint64', 'uint64', 0, None, 'This is a computed attribute of type unsigned 64 bit integer', {}, True, None, False, ''),
    ])

    @classmethod
    def _populate_role_data(cls):
        """Populate a role structure with the non-default roles on this node type"""
        role_data = super()._populate_role_data()
        role_data.inputs.a_matrix = og.AttributeRole.MATRIX
        role_data.inputs.a_string = og.AttributeRole.TEXT
        role_data.outputs.a_matrix = og.AttributeRole.MATRIX
        role_data.outputs.a_string = og.AttributeRole.TEXT
        return role_data

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

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

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

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

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

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

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

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

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

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

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

        @a_int.setter
        def a_int(self, value):
            if self._setting_locked:
                raise og.ReadOnlyError(self._attributes.a_int)
            data_view = og.AttributeValueHelper(self._attributes.a_int)
            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)

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

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

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

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

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

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

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

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

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

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

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

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

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

        @a_uint64.setter
        def a_uint64(self, value):
            if self._setting_locked:
                raise og.ReadOnlyError(self._attributes.a_uint64)
            data_view = og.AttributeValueHelper(self._attributes.a_uint64)
            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.a_array_size = None
            self.a_string_size = None
            self._batchedWriteValues = { }

        @property
        def a_array(self):
            data_view = og.AttributeValueHelper(self._attributes.a_array)
            return data_view.get(reserved_element_count=self.a_array_size)

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

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

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

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

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

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

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

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

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

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

        @a_int.setter
        def a_int(self, value):
            data_view = og.AttributeValueHelper(self._attributes.a_int)
            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)

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

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

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

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

        @property
        def a_string(self):
            data_view = og.AttributeValueHelper(self._attributes.a_string)
            return data_view.get(reserved_element_count=self.a_string_size)

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

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

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

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

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

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

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

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

        @a_uint64.setter
        def a_uint64(self, value):
            data_view = og.AttributeValueHelper(self._attributes.a_uint64)
            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 = OgnTutorialDefaultsDatabase.ValuesForInputs(node, self.attributes.inputs, dynamic_attributes)
        dynamic_attributes = self.dynamic_attribute_data(node, og.AttributePortType.ATTRIBUTE_PORT_TYPE_OUTPUT)
        self.outputs = OgnTutorialDefaultsDatabase.ValuesForOutputs(node, self.attributes.outputs, dynamic_attributes)
        dynamic_attributes = self.dynamic_attribute_data(node, og.AttributePortType.ATTRIBUTE_PORT_TYPE_STATE)
        self.state = OgnTutorialDefaultsDatabase.ValuesForState(node, self.attributes.state, dynamic_attributes)
