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

DEPRECATED - use ReadPrimAttributes!
"""


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

    Class Members:
        node: Node being evaluated

    Attribute Value Properties:
        Inputs:
            inputs.attrNamesToImport
            inputs.computeBoundingBox
            inputs.prim
            inputs.usdTimecode
        Outputs:
            outputs.primBundle
        State:
            state.attrNamesToImport
            state.computeBoundingBox
            state.primPath
            state.primTypes
            state.usdTimecode
    """

    # 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:attrNamesToImport', 'token', 0, 'Attributes To Import', "A list of wildcard patterns used to match the attribute names that are to be imported\n\nSupported syntax of wildcard pattern:\n    '*' - match an arbitrary number of any characters\n    '?' - match any single character\n    '^' - (caret) is used to define a pattern that is to be excluded\n\nExample of wildcard patterns, input: ['points', 'faceVertexCount', 'faceVertexIndices', 'size']\n    '*' - match any\n    '* ^points' - match any, but exclude 'points'\n    '* ^face*' - match any, but exclude 'faceVertexCount' and 'faceVertexIndices'", {ogn.MetadataKeys.DEFAULT: '"*"'}, True, "*", False, ''),
        ('inputs:computeBoundingBox', 'bool', 0, 'Compute Bounding Box', "For each primitive compute local bounding box and store them as 'bboxMinCorner', 'bboxMaxCorner' and 'bboxTransform' attributes.", {ogn.MetadataKeys.DEFAULT: 'false'}, True, False, False, ''),
        ('inputs:prim', 'bundle', 0, None, "The prims to be read from when 'usePathPattern' is false", {}, False, None, False, ''),
        ('inputs:usdTimecode', 'timecode', 0, 'Time', 'The time at which to evaluate the transform of the USD prim. A value of "NaN" indicates that the default USD time stamp should be used', {ogn.MetadataKeys.DEFAULT: '"NaN"'}, True, float("NaN"), False, ''),
        ('outputs:primBundle', 'bundle', 0, None, 'A bundle of the target Prim attributes.\nIn addition to the data attributes, there is a token attribute named sourcePrimPath\nwhich contains the path of the Prim being read', {}, True, None, False, ''),
        ('state:attrNamesToImport', 'uint64', 0, None, 'State from previous evaluation', {}, True, None, False, ''),
        ('state:computeBoundingBox', 'bool', 0, None, 'State from previous evaluation', {ogn.MetadataKeys.DEFAULT: 'false'}, True, False, False, ''),
        ('state:primPath', 'uint64', 0, None, 'State from previous evaluation', {}, True, None, False, ''),
        ('state:primTypes', 'uint64', 0, None, 'State from previous evaluation', {}, True, None, False, ''),
        ('state:usdTimecode', 'timecode', 0, None, 'State from previous evaluation', {ogn.MetadataKeys.DEFAULT: '"NaN"'}, True, float("NaN"), 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.prim = og.AttributeRole.BUNDLE
        role_data.inputs.usdTimecode = og.AttributeRole.TIMECODE
        role_data.outputs.primBundle = og.AttributeRole.BUNDLE
        role_data.state.usdTimecode = og.AttributeRole.TIMECODE
        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.__bundles = og.BundleContainer(context, node, attributes, [], read_only=True, gpu_ptr_kinds={})
            self._batchedReadAttributes = []
            self._batchedReadValues = []

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

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

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

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

        @property
        def prim(self) -> og.BundleContents:
            """Get the bundle wrapper class for the attribute inputs.prim"""
            return self.__bundles.prim

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

        @usdTimecode.setter
        def usdTimecode(self, value):
            if self._setting_locked:
                raise og.ReadOnlyError(self._attributes.usdTimecode)
            data_view = og.AttributeValueHelper(self._attributes.usdTimecode)
            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.__bundles = og.BundleContainer(context, node, attributes, [], read_only=False, gpu_ptr_kinds={})
            self._batchedWriteValues = { }

        @property
        def primBundle(self) -> og.BundleContents:
            """Get the bundle wrapper class for the attribute outputs.primBundle"""
            return self.__bundles.primBundle

        @primBundle.setter
        def primBundle(self, bundle: og.BundleContents):
            """Overwrite the bundle attribute outputs.primBundle with a new bundle"""
            if not isinstance(bundle, og.BundleContents):
                carb.log_error("Only bundle attributes can be assigned to another bundle attribute")
            self.__bundles.primBundle.bundle = bundle

        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)

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

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

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

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

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

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

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

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

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

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

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