/**
 *
 * xModify is an extension of the jQuery library that processes requests
 * and update the HTML DOM using the xModify syntax.  Included in xModify is
 * a series of instructions that can be used to update html.
 *
 * insert-after, insert-before, append, set-attribute, set-style
 * set-innerhtml, replace-children, remove-element, remove-attribute
 * replace
 *
 *
 */
jQuery.extend(jQuery.swoosh, {
		
    /**
     * Function loads a macro file from the server.
     * The results of the request will be automatically
     * processed.  This function redirects to the xModify function
     * that will process the document generically.
     *
     * Look at the documenation for the jQuery.ajax function
     * for information on the parameters.
     *
     * http://docs.jquery.com/Ajax
     *
     */
    loadMacro: function(){
        jQuery.swoosh.xModify.apply(this, arguments);
    },
	
	/**
	 * Based on the macro name parameter execute the macro.
	 * 
	 * @param {Object} macroName
	 */
    runMacro: function(){
    	this._processDoc(this._parseMacroXML(this._formatMacro(this._macroMap[arguments[0]], arguments)));
    },
	
	/**
	 * Unload the macro from the macro list.  Use when the macro is no longer
	 * needed.
	 * 
	 * @param {Object} macroName
	 */
    unloadMacro: function(macroId){
        this._macroMap[macroId] = null;
    },

	//PRIVATE METHODS AND VARIABLES
    /**
     * Map of the macros that have been loaded. Developes use the 
     * loadMacro, unloadMacro, and runMacro functions to use the
     * macro functionality.
     */
	_macroMap:{},
    
	/**
	 * A simple approximation of Java message format,
	 * takes a string like "aaa{0} bbb{1} ccc{2}" and plugs
	 * in arguments in that order. Currently there is no escape syntax at all. TODO
	 * 
	 * @param {String} formatString The string message format.
	 * @param {String/Array} args An array of arguments to plug into the message format
	 * or a single argument
	 */
	_formatMacro: function(formatString, args){
		for (var i = 1; args && i < args.length; i++)	
			formatString = formatString.replace(new RegExp("\\{" + (i-1) + "\\}", "gm"), ""+args[i]);
		return formatString;
	},
	
	/**
	 * Uses the browser xml parsser to create
	 * @param {Object} xmlContent
	 */
	_parseMacroXML: function(xmlContent){
		if (jQuery.browser.msie){ //IE
			var nativeDoc=new ActiveXObject("Microsoft.XMLDOM");
			nativeDoc.async="false";
			nativeDoc.loadXML(xmlContent);
			return nativeDoc;
		}else if (document.implementation && //MOZ variants
					document.implementation.createDocument){
			var parser=new DOMParser(), 
				nativeDoc=parser.parseFromString(xmlContent,"text/xml");
			return nativeDoc;
		}
	},

	//PRIVATE METHODS AND VARIABLES
    /**
     * Will return the macro element.
     */
    _macroProcessDoc: function(modElement, variables){
		var variables = {},
			arry = modElement.childNodes, 
			len = arry.length;

	    for (var i = 0; i < len; i++)
			if (arry[i].nodeType == 1)
				this._macroProcessElement(arry[i], variables);           
    },

	/**
	 * Loop over all of the macro elements and place them into the _macroMap.
	 * Need to convert the modifications elements to the string, which is the
	 * value of the _macroMap.
	 * 
	 * @param {Object} modElement
	 * @param {Object} variables
	 */
    _macroProcessElement: function(modElement, variables){
		var macroId = modElement.getAttribute("id"), 
			macroValue = "<xal xmlns:xm=\"http://openxal.org/core/xmodify\">";
		for (var i = 0; i < modElement.childNodes.length; i++)
			if (modElement.childNodes[i].nodeType == 1)
				macroValue += this._convertToString(modElement.childNodes[i]);
			else
				macroValue += modElement.childNodes[i].nodeValue;			
		
		this._macroMap[macroId] = macroValue+"</xal>";	
	},
	
    /**
     * Will run the macro specified by the ref attribute.
     */
    _macroApplyProcessDoc: function(modElement, variables){
		this.runMacro(modElement.getAttribute("ref"));
   }
});

/**
 * Add the processor for the "modifications" elements in the document.
 * This is a necessary becuase the swoosh client just process the document
 */
jQuery.swoosh._modules["macros"] = jQuery.swoosh._macroProcessDoc;
jQuery.swoosh._modules["apply-macro"] = jQuery.swoosh._macroApplyProcessDoc;
