﻿module 
    kind jsfile
    
	var util = require('util')
	
	#
		# Nodify 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
		# Outputs
		#   nodes: Array of [
		#     line -> mTreeNode : {
		#       + parent: Object, // parent mTreeNode
		#       + model: Object, // the MTreeBrick to which the line belongs
		#       + children: Array, // 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 MTreeBrick
		# \        // 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
		# \r       // implements line continuation
		#          //   the value is appendend to the value of the parent line
		#          //   with a soft break separator:  prevLine,value += '\r' + currentLine.value
		#
    
	set module.exports
        function 
            param lines
            param mTree
            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 = mTree.getNewNodeId()
                set line.model = mTree
                
				if line.indent == 0 && current == null
                    set line.parent = null
                    _ nodes.push(line)
                
				elif current == null
					return 
						_ error
							@ 'Malformed tree, root node cannot have an indent.'
							@ line
							@ mTree
                
				elif line.indent == current.indent
                
				    if typeof(current.parent) === 'undefined' || current.parent === null
						return
							_ error
								@ 'Malformed tree, only one root note allowed.'
								@ line
								@ mTree
                    set line.parent = current.parent
                    _ current.parent.children.push(line)
                
				elif line.indent > current.indent
                
				    if nameFirstChar == '$' && line.name === '$params'
                        if current.indent > 0
							return
								_ error
									@ 'The $params node must be a child of the root node.'
									@ line 
									@ mTree
                        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 
					elif nameFirstChar == '\\' && line.name === '\\r'
						# value continuation on new line with soft break
                        set current.value += ('\r' + 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
							_ error
								@ 'Malformed tree, only one root note allowed.'
								@ line
								@ mTree
                set current = line
                set current.children = []
            
			return nodes

	function error
		param message
		param line
		param mTree
		set message = message +
			\b '\nNode ' + 
			\b line.name + ' ' + (line.value || '') +
			\b ' row: ' + line.row + ' col: ' + line.col + 
			\b '.\n Filepath: ' + mTree.uri
		return
			{
				@ __is_error true
				@ message message
				@ source 'wizzi-mtree/lib/loader/nodifier'

