
class Macro:
	
	Template = require "../template";

	constructor(name, args, body, location, prepor):
		if args:
			for i <- args:
				if not args[i] = args[i].trim():
					args.splice(i, 1);
		@.name     = name;
		@.args     = args;
		@.bodys    = Template.create(body.replace(/\\\n\s*/g, ''), args);
		@.location = location;

	parse(params):
		if !params && @.args:
			return false;
		value = '';
		for item => @.bodys:
			if item as 'string':
				value += item;
			else:
				value += item.apply(@, params);
		if @.args:
			value = replaceParams(value, params, @);
		return value;

	error():
		Err @.location;

	function argsRe(macro):
		if !macro._args_re:
			args = macro.args.join('\\b|\\b')
			args = args ? '|\\b'+ args+'\\b' : '';
			macro._args_re = new RegExp('(\#{0,3}@?)(\#(\\d+)|\\bARGR\\.\\.\\.'+args+')');
		return macro._args_re;

	function replaceParams(content, params, macro):
		args    = macro.args;
		args_re = argsRe(macro);
		out     = '';
		while m = content.match(args_re):
			if !m[0]:
				break;
			val   = '';
			key   = m[2];
			index = m[3] || args.indexOf(key);
			if key == 'ARGR...':
				val = params.slice(index >= 0 ? index : args.length).join(', ');
			else if params[index]:
				val = params[index]+'';
			switch val && m[1]:
				case '###':
					val = '##'+'"'+val.replace(/(^|[^\\])"/g, '$1\\"')+'"';
				case '#':
					val = '"'+val.replace(/(^|[^\\])"/g, '$1\\"')+'"';
				case '##@':
					val = '##'+"'"+val.replace(/(^|[^\\])'/g, "$1\\'")+"'";
				case '#@':
					val = "'"+val.replace(/(^|[^\\])'/g, "$1\\'")+"'";
				case '##':
					val = '##'+val;
			out += content.slice(0, m.index) + val;
			content = content.substr(m.index+m[0].length);
		content = (out+content).replace(/"##"|'##'|##,|##/g, '');
		return content;

module.exports = Macro;