﻿module wizzi-mtree@${wzCtx.version}.loader.nodifier
    kind jsfile
    
	var util = require('util')
    var errors = require('../errors')

    #
        # TODO Error management
	
	#
		# Nodifies the lines of an IttfDocument and creates a
		# tree structure object based on line indentation.
		# . detects the $params command
		# . implements line continuation
		# . assigns an id to each node
		# !!! A line object is transformed in place into a node object 
		#     without recreation (no cloning) !!!
		#
		# Inputs
		#     - the lines produced by the liner
		#     - a newly created, empty, mTreeBrick
		# Outputs
		#   [ nodes
		#     { line -> mTreeNode
		#       { parent
		#         // parent mTreeNode
		#       { model
		#         // the mTreeBrick to which the line belongs
		#       [ children
		#         // the children mTreeNodes
		#       id: Number,
		#       indent: Number,
		#       name: String,
		#       value: String,
		#       row: Number,
		#       col: Number,
		#       sourceKey: String,
		#       tagSuffix: undefined || '('
		#       hasMacro: Boolean
		#
		# Ittf commands:
		# $params  // the param values are stored in the MTree
        # \        // implements line continuation
		#          //   the value is appendend to the value of the parent line
		#          //   without separators
		# \b       // implements line continuation
		#          //   the value is appendend to the value of the parent line
		#          //   with a space separator:  prevLine,value += ' ' + currentLine.value
		# \n       // implements line continuation
		#          //   the value is appendend to the value of the parent line
		#          //   with a line break separator:  prevLine,value += '\n' + currentLine.value
		#
    
	set module.exports
        function 
            [ lines
            { mTreeBrick
            var 
                decl nodes
                    [ 
                decl root = null
                decl current = null
                decl nameFirstChar = null
                decl nameLength = 0
                decl line
                decl i
                decl l = lines.length
            
			for var i = 0; i < l; i++
                set line = lines[i]
                set nameFirstChar = line.name[0]
                set nameLength = line.name.length
                set line.id = mTreeBrick.loadHistory.getNewNodeId()
                # deprecated
                set line.model = mTreeBrick
                set line.mTreeBrick = mTreeBrick
                
				if line.indent == 0 && current == null
                    set line.parent = null
                    _ nodes.push(line)
                
				elif current == null
					return 
						_ local_error
							@ 'InvalidIttfError'
							@ 'default'
							@ 'Malformed tree, root node cannot have an indent.'
							@ line
							@ mTreeBrick
                
				elif line.indent == current.indent
                
				    if typeof(current.parent) === 'undefined' || current.parent === null
						return
							_ local_error
								@ 'InvalidIttfError'
								@ 'default'
								@ 'Malformed tree, only one root note allowed.'
								@ line
								@ mTreeBrick
                    set line.parent = current.parent
                    _ current.parent.children.push(line)
                
				elif line.indent > current.indent
                
				    if nameFirstChar == '$' && line.name === '$params'
                        if current.indent > 0
                            # loog 'wizzi-mtree.nodifier.current.name', current.name, current.value, line.value
                            if current.name !== '$fragment'
                                return
                                    _ local_error
                                        @ 'InvalidIttfError'
                                        @ 'default'
                                        @ 'The $params node must be a child of the root node.'
                                        @ line 
                                        @ mTreeBrick
                            else
                                set current.$params = line.value
                        else
                            set current.model.$params = line.value
                        continue 
                    
					elif nameFirstChar == '\\' && nameLength == 1
						# value continuation on new line
                        set current.value += line.value
                        continue 
                    
					elif nameFirstChar == '\\' && line.name === '\\b'
						# value continuation on new line with space
                        set current.value += (' ' + line.value)
                        continue 
                    
					elif nameFirstChar == '\\' && line.name === '\\n'
						# value continuation on new line with line break
                        set current.value += ('\n' + line.value)
                        continue 
                    else 
                        set line.parent = current
                        _ current.children.push(line)
                
				elif line.indent < current.indent
                    
					var parent = current.parent
                    while parent != null && line.indent < parent.indent
                        set parent = parent.parent
                    set line.parent = parent.parent
                    if parent.parent
                        _ parent.parent.children.push(line)
                    else
						return
							_ local_error
								@ 'InvalidIttfError'
								@ 'default'
								@ 'Malformed tree, only one root note allowed.'
								@ line
								@ mTreeBrick
                set current = line
                set current.children = []
            
			# loog 'nodes -------------->\n', nodes[0].children[0]
			
			return nodes

	function local_error
		param errorName
		param method
		param message
		param line
		param mTreeBrick
        $* 6/6/19
		if line
			set message = message + 
				\b '\nIn node: ' + 
				\b line.name + ' ' + (line.value || '') +
				\b ' row: ' + line.row + ' col: ' + line.col + 
				\b ' file: ' + mTreeBrick.uri
        *$
		return
            new errors.WizziError
                @ errorName
                [
					@ errorName
                @ mTreeBrick
                {
					{ source
						@ method 'wizzi-mtree@${wzCtx.version}.loader.nodifier.' + method
					{ mtree
						@ mTreeBrickLine line
						@ mTreeBrick mTreeBrick
                    
			$* 6/6/19
            _ error
				@ name
				@ method
				@ message
            *$