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

Event node which fires when a keyboard event occurs. The event can be a combination of keys, containing key modifiers of
ctrl, alt and shift, and a normal key of any key. keyIn.
 For key combinations, the press event requires all keys to be pressed,
with the normal key pressed last. The release event is only triggered once when one of the chosen keys released after pressed
event happens.
 For example: if the combination is ctrl-shift-D, the pressed event happens once right after D is pressed
while both ctrl and shit are held. And the release event happens only once when the user releases any key of ctrl, shift
and D while holding them.
"""


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



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

    Class Members:
        node: Node being evaluated

    Attribute Value Properties:
        Inputs:
            inputs.altIn
            inputs.ctrlIn
            inputs.keyIn
            inputs.onlyPlayback
            inputs.shiftIn
        Outputs:
            outputs.isPressed
            outputs.keyOut
            outputs.pressed
            outputs.released

    Predefined Tokens:
        tokens.A
        tokens.B
        tokens.C
        tokens.D
        tokens.E
        tokens.F
        tokens.G
        tokens.H
        tokens.I
        tokens.J
        tokens.K
        tokens.L
        tokens.M
        tokens.N
        tokens.O
        tokens.P
        tokens.Q
        tokens.R
        tokens.S
        tokens.T
        tokens.U
        tokens.V
        tokens.W
        tokens.X
        tokens.Y
        tokens.Z
        tokens.Apostrophe
        tokens.Backslash
        tokens.Backspace
        tokens.CapsLock
        tokens.Comma
        tokens.Del
        tokens.Down
        tokens.End
        tokens.Enter
        tokens.Equal
        tokens.Escape
        tokens.F1
        tokens.F10
        tokens.F11
        tokens.F12
        tokens.F2
        tokens.F3
        tokens.F4
        tokens.F5
        tokens.F6
        tokens.F7
        tokens.F8
        tokens.F9
        tokens.GraveAccent
        tokens.Home
        tokens.Insert
        tokens.Key0
        tokens.Key1
        tokens.Key2
        tokens.Key3
        tokens.Key4
        tokens.Key5
        tokens.Key6
        tokens.Key7
        tokens.Key8
        tokens.Key9
        tokens.Left
        tokens.LeftAlt
        tokens.LeftBracket
        tokens.LeftControl
        tokens.LeftShift
        tokens.LeftSuper
        tokens.Menu
        tokens.Minus
        tokens.NumLock
        tokens.Numpad0
        tokens.Numpad1
        tokens.Numpad2
        tokens.Numpad3
        tokens.Numpad4
        tokens.Numpad5
        tokens.Numpad6
        tokens.Numpad7
        tokens.Numpad8
        tokens.Numpad9
        tokens.NumpadAdd
        tokens.NumpadDel
        tokens.NumpadDivide
        tokens.NumpadEnter
        tokens.NumpadEqual
        tokens.NumpadMultiply
        tokens.NumpadSubtract
        tokens.PageDown
        tokens.PageUp
        tokens.Pause
        tokens.Period
        tokens.PrintScreen
        tokens.Right
        tokens.RightAlt
        tokens.RightBracket
        tokens.RightControl
        tokens.RightShift
        tokens.RightSuper
        tokens.ScrollLock
        tokens.Semicolon
        tokens.Slash
        tokens.Space
        tokens.Tab
        tokens.Up
    """

    # 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:altIn', 'bool', 0, 'Alt', 'When true, the node will check with a key modifier Alt', {ogn.MetadataKeys.LITERAL_ONLY: '1'}, True, False, False, ''),
        ('inputs:ctrlIn', 'bool', 0, 'Ctrl', 'When true, the node will check with a key modifier Control', {ogn.MetadataKeys.LITERAL_ONLY: '1'}, True, False, False, ''),
        ('inputs:keyIn', 'token', 0, 'Key In', 'The key to trigger the downstream execution ', {'displayGroup': 'parameters', ogn.MetadataKeys.LITERAL_ONLY: '1', ogn.MetadataKeys.ALLOWED_TOKENS: 'A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,Apostrophe,Backslash,Backspace,CapsLock,Comma,Del,Down,End,Enter,Equal,Escape,F1,F10,F11,F12,F2,F3,F4,F5,F6,F7,F8,F9,GraveAccent,Home,Insert,Key0,Key1,Key2,Key3,Key4,Key5,Key6,Key7,Key8,Key9,Left,LeftAlt,LeftBracket,LeftControl,LeftShift,LeftSuper,Menu,Minus,NumLock,Numpad0,Numpad1,Numpad2,Numpad3,Numpad4,Numpad5,Numpad6,Numpad7,Numpad8,Numpad9,NumpadAdd,NumpadDel,NumpadDivide,NumpadEnter,NumpadEqual,NumpadMultiply,NumpadSubtract,PageDown,PageUp,Pause,Period,PrintScreen,Right,RightAlt,RightBracket,RightControl,RightShift,RightSuper,ScrollLock,Semicolon,Slash,Space,Tab,Up', ogn.MetadataKeys.ALLOWED_TOKENS_RAW: '["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "Apostrophe", "Backslash", "Backspace", "CapsLock", "Comma", "Del", "Down", "End", "Enter", "Equal", "Escape", "F1", "F10", "F11", "F12", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "GraveAccent", "Home", "Insert", "Key0", "Key1", "Key2", "Key3", "Key4", "Key5", "Key6", "Key7", "Key8", "Key9", "Left", "LeftAlt", "LeftBracket", "LeftControl", "LeftShift", "LeftSuper", "Menu", "Minus", "NumLock", "Numpad0", "Numpad1", "Numpad2", "Numpad3", "Numpad4", "Numpad5", "Numpad6", "Numpad7", "Numpad8", "Numpad9", "NumpadAdd", "NumpadDel", "NumpadDivide", "NumpadEnter", "NumpadEqual", "NumpadMultiply", "NumpadSubtract", "PageDown", "PageUp", "Pause", "Period", "PrintScreen", "Right", "RightAlt", "RightBracket", "RightControl", "RightShift", "RightSuper", "ScrollLock", "Semicolon", "Slash", "Space", "Tab", "Up"]', ogn.MetadataKeys.DEFAULT: '"A"'}, True, "A", False, ''),
        ('inputs:onlyPlayback', 'bool', 0, 'Only Simulate On Play', 'When true, the node is only computed while Stage is being played.', {ogn.MetadataKeys.LITERAL_ONLY: '1', ogn.MetadataKeys.DEFAULT: 'true'}, True, True, False, ''),
        ('inputs:shiftIn', 'bool', 0, 'Shift', 'When true, the node will check with a key modifier Shift', {ogn.MetadataKeys.LITERAL_ONLY: '1'}, True, False, False, ''),
        ('outputs:isPressed', 'bool', 0, None, 'True if the key was pressed, False if it was released', {}, True, None, False, ''),
        ('outputs:keyOut', 'token', 0, 'Key Out', 'The key that was pressed or released', {}, True, None, False, ''),
        ('outputs:pressed', 'execution', 0, 'Pressed', 'Executes when key was pressed', {}, True, None, False, ''),
        ('outputs:released', 'execution', 0, 'Released', 'Executes when key was released', {}, True, None, False, ''),
    ])

    class tokens:
        A = "A"
        B = "B"
        C = "C"
        D = "D"
        E = "E"
        F = "F"
        G = "G"
        H = "H"
        I = "I"
        J = "J"
        K = "K"
        L = "L"
        M = "M"
        N = "N"
        O = "O"
        P = "P"
        Q = "Q"
        R = "R"
        S = "S"
        T = "T"
        U = "U"
        V = "V"
        W = "W"
        X = "X"
        Y = "Y"
        Z = "Z"
        Apostrophe = "Apostrophe"
        Backslash = "Backslash"
        Backspace = "Backspace"
        CapsLock = "CapsLock"
        Comma = "Comma"
        Del = "Del"
        Down = "Down"
        End = "End"
        Enter = "Enter"
        Equal = "Equal"
        Escape = "Escape"
        F1 = "F1"
        F10 = "F10"
        F11 = "F11"
        F12 = "F12"
        F2 = "F2"
        F3 = "F3"
        F4 = "F4"
        F5 = "F5"
        F6 = "F6"
        F7 = "F7"
        F8 = "F8"
        F9 = "F9"
        GraveAccent = "GraveAccent"
        Home = "Home"
        Insert = "Insert"
        Key0 = "Key0"
        Key1 = "Key1"
        Key2 = "Key2"
        Key3 = "Key3"
        Key4 = "Key4"
        Key5 = "Key5"
        Key6 = "Key6"
        Key7 = "Key7"
        Key8 = "Key8"
        Key9 = "Key9"
        Left = "Left"
        LeftAlt = "LeftAlt"
        LeftBracket = "LeftBracket"
        LeftControl = "LeftControl"
        LeftShift = "LeftShift"
        LeftSuper = "LeftSuper"
        Menu = "Menu"
        Minus = "Minus"
        NumLock = "NumLock"
        Numpad0 = "Numpad0"
        Numpad1 = "Numpad1"
        Numpad2 = "Numpad2"
        Numpad3 = "Numpad3"
        Numpad4 = "Numpad4"
        Numpad5 = "Numpad5"
        Numpad6 = "Numpad6"
        Numpad7 = "Numpad7"
        Numpad8 = "Numpad8"
        Numpad9 = "Numpad9"
        NumpadAdd = "NumpadAdd"
        NumpadDel = "NumpadDel"
        NumpadDivide = "NumpadDivide"
        NumpadEnter = "NumpadEnter"
        NumpadEqual = "NumpadEqual"
        NumpadMultiply = "NumpadMultiply"
        NumpadSubtract = "NumpadSubtract"
        PageDown = "PageDown"
        PageUp = "PageUp"
        Pause = "Pause"
        Period = "Period"
        PrintScreen = "PrintScreen"
        Right = "Right"
        RightAlt = "RightAlt"
        RightBracket = "RightBracket"
        RightControl = "RightControl"
        RightShift = "RightShift"
        RightSuper = "RightSuper"
        ScrollLock = "ScrollLock"
        Semicolon = "Semicolon"
        Slash = "Slash"
        Space = "Space"
        Tab = "Tab"
        Up = "Up"

    @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.outputs.pressed = og.AttributeRole.EXECUTION
        role_data.outputs.released = 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 altIn(self):
            data_view = og.AttributeValueHelper(self._attributes.altIn)
            return data_view.get()

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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