// Hacked together from Javascript and XML Syntaxes, Edward Kmett 2006. Available under the LGPL.

dp.sh.Brushes.E4x = function() {
	var keywords =	'abstract boolean break byte case catch char class const continue debugger ' +
			'default delete do double else enum export extends false final finally float ' +
			'for function goto if implements import in instanceof int interface long native ' +
			'new null package private protected public return short static super switch ' +
			'synchronized this throw throws transient true try typeof var void volatile while with';

	this.regexList = [
		{ regex: new RegExp('"(?:[^"\n]|[\"])*?"', 'g'),	css: 'string' },
		{ regex: new RegExp("'(?:[^'\n]|[\'])*?'", 'g'),	css: 'string' },
		{ regex: new RegExp('^\\s*#.*', 'gm'),			css: 'preprocessor' },
		{ regex: new RegExp(this.GetKeywords(keywords), 'gm'),	css: 'keyword' }	
	];

	this.CssClass = 'dp-e4x';
};

dp.sh.Brushes.E4x.prototype     = new dp.sh.Highlighter();
dp.sh.Brushes.E4x.Aliases = [ 'e4x'];

dp.sh.Brushes.E4x.prototype.ProcessRegexList = function() {
	function push(array, value)
	{
		array[array.length] = value;
	}
	
	/* If only there was a way to get index of a group within a match, the whole XML
	   could be matched with the expression looking something like that:
	
	   (<!\[CDATA\[\s*.*\s*\]\]>)
	   | (<!--\s*.*\s*?-->)
	   | (<)*(\w+)*\s*(\w+)\s*=\s*(".*?"|'.*?'|\w+)(/*>)*
	   | (</?)(.*?)(/?>)
	*/
	var index	= 0;
	var match	= null;
	var regex	= null;

	// Match CDATA in the following format <![ ... [ ... ]]>
	// <\!\[[\w\s]*?\[(.|\s)*?\]\]>
	this.GetMatches(new RegExp('<\\!\\[[\\w\\s]*?\\[(.|\\s)*?\\]\\]>', 'gm'), 'cdata');

	// Match comments
	// <!--\s*.*\s*?-->
	regex = new RegExp("<\!--|-->","g");//.*?-->","gm");
	var cstart = -1;
        while((match = regex.exec(this.code)) != null) {
		if (match[0].charAt(0)=="<") { 
			if (cstart<0) cstart = match.index;
		} else { 
			if (cstart>=0) {
				// comment from cstart to here
				this.matches[this.matches.length] = new dp.sh.Match(this.code.substring(cstart,match.index+3),cstart,"comments");
				cstart = -1;
			}
		}
        }


	alert("XML");
	try { 
	// Match opening and closing tags
	// TODO: allow replacement of objects with {} proxies.
	regex = new RegExp("(</?)\\s*([A-Za-z0-9\-_\.]+)([^<>]*?)(/?>)","gm");
	var attr_re = new RegExp('([:\\w-\.]+)\\s*=\\s*(".*?"|\'.*?\'|\\{.*?\\}|\\w+)*', 'gm');
	var attr_match;
	while((match = regex.exec(this.code)) != null) { 
		push(this.matches, new dp.sh.Match(match[2], match.index + match[0].indexOf(match[2]), 'tag-name'));
		push(this.matches, new dp.sh.Match(match[1], match.index, 'tag'));
		push(this.matches, new dp.sh.Match(match[4], match.index + match[0].length-match[4].length,'tag'));
		var attr_base = match.index+match[0].length-match[4].length-match[3].length;
		while((attr_match = attr_re.exec(match[3])) != null) {
			push(this.matches, new dp.sh.Match(attr_match[1], attr_base+attr_match.index, 'attribute'));
		}
	}
	} catch(e) { alert(e);} 

	this.GetMatches(new RegExp('//.*$', 'gm'),'comments');
	this.GetMatches(new RegExp('/\\*[\\s\\S]*?\\*/', 'g'),'comments');
	// now do the conventional javascript matches
	for(var i = 0; i < this.regexList.length; i++) this.GetMatches(this.regexList[i].regex, this.regexList[i].css);
};
