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

Reads the current state of the mouse. You can choose which mouse element this node is associated with. When mouse element
is chosen to be a button, only outputs:isPressed is meaningful. When coordinates are chosen, only outputs:coords and outputs:window
are meaningful.
 Pixel coordinates are the position of the mouse cursor in screen pixel units with (0,0) top left. Normalized
coordinates are values between 0-1 where 0 is top/left and 1 is bottom/right. By default, coordinates are relative to the
application window, but if 'Use Relative Coords' is set to true, then coordinates are relative to the workspace window containing
the mouse pointer.
"""

import omni.graph.core as og
import omni.graph.core._omni_graph_core as _og
import omni.graph.tools.ogn as ogn
import numpy
class OgnReadMouseStateDatabase(og.Database):
    """Helper class providing simplified access to data on nodes of type omni.graph.ui.ReadMouseState

    Class Members:
        node: Node being evaluated

    Attribute Value Properties:
        Inputs:
            inputs.mouseElement
            inputs.useRelativeCoords
        Outputs:
            outputs.coords
            outputs.isPressed
            outputs.window

    Predefined Tokens:
        tokens.LeftButton
        tokens.RightButton
        tokens.MiddleButton
        tokens.ForwardButton
        tokens.BackButton
        tokens.MouseCoordsNormalized
        tokens.MouseCoordsPixel
    """
    # 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:mouseElement', 'token', 0, 'Mouse Element', 'The mouse input to check the state of', {'displayGroup': 'parameters', ogn.MetadataKeys.ALLOWED_TOKENS: 'Left Button,Right Button,Middle Button,Forward Button,Back Button,Normalized Mouse Coordinates,Pixel Mouse Coordinates', ogn.MetadataKeys.ALLOWED_TOKENS_RAW: '{"LeftButton": "Left Button", "RightButton": "Right Button", "MiddleButton": "Middle Button", "ForwardButton": "Forward Button", "BackButton": "Back Button", "MouseCoordsNormalized": "Normalized Mouse Coordinates", "MouseCoordsPixel": "Pixel Mouse Coordinates"}', ogn.MetadataKeys.DEFAULT: '"Left Button"'}, True, 'Left Button', False, ''),
        ('inputs:useRelativeCoords', 'bool', 0, 'Use Relative Coords', "When true, the output 'coords' is made relative to the workspace window containing the\nmouse pointer instead of the entire application window", {}, True, False, False, ''),
        ('outputs:coords', 'float2', 0, None, 'The coordinates of the mouse. If the mouse element selected is a button, this will output a zero vector.', {}, True, None, False, ''),
        ('outputs:isPressed', 'bool', 0, None, 'True if the button is currently pressed, false otherwise. If the mouse element selected\nis a coordinate, this will output false.', {}, True, None, False, ''),
        ('outputs:window', 'token', 0, None, "The name of the workspace window containing the mouse pointer if 'Use Relative Coords' is true\nand the mouse element selected is a coordinate", {}, True, None, False, ''),
    ])
    class tokens:
        LeftButton = "Left Button"
        RightButton = "Right Button"
        MiddleButton = "Middle Button"
        ForwardButton = "Forward Button"
        BackButton = "Back Button"
        MouseCoordsNormalized = "Normalized Mouse Coordinates"
        MouseCoordsPixel = "Pixel Mouse Coordinates"
    class ValuesForInputs(og.DynamicAttributeAccess):
        LOCAL_PROPERTY_NAMES = {"mouseElement", "useRelativeCoords", "_setting_locked", "_batchedReadAttributes", "_batchedReadValues"}
        """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._attributes.mouseElement, self._attributes.useRelativeCoords]
            self._batchedReadValues = ["Left Button", False]

        @property
        def mouseElement(self):
            return self._batchedReadValues[0]

        @mouseElement.setter
        def mouseElement(self, value):
            self._batchedReadValues[0] = value

        @property
        def useRelativeCoords(self):
            return self._batchedReadValues[1]

        @useRelativeCoords.setter
        def useRelativeCoords(self, value):
            self._batchedReadValues[1] = value

        def __getattr__(self, item: str):
            if item in self.LOCAL_PROPERTY_NAMES:
                return object.__getattribute__(self, item)
            else:
                return super().__getattr__(item)

        def __setattr__(self, item: str, new_value):
            if item in self.LOCAL_PROPERTY_NAMES:
                object.__setattr__(self, item, new_value)
            else:
                super().__setattr__(item, new_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 = {"coords", "isPressed", "window", "_batchedWriteValues"}
        """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 coords(self):
            value = self._batchedWriteValues.get(self._attributes.coords)
            if value:
                return value
            else:
                data_view = og.AttributeValueHelper(self._attributes.coords)
                return data_view.get()

        @coords.setter
        def coords(self, value):
            self._batchedWriteValues[self._attributes.coords] = value

        @property
        def isPressed(self):
            value = self._batchedWriteValues.get(self._attributes.isPressed)
            if value:
                return value
            else:
                data_view = og.AttributeValueHelper(self._attributes.isPressed)
                return data_view.get()

        @isPressed.setter
        def isPressed(self, value):
            self._batchedWriteValues[self._attributes.isPressed] = value

        @property
        def window(self):
            value = self._batchedWriteValues.get(self._attributes.window)
            if value:
                return value
            else:
                data_view = og.AttributeValueHelper(self._attributes.window)
                return data_view.get()

        @window.setter
        def window(self, value):
            self._batchedWriteValues[self._attributes.window] = value

        def __getattr__(self, item: str):
            if item in self.LOCAL_PROPERTY_NAMES:
                return object.__getattribute__(self, item)
            else:
                return super().__getattr__(item)

        def __setattr__(self, item: str, new_value):
            if item in self.LOCAL_PROPERTY_NAMES:
                object.__setattr__(self, item, new_value)
            else:
                super().__setattr__(item, new_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 = OgnReadMouseStateDatabase.ValuesForInputs(node, self.attributes.inputs, dynamic_attributes)
        dynamic_attributes = self.dynamic_attribute_data(node, og.AttributePortType.ATTRIBUTE_PORT_TYPE_OUTPUT)
        self.outputs = OgnReadMouseStateDatabase.ValuesForOutputs(node, self.attributes.outputs, dynamic_attributes)
        dynamic_attributes = self.dynamic_attribute_data(node, og.AttributePortType.ATTRIBUTE_PORT_TYPE_STATE)
        self.state = OgnReadMouseStateDatabase.ValuesForState(node, self.attributes.state, dynamic_attributes)
