/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/
export var conf = {
    comments: {
        lineComment: "'",
        blockComment: ['/*', '*/']
    },
    brackets: [
        ['{', '}'],
        ['[', ']'],
        ['(', ')'],
        ['<', '>'],
        ['addhandler', 'end addhandler'],
        ['class', 'end class'],
        ['enum', 'end enum'],
        ['event', 'end event'],
        ['function', 'end function'],
        ['get', 'end get'],
        ['if', 'end if'],
        ['interface', 'end interface'],
        ['module', 'end module'],
        ['namespace', 'end namespace'],
        ['operator', 'end operator'],
        ['property', 'end property'],
        ['raiseevent', 'end raiseevent'],
        ['removehandler', 'end removehandler'],
        ['select', 'end select'],
        ['set', 'end set'],
        ['structure', 'end structure'],
        ['sub', 'end sub'],
        ['synclock', 'end synclock'],
        ['try', 'end try'],
        ['while', 'end while'],
        ['with', 'end with'],
        ['using', 'end using'],
        ['do', 'loop'],
        ['for', 'next']
    ],
    autoClosingPairs: [
        { open: '{', close: '}', notIn: ['string', 'comment'] },
        { open: '[', close: ']', notIn: ['string', 'comment'] },
        { open: '(', close: ')', notIn: ['string', 'comment'] },
        { open: '"', close: '"', notIn: ['string', 'comment'] },
        { open: '<', close: '>', notIn: ['string', 'comment'] }
    ],
    folding: {
        markers: {
            start: new RegExp('^\\s*#Region\\b'),
            end: new RegExp('^\\s*#End Region\\b')
        }
    }
};
export var language = {
    defaultToken: '',
    tokenPostfix: '.vb',
    ignoreCase: true,
    brackets: [
        { token: 'delimiter.bracket', open: '{', close: '}' },
        { token: 'delimiter.array', open: '[', close: ']' },
        { token: 'delimiter.parenthesis', open: '(', close: ')' },
        { token: 'delimiter.angle', open: '<', close: '>' },
        // Special bracket statement pairs
        // according to https://msdn.microsoft.com/en-us/library/tsw2a11z.aspx
        {
            token: 'keyword.tag-addhandler',
            open: 'addhandler',
            close: 'end addhandler'
        },
        { token: 'keyword.tag-class', open: 'class', close: 'end class' },
        { token: 'keyword.tag-enum', open: 'enum', close: 'end enum' },
        { token: 'keyword.tag-event', open: 'event', close: 'end event' },
        {
            token: 'keyword.tag-function',
            open: 'function',
            close: 'end function'
        },
        { token: 'keyword.tag-get', open: 'get', close: 'end get' },
        { token: 'keyword.tag-if', open: 'if', close: 'end if' },
        {
            token: 'keyword.tag-interface',
            open: 'interface',
            close: 'end interface'
        },
        { token: 'keyword.tag-module', open: 'module', close: 'end module' },
        {
            token: 'keyword.tag-namespace',
            open: 'namespace',
            close: 'end namespace'
        },
        {
            token: 'keyword.tag-operator',
            open: 'operator',
            close: 'end operator'
        },
        {
            token: 'keyword.tag-property',
            open: 'property',
            close: 'end property'
        },
        {
            token: 'keyword.tag-raiseevent',
            open: 'raiseevent',
            close: 'end raiseevent'
        },
        {
            token: 'keyword.tag-removehandler',
            open: 'removehandler',
            close: 'end removehandler'
        },
        { token: 'keyword.tag-select', open: 'select', close: 'end select' },
        { token: 'keyword.tag-set', open: 'set', close: 'end set' },
        {
            token: 'keyword.tag-structure',
            open: 'structure',
            close: 'end structure'
        },
        { token: 'keyword.tag-sub', open: 'sub', close: 'end sub' },
        {
            token: 'keyword.tag-synclock',
            open: 'synclock',
            close: 'end synclock'
        },
        { token: 'keyword.tag-try', open: 'try', close: 'end try' },
        { token: 'keyword.tag-while', open: 'while', close: 'end while' },
        { token: 'keyword.tag-with', open: 'with', close: 'end with' },
        // Other pairs
        { token: 'keyword.tag-using', open: 'using', close: 'end using' },
        { token: 'keyword.tag-do', open: 'do', close: 'loop' },
        { token: 'keyword.tag-for', open: 'for', close: 'next' }
    ],
    keywords: [
        'AddHandler',
        'AddressOf',
        'Alias',
        'And',
        'AndAlso',
        'As',
        'Async',
        'Boolean',
        'ByRef',
        'Byte',
        'ByVal',
        'Call',
        'Case',
        'Catch',
        'CBool',
        'CByte',
        'CChar',
        'CDate',
        'CDbl',
        'CDec',
        'Char',
        'CInt',
        'Class',
        'CLng',
        'CObj',
        'Const',
        'Continue',
        'CSByte',
        'CShort',
        'CSng',
        'CStr',
        'CType',
        'CUInt',
        'CULng',
        'CUShort',
        'Date',
        'Decimal',
        'Declare',
        'Default',
        'Delegate',
        'Dim',
        'DirectCast',
        'Do',
        'Double',
        'Each',
        'Else',
        'ElseIf',
        'End',
        'EndIf',
        'Enum',
        'Erase',
        'Error',
        'Event',
        'Exit',
        'False',
        'Finally',
        'For',
        'Friend',
        'Function',
        'Get',
        'GetType',
        'GetXMLNamespace',
        'Global',
        'GoSub',
        'GoTo',
        'Handles',
        'If',
        'Implements',
        'Imports',
        'In',
        'Inherits',
        'Integer',
        'Interface',
        'Is',
        'IsNot',
        'Let',
        'Lib',
        'Like',
        'Long',
        'Loop',
        'Me',
        'Mod',
        'Module',
        'MustInherit',
        'MustOverride',
        'MyBase',
        'MyClass',
        'NameOf',
        'Namespace',
        'Narrowing',
        'New',
        'Next',
        'Not',
        'Nothing',
        'NotInheritable',
        'NotOverridable',
        'Object',
        'Of',
        'On',
        'Operator',
        'Option',
        'Optional',
        'Or',
        'OrElse',
        'Out',
        'Overloads',
        'Overridable',
        'Overrides',
        'ParamArray',
        'Partial',
        'Private',
        'Property',
        'Protected',
        'Public',
        'RaiseEvent',
        'ReadOnly',
        'ReDim',
        'RemoveHandler',
        'Resume',
        'Return',
        'SByte',
        'Select',
        'Set',
        'Shadows',
        'Shared',
        'Short',
        'Single',
        'Static',
        'Step',
        'Stop',
        'String',
        'Structure',
        'Sub',
        'SyncLock',
        'Then',
        'Throw',
        'To',
        'True',
        'Try',
        'TryCast',
        'TypeOf',
        'UInteger',
        'ULong',
        'UShort',
        'Using',
        'Variant',
        'Wend',
        'When',
        'While',
        'Widening',
        'With',
        'WithEvents',
        'WriteOnly',
        'Xor'
    ],
    tagwords: [
        'If',
        'Sub',
        'Select',
        'Try',
        'Class',
        'Enum',
        'Function',
        'Get',
        'Interface',
        'Module',
        'Namespace',
        'Operator',
        'Set',
        'Structure',
        'Using',
        'While',
        'With',
        'Do',
        'Loop',
        'For',
        'Next',
        'Property',
        'Continue',
        'AddHandler',
        'RemoveHandler',
        'Event',
        'RaiseEvent',
        'SyncLock'
    ],
    // we include these common regular expressions
    symbols: /[=><!~?;\.,:&|+\-*\/\^%]+/,
    integersuffix: /U?[DI%L&S@]?/,
    floatsuffix: /[R#F!]?/,
    // The main tokenizer for our languages
    tokenizer: {
        root: [
            // whitespace
            { include: '@whitespace' },
            // special ending tag-words
            [/next(?!\w)/, { token: 'keyword.tag-for' }],
            [/loop(?!\w)/, { token: 'keyword.tag-do' }],
            // usual ending tags
            [
                /end\s+(?!for|do)(addhandler|class|enum|event|function|get|if|interface|module|namespace|operator|property|raiseevent|removehandler|select|set|structure|sub|synclock|try|while|with|using)/,
                { token: 'keyword.tag-$1' }
            ],
            // identifiers, tagwords, and keywords
            [
                /[a-zA-Z_]\w*/,
                {
                    cases: {
                        '@tagwords': { token: 'keyword.tag-$0' },
                        '@keywords': { token: 'keyword.$0' },
                        '@default': 'identifier'
                    }
                }
            ],
            // Preprocessor directive
            [/^\s*#\w+/, 'keyword'],
            // numbers
            [/\d*\d+e([\-+]?\d+)?(@floatsuffix)/, 'number.float'],
            [/\d*\.\d+(e[\-+]?\d+)?(@floatsuffix)/, 'number.float'],
            [/&H[0-9a-f]+(@integersuffix)/, 'number.hex'],
            [/&0[0-7]+(@integersuffix)/, 'number.octal'],
            [/\d+(@integersuffix)/, 'number'],
            // date literal
            [/#.*#/, 'number'],
            // delimiters and operators
            [/[{}()\[\]]/, '@brackets'],
            [/@symbols/, 'delimiter'],
            // strings
            [/["\u201c\u201d]/, { token: 'string.quote', next: '@string' }]
        ],
        whitespace: [
            [/[ \t\r\n]+/, ''],
            [/(\'|REM(?!\w)).*$/, 'comment']
        ],
        string: [
            [/[^"\u201c\u201d]+/, 'string'],
            [/["\u201c\u201d]{2}/, 'string.escape'],
            [/["\u201c\u201d]C?/, { token: 'string.quote', next: '@pop' }]
        ]
    }
};
