

	var mr_ajax_reqObj = null;
	var mr_ajax_processCounter = -1;
	var mr_ajax_debugMode = false;
	var mr_ajax_ruleSets = null;
	var mr_ajax_cacheBuster = false;
	var mr_ajax_defaultContent = Array();
	var mr_success = false;
	var mr_onCompleteFunctionName = '';

//*************************************************//
//           MAIN FUNCTIONS                        //
//*************************************************//	

	function mr_ajax_do(ruleGeneratorFunctionName, onCompleteFunctionName)
	{
		if(readQueryString('de_bug')=='true') mr_ajax_debugMode = true;
		
		mr_onCompleteFunctionName = onCompleteFunctionName;
		
		//get the rules, if they can't be got don't do anything ... default display will take over
		try
		{
			mr_ajax_ruleSets = eval(ruleGeneratorFunctionName+'();');
		}
		catch(e)
		{
			if(mr_ajax_debugMode)
			alert('mr_ajax_do-eval rules: ' + ruleGeneratorFunctionName + '::' + e);
			return;
		}
		
		
		//before we get started we need to save the content in the display objs
		for(i=0;i<mr_ajax_ruleSets.length;i++)
		{
			
			mr_ajax_processCounter=i; // move the process counter along so that the rule parser can work [i know bad design]
			var displayObjName = mr_ajax_rulesetParser('display');
			var displayObj = document.getElementById(displayObjName);
			if(mr_ajax_debugMode) alert('displayObjName:' + displayObjName + ' displayObj:' + displayObj);
			try
			{
				mr_ajax_defaultContent[i] = displayObj.innerHTML;
				displayObj.innerHTML = '';
			}
			catch(e)
			{		
				if(mr_ajax_debugMode) alert('mr_ajax_do-loop rules' + e);
				mr_ajax_triggerDefaultContent(); //try to display the default content				
				//let the operation continue since only one rule may have an issue
			}
	
		}
		
		//set the process counter back to -1
		mr_ajax_processCounter = -1;
		
		//now kick off the function that will manage getting the content, this is the first execution
		//mr_ajax_readyStateHandler will kick it off each time a rule finishes
		mr_ajax_processMrg();
	}

	function mr_ajax_processMrg()
	{
		mr_ajax_reqObj = null;			
		if(mr_ajax_processCounter>=mr_ajax_ruleSets.length-1) 
		{
			if(mr_onCompleteFunctionName!=null && mr_onCompleteFunctionName!='') 
				eval(mr_onCompleteFunctionName + '(' + mr_success + ');'); //call the finish function
			return;
		}
		mr_ajax_processCounter++;
		
		var url = mr_ajax_rulesetParser('url');
		
		if(mr_ajax_cacheBuster)
			url += (url.indexOf('?')==-1)?'?__cb='+Math.random():'&__cb='+Math.random(); //add a cachebuster
		
		if(mr_ajax_debugMode) alert('url:' + url);
		
		mr_ajax_reqObj = mr_ajax_createReqObj();
		mr_ajax_reqObj.open('get', url);
		mr_ajax_reqObj.onreadystatechange = mr_ajax_readyStateHandler;
		mr_ajax_reqObj.send(null);
	}
	
	function mr_ajax_createReqObj() {
		var reqObj;
		try
		{
			reqObj = new window.XMLHttpRequest();
		} catch(e) {
			try 
			{
				reqObj = new ActiveXObject("Microsoft.XMLHTTP");
			} catch(e) {/*don't do anything default will be displayed*/}
		}
		return reqObj;
	}

	function mr_ajax_readyStateHandler() { 
		 if(mr_ajax_reqObj.readyState == 4)
		 { 
			if(mr_ajax_reqObj.status==200)
			{
				var response = mr_ajax_reqObj.responseText; 
				if(response) 
				{ 
					//fix a problem with the XML generated by hcom
					response = response.replace(/^\s+|\s+$/g, ''); //trim spaces
					response = response.replace(/\&\#/g,'AMPSIGNHASH');
					response = response.replace(/\&amp;/g,'AMPENCODE');
					response = response.replace(/\&/g,'&amp;');
					response = response.replace(/AMPSIGNHASH/g,'&#');
					response = response.replace(/AMPENCODE/g,'&amp;');
					
					//IE has problem with some encoded characters so put in hidden div to translate
					document.getElementById('mr_workarounddiv').innerText=response;
					response = document.getElementById('mr_workarounddiv').innerText;
					
					//finally we can do some work
					mr_ajax_processXML(response);						
				}
			}
			mr_ajax_processMrg(); 
		 }
	}

	function mr_ajax_processXML(xml)
	{
		//Get the rules
		var nodeListName = mr_ajax_rulesetParser('xmllist');
		var num = mr_ajax_rulesetParser('num');
		var templateObjName = mr_ajax_rulesetParser('template');
		var displayObjName = mr_ajax_rulesetParser('display');
		
		//Validate the num setting, if not a number make it 2 for a default value
		if(parseInt(num)=='NaN') num = 2; 
		
		//get the innerHTML of the hidden div that contains the HTML for each object that will be rendered
		var templateObj = document.getElementById(templateObjName);
		
		//get the object that each object will be put into
		var displayObj = document.getElementById(displayObjName);
		
		//make sure both object exists
		if(templateObj==null||displayObj==null)
		{
			if(mr_ajax_debugMode)
				alert('check displayObj:'+displayObj+'\ntemplateObj:'+templateObj);
			
			mr_ajax_triggerDefaultContent();
			return;
		}

		//Get the inner HTML of the templateObj to be used as the template for each item
		var templateObjMasterStr = templateObj.innerHTML;
		//Have to fix what the DOM does with special characters
		templateObjMasterStr = templateObjMasterStr.replace(/%7B/gi,'{');
		templateObjMasterStr = templateObjMasterStr.replace(/%7D/gi,'}');
		
		
		//need to save the orignal innerHTML for the displayObj for a test later
		var orginalDisplayObjInnerHTML = displayObj.innerHTML;
		
		//create xml dom object
		var xmldoc=null;
		try
		{
			if(window.ActiveXObject) //code for Internet Explorer
			{
				xmldoc=new ActiveXObject("Microsoft.XMLDOM");
				xmldoc.async="false";
				xmldoc.loadXML(xml);
			}
			else if(document.implementation.createDocument) //code for Mozilla, Firefox, Opera
			{
					var parser=new DOMParser();
					xmldoc=parser.parseFromString(xml,"text/xml");	
			}
			else
			{
				if(mr_ajax_debugMode) alert('mr_ajax_processXML-cant create parser');
				mr_ajax_triggerDefaultContent();
				return;
			}
		}
		catch(e)
		{
			if(mr_ajax_debugMode) alert('error creating parser: ' + e);
			mr_ajax_triggerDefaultContent();
			return;
		}
		
		//create the node list you want to work with
		var nodeList=null;
		var nodeListCount=-1;
		try
		{
			//alert(xmldoc.getElementsByTagName('harrahs').length);
			nodeList = xmldoc.getElementsByTagName(nodeListName);
			nodeListCount = nodeList.length;
		}
		catch(e)
		{
			if(mr_ajax_debugMode) alert('couldnt get nodelist: ' + e);
			mr_ajax_triggerDefaultContent();
			return;
		}
		if(mr_ajax_debugMode) alert('count: ' + nodeListCount);
			
		//turn the semicolon seperated string into an array
		var valueNodeNameArray = null;
		var valueNodeNameArrayCount = -1;
		try
		{
			valueNodeNameArray = mr_ajax_getNamesFromTemplate(templateObjName);
			valueNodeNameArrayCount = valueNodeNameArray.length;
		}
		catch(e)
		{
			if(mr_ajax_debugMode) alert('error creating value nodes: ' + e);
			mr_ajax_triggerDefaultContent();
			return;
		}
		
		//Find all indexes that are acceptable to the rule
		//rank=1&active=true
		var rule = mr_ajax_rulesetParser('rule');
		
		var ruleNameValues = rule.split('&');
		var acceptableIndexes = Array();
		var isAcceptable = false;
		
		//FIRST Build the acceptableIndexes array
		for(i=0;i<nodeListCount;i++)
		{
			isAcceptable = false;
			for(j=0;j<ruleNameValues.length;j++)
			{
				try
				{
					var arr = ruleNameValues[j].split('=');
					if(arr.length==2)
					{
						var ruleName = arr[0];
						var ruleValue = arr[1];
						var nodeValue = nodeList[i].getElementsByTagName(ruleName)[0].childNodes[0].nodeValue;
						var operator = ruleValue.substring(0,1);
						if(operator=='>'&&mr_isNumber(nodeValue))
						{
							ruleValue = ruleValue.substring(1);
							isAcceptable = (nodeValue>=ruleValue);
						}
						else if (operator=='<'&&mr_isNumber(nodeValue))
						{
							ruleValue = ruleValue.substring(1);
							isAcceptable = (nodeValue<=ruleValue);
						}
						else
						{
							isAcceptable = (nodeValue==ruleValue);
						}
						if(mr_ajax_debugMode)
							//alert('name: ' + ruleName + ' value: ' + ruleValue + ' node ' + nodeValue + ' accept ' + isAcceptable);
							
						if(isAcceptable==false) break; //once one doesn't match we have to exit
					}
				}catch(e){}
			}
			if(isAcceptable)
				acceptableIndexes[acceptableIndexes.length]=i;				
		}
		
		//SECOND make sure we have enough acceptable indexes			
		//ADDED FALSE TO SHUT OFF UNTIL I CAN FIGURE OUT HOW NOT TO DISPLAY UNAVAIL DATA
		if(false && acceptableIndexes.length<num)
		{
			for(i=0;i<nodeListCount;i++)
			{
				var str = '|' + acceptableIndexes.join('|') + '|';
				if(str.indexOf('|'+i+'|')==-1)
				{
					acceptableIndexes[acceptableIndexes.length]=i;
					if(acceptableIndexes.length==(Number(num)+1)) break;
				}
			}
		}
		//MIGHT BE BETTER TO PICK THE RANDOM NUMBERS NOW???
		//END FIND ACCEPTABLE
		
		//USED TO KEEP TRACK OF WHAT WE PICKED
		var randomPicks = '|';
		
		//run the specified number of times
		for(i=0;i<num;i++)
		{
			//create a copy of the template so that we can fill with values
			var templateObjStr = templateObjMasterStr;
			//pick a random number to figure out what to display making sure we don't dup any 50 iterations is enough
			var ind = -1;
			for(r=0;r<50;r++)
			{
				ind = Math.round(Math.random()*(acceptableIndexes.length-1));
				//just a simple text concat of the numbers picked to determine if the number was previously used
				if(randomPicks.indexOf('|'+ind+'|')>-1)
				{ind = -1;} //set ind back
				else
				{ randomPicks += ind + '|'; break;}
			}	
			
			var node = nodeList[acceptableIndexes[ind]];
			//GET AND REPLACE THE VALUES
			for(j=0;j<valueNodeNameArrayCount;j++)
			{
				try
				{
					var name = valueNodeNameArray[j];
					//special case for property code also replace propertyname
					if(valueNodeNameArray[j].toLowerCase()=='propertyname'){
						value = node.getElementsByTagName('propertyCode')[0].childNodes[0].nodeValue;
						var propertyNameMap = getPropertyNameMap();
						value = propertyNameMap[value];
						token = new RegExp('{{propertyname}}','gi');
						templateObjStr = templateObjStr.replace(token,value);
					}
				
					if(name.indexOf('--e')>-1) name = name.substring(0,name.indexOf('--e'));
					if(name.indexOf('--t')>-1) name = name.substring(0,name.indexOf('--t'));
					var value = node.getElementsByTagName(name)[0].childNodes[0].nodeValue;
					
					//OK why am i doing the same thing over ... if the tag name uses {[tag name]} 
					//you need to escape the value for single and double quotes so it can be passed
					//into a function ... that is what this does...					
					if(valueNodeNameArray[j].indexOf('--e')>-1) value = mr_escape(value);  //escapes
					if(valueNodeNameArray[j].indexOf('--t')>-1) value = mr_trimer(value,valueNodeNameArray[j]); //trims
					//if(valueNodeNameArray[j].indexOf('teaser')>-1) value = mr_span_writer(value,75);
					
					
						
					
					
					var token = new RegExp('{{' + valueNodeNameArray[j] + '}}','gi');
					templateObjStr = templateObjStr.replace(token,value);		
				
				}
				catch(e)
				{
					//don't think it is necessary to do anything if there is an exception
				}
			}//end for
			
			//get rid of the rest of the tokens
			try
			{
				if(templateObjStr.indexOf('{{')>-1 && (templateObjMasterStr!=templateObjStr))
				{
					if(mr_ajax_debugMode) alert('removing {{ & }}');
					var tmpObjStr = templateObjStr;
					var tmpObjStrA = tmpObjStr.split('{{');
					var len_tmpObjStrA = tmpObjStrA.length;
					for(z=0;z<len_tmpObjStrA;z++)
					{
						var tmpObj_value = tmpObjStrA[z];
						var tmpObj_value_start = tmpObj_value.indexOf('}}');
						if(tmpObj_value_start>-1)
							tmpObjStrA[z]=tmpObj_value.substring(tmpObj_value_start + 2);
					}
					templateObjStr = tmpObjStrA.join('');
				}
			}catch(e){}
			
			//Test to make sure the new content is different than the existing content to 
			//prevent duplicating the same string
			if(mr_ajax_debugMode) alert('is obj not same: ' + (templateObjMasterStr!=templateObjStr));
			if(templateObjMasterStr!=templateObjStr)
			{	
				displayObj.innerHTML+=templateObjStr;		
				mr_success = true;
			}
		}
		//was the displayObj modified --> yes then display default content
		if(displayObj.innerHTML==orginalDisplayObjInnerHTML)
		{
			mr_ajax_triggerDefaultContent();
		}
		return;
	}
	
	//*************************************************//
	//           UTILITY FUNCTIONS                     //
	//*************************************************//	
	function mr_trimer(text,name)
	{var size = 75;
		//extract size from name
		var nameParts = name.split('--t');
		if(nameParts.length==2)
		{
			size = nameParts[1];
		}
		
		var charArray = text.split('');
		var spanText = '';
		
		if(charArray.length > size)
		{
			for(i=0;i<size;i++)
			{
				spanText = spanText + charArray[i];
			}
			spanText = spanText + '...';
		}
		else
		{		
			spanText = text;
		}
		return spanText;
	}
	
	function mr_span_writer(text,size)
	{
		var charArray = text.split('');
		var spanText = '';
		
		if(charArray.length > size)
		{
			for(i=0;i<size;i++)
			{
				spanText = spanText + charArray[i];
			}
			spanText = spanText + '...';
		}
		else
		{		
			spanText = text;
		}
		return spanText;
	}
	
	function mr_escape(str)
	{
		
		//str = str.replace(/\"/gi,'\\\"');  //do double quotes
		str = str.replace(/\'/gi,'\\\''); //do single quotes
		return str;
	}
	
	function mr_isNumber(str)
	{
		var num = new Number(str);
		return (!isNaN(num));
	}
	
	function mr_ajax_rulesetParser(name)
	{
		name = name+':'; //append the colon
		var nameLen = name.length; //get the length of the name so that we can strip it later
		var ruleSet = mr_ajax_ruleSets[mr_ajax_processCounter]; //get the current ruleset
		var start = ruleSet.indexOf(name, 0); //where does the name start
		var end = ruleSet.indexOf('|', start); //where is the first pipe after the name start
		if(end==-1)end=ruleSet.length; //if it is the last item it might not have a |
		var value = ruleSet.substring(start+nameLen, end); //get everything form name end to the pipe
		return value;
	}

	function mr_ajax_getNamesFromTemplate(templateObjName)
	{
		var templateObj = document.getElementById(templateObjName).innerHTML;
		templateObj = templateObj.replace(/%7B/gi,'{');
		templateObj = templateObj.replace(/%7D/gi,'}');
					
		var arr = templateObj.split('{{');
		var nameValues=Array();
		var dupStr='';
		
		for(i=1;i<arr.length;i++)
		{
			arr[i] = arr[i].substr(0,arr[i].indexOf('}}')); //get the name from the remaining part of string by matching to }}
			if(dupStr.indexOf('|'+arr[i]+'|')==-1) //extract dups
			{
				nameValues[nameValues.length] = arr[i];
				dupStr += '|'+arr[i]+'|';	
			}
		}
		return(nameValues);	
	}
	
	function mr_ajax_triggerDefaultContent()
	{
		var displayObjName = mr_ajax_rulesetParser('display');
		var displayObj = document.getElementById(displayObjName);
		try
		{
			displayObj.innerHTML = mr_ajax_defaultContent[mr_ajax_processCounter];
		}
		catch(e){if(mr_ajax_debugMode)alert('mr_ajax_triggerDefaultContent: ' + e);}
	}

	