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

Easing function which iterpolates between a start and end value. Vectors are eased component-wise. The easing functions can
be applied to decimal types. Linear: Interpolates between start and finish at a fixed rate. EaseIn: Starts slowly and ends
fast according to an exponential, the slope is determined by the 'exponent' input. EaseOut: Same as EaseIn, but starts fast
and ends slow EaseInOut: Combines EaseIn and EaseOut SinIn: Starts slowly and ends fast according to a sinusoidal curve SinOut:
Same as SinIn, but starts fast and ends slow SinInOut: Combines SinIn and SinOut
"""

from typing import Any

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



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

    Class Members:
        node: Node being evaluated

    Attribute Value Properties:
        Inputs:
            inputs.alpha
            inputs.blendExponent
            inputs.easeFunc
            inputs.end
            inputs.start
        Outputs:
            outputs.result

    Predefined Tokens:
        tokens.EaseIn
        tokens.EaseOut
        tokens.EaseInOut
        tokens.Linear
        tokens.SinIn
        tokens.SinOut
        tokens.SinInOut
    """

    # 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:alpha', 'float,float[]', 1, None, 'The normalized time (0 - 1.0). Values outside this range will be clamped', {}, True, None, False, ''),
        ('inputs:blendExponent', 'int', 0, None, 'The blend exponent, which is the degree of the ease curve\n (1 = linear, 2 = quadratic, 3 = cubic, etc). \nThis only applies to the Ease* functions', {ogn.MetadataKeys.DEFAULT: '2'}, True, 2, False, ''),
        ('inputs:easeFunc', 'token', 0, 'Operation', 'The easing function to apply (EaseIn, EaseOut, EaseInOut, Linear, SinIn, SinOut, SinInOut)', {ogn.MetadataKeys.ALLOWED_TOKENS: 'EaseIn,EaseOut,EaseInOut,Linear,SinIn,SinOut,SinInOut', ogn.MetadataKeys.ALLOWED_TOKENS_RAW: '["EaseIn", "EaseOut", "EaseInOut", "Linear", "SinIn", "SinOut", "SinInOut"]', ogn.MetadataKeys.DEFAULT: '"EaseInOut"'}, True, "EaseInOut", False, ''),
        ('inputs:end', 'colord[3],colord[3][],colord[4],colord[4][],colorf[3],colorf[3][],colorf[4],colorf[4][],colorh[3],colorh[3][],colorh[4],colorh[4][],double,double[2],double[2][],double[3],double[3][],double[4],double[4][],double[],float,float[2],float[2][],float[3],float[3][],float[4],float[4][],float[],half,half[2],half[2][],half[3],half[3][],half[4],half[4][],half[],normald[3],normald[3][],normalf[3],normalf[3][],normalh[3],normalh[3][],pointd[3],pointd[3][],pointf[3],pointf[3][],pointh[3],pointh[3][],quatd[4],quatd[4][],quatf[4],quatf[4][],quath[4],quath[4][],texcoordd[2],texcoordd[2][],texcoordd[3],texcoordd[3][],texcoordf[2],texcoordf[2][],texcoordf[3],texcoordf[3][],texcoordh[2],texcoordh[2][],texcoordh[3],texcoordh[3][],timecode,timecode[],vectord[3],vectord[3][],vectorf[3],vectorf[3][],vectorh[3],vectorh[3][]', 1, None, 'The end value', {}, True, None, False, ''),
        ('inputs:start', 'colord[3],colord[3][],colord[4],colord[4][],colorf[3],colorf[3][],colorf[4],colorf[4][],colorh[3],colorh[3][],colorh[4],colorh[4][],double,double[2],double[2][],double[3],double[3][],double[4],double[4][],double[],float,float[2],float[2][],float[3],float[3][],float[4],float[4][],float[],half,half[2],half[2][],half[3],half[3][],half[4],half[4][],half[],normald[3],normald[3][],normalf[3],normalf[3][],normalh[3],normalh[3][],pointd[3],pointd[3][],pointf[3],pointf[3][],pointh[3],pointh[3][],quatd[4],quatd[4][],quatf[4],quatf[4][],quath[4],quath[4][],texcoordd[2],texcoordd[2][],texcoordd[3],texcoordd[3][],texcoordf[2],texcoordf[2][],texcoordf[3],texcoordf[3][],texcoordh[2],texcoordh[2][],texcoordh[3],texcoordh[3][],timecode,timecode[],vectord[3],vectord[3][],vectorf[3],vectorf[3][],vectorh[3],vectorh[3][]', 1, None, 'The start value', {}, True, None, False, ''),
        ('outputs:result', 'colord[3],colord[3][],colord[4],colord[4][],colorf[3],colorf[3][],colorf[4],colorf[4][],colorh[3],colorh[3][],colorh[4],colorh[4][],double,double[2],double[2][],double[3],double[3][],double[4],double[4][],double[],float,float[2],float[2][],float[3],float[3][],float[4],float[4][],float[],half,half[2],half[2][],half[3],half[3][],half[4],half[4][],half[],normald[3],normald[3][],normalf[3],normalf[3][],normalh[3],normalh[3][],pointd[3],pointd[3][],pointf[3],pointf[3][],pointh[3],pointh[3][],quatd[4],quatd[4][],quatf[4],quatf[4][],quath[4],quath[4][],texcoordd[2],texcoordd[2][],texcoordd[3],texcoordd[3][],texcoordf[2],texcoordf[2][],texcoordf[3],texcoordf[3][],texcoordh[2],texcoordh[2][],texcoordh[3],texcoordh[3][],timecode,timecode[],vectord[3],vectord[3][],vectorf[3],vectorf[3][],vectorh[3],vectorh[3][]', 1, 'Result', 'The eased result of the function applied to value', {}, True, None, False, ''),
    ])

    class tokens:
        EaseIn = "EaseIn"
        EaseOut = "EaseOut"
        EaseInOut = "EaseInOut"
        Linear = "Linear"
        SinIn = "SinIn"
        SinOut = "SinOut"
        SinInOut = "SinInOut"

    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 alpha(self) -> og.RuntimeAttribute:
            """Get the runtime wrapper class for the attribute inputs.alpha"""
            return og.RuntimeAttribute(self._attributes.alpha.get_attribute_data(), self._context, True)

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

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

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

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

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

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

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

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

        @start.setter
        def start(self, value_to_set: Any):
            """Assign another attribute's value to outputs.start"""
            if isinstance(value_to_set, og.RuntimeAttribute):
                self.start.value = value_to_set.value
            else:
                self.start.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 result(self) -> og.RuntimeAttribute:
            """Get the runtime wrapper class for the attribute outputs.result"""
            return og.RuntimeAttribute(self._attributes.result.get_attribute_data(), self._context, False)

        @result.setter
        def result(self, value_to_set: Any):
            """Assign another attribute's value to outputs.result"""
            if isinstance(value_to_set, og.RuntimeAttribute):
                self.result.value = value_to_set.value
            else:
                self.result.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 = OgnEaseDatabase.ValuesForInputs(node, self.attributes.inputs, dynamic_attributes)
        dynamic_attributes = self.dynamic_attribute_data(node, og.AttributePortType.ATTRIBUTE_PORT_TYPE_OUTPUT)
        self.outputs = OgnEaseDatabase.ValuesForOutputs(node, self.attributes.outputs, dynamic_attributes)
        dynamic_attributes = self.dynamic_attribute_data(node, og.AttributePortType.ATTRIBUTE_PORT_TYPE_STATE)
        self.state = OgnEaseDatabase.ValuesForState(node, self.attributes.state, dynamic_attributes)
