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

This node smoothly rotates a prim object to match a target prim object given a speed and easing factor.  At the end of the
maneuver, the source prim will have the rotation as the target prim.
 Note: The Prim must have xform:orient in transform
stack in order to interpolate rotations
"""

import usdrt

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



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

    Class Members:
        node: Node being evaluated

    Attribute Value Properties:
        Inputs:
            inputs.execIn
            inputs.exponent
            inputs.sourcePrim
            inputs.sourcePrimPath
            inputs.speed
            inputs.stop
            inputs.targetPrim
            inputs.targetPrimPath
            inputs.useSourcePath
            inputs.useTargetPath
        Outputs:
            outputs.finished
    """

    # 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:execIn', 'execution', 0, 'Execute In', 'The input execution', {}, True, None, False, ''),
        ('inputs:exponent', 'float', 0, None, 'The blend exponent, which is the degree of the ease curve\n (1 = linear, 2 = quadratic, 3 = cubic, etc). ', {ogn.MetadataKeys.DEFAULT: '2.0'}, True, 2.0, False, ''),
        ('inputs:sourcePrim', 'target', 0, None, 'The source prim to be transformed', {}, False, [], False, ''),
        ('inputs:sourcePrimPath', 'path', 0, None, "The source prim to be transformed, used when 'useSourcePath' is true", {}, False, None, False, ''),
        ('inputs:speed', 'double', 0, None, 'The peak speed of approach (Units / Second)', {ogn.MetadataKeys.DEFAULT: '1.0'}, True, 1.0, False, ''),
        ('inputs:stop', 'execution', 0, 'Stop', 'Stops the maneuver', {}, True, None, False, ''),
        ('inputs:targetPrim', 'target', 0, None, "The destination prim. The target's rotation will be matched by the sourcePrim", {}, False, [], False, ''),
        ('inputs:targetPrimPath', 'path', 0, None, "The destination prim. The target's rotation will be matched by the sourcePrim, used when 'useTargetPath' is true", {}, False, None, False, ''),
        ('inputs:useSourcePath', 'bool', 0, None, "When true, the 'sourcePrimPath' attribute is used, otherwise it will read the connection at the 'sourcePrim' attribute", {ogn.MetadataKeys.DEFAULT: 'false'}, True, False, False, ''),
        ('inputs:useTargetPath', 'bool', 0, None, "When true, the 'targetPrimPath' attribute is used, otherwise it will read the connection at the 'targetPrim' attribute", {ogn.MetadataKeys.DEFAULT: 'false'}, True, False, False, ''),
        ('outputs:finished', 'execution', 0, 'Finished', 'The output execution, sent one the maneuver is completed', {}, 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.execIn = og.AttributeRole.EXECUTION
        role_data.inputs.sourcePrim = og.AttributeRole.TARGET
        role_data.inputs.sourcePrimPath = og.AttributeRole.PATH
        role_data.inputs.stop = og.AttributeRole.EXECUTION
        role_data.inputs.targetPrim = og.AttributeRole.TARGET
        role_data.inputs.targetPrimPath = og.AttributeRole.PATH
        role_data.outputs.finished = og.AttributeRole.EXECUTION
        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 execIn(self):
            data_view = og.AttributeValueHelper(self._attributes.execIn)
            return data_view.get()

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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