function JSTestimonialSwitcher(container, interval) {

  this.getTestimonials = function() {
	me.showLoadingFor(me.container);
	if (window.XMLHttpRequest) { // Mozilla etc. 
		xmlhttp=new XMLHttpRequest(); 
	} else if (window.ActiveXObject) { // IE 
		xmlhttp=new ActiveXObject("Microsoft.XMLHTTP"); 
	}
	if (!xmlhttp) throw "unsupported browser";
	xmlhttp.onreadystatechange=me.parseDoc;
	xmlhttp.open("GET","lib/xml/testimonials.php",true); 
	xmlhttp.setRequestHeader("Content-Type", "application/xml"); 
	xmlhttp.send(null);
  };

  this.parseDoc = function() {
	if(xmlhttp.readyState < 4) return;
	if(xmlhttp.status != 200) throw ("Not status 200");
	var doc = xmlhttp.responseXML;
	if((!doc || !doc.documentElement) && window.ActiveXObject) {
			alert("in if");
			doc = new ActiveXObject("Microsoft.XMLDOM");
			doc.async=false;
			doc.loadXML(xmlhttp.responseText);
			if(!doc.firstChild) {
				var txt = xmlhttp.responseText;
				doc.loadXML(me.cleanText(txt));
			}
	}
	if(!doc || !doc.documentElement) {
		me.setTestimonials(null, me);
	} else {
		me.setTestimonials(doc, me);
	}
  };

  this.setTestimonials = function(doc) {
	if(!me.testDoc(doc)) {
		alert('invalid doc');
	} else {
		var tNodes = doc.getElementsByTagName("testimonial");
		var testimonials = new Array();
		for(var i=0; i<tNodes.length; i++) {
			var t = new Object();
			for(var n=0; n<tNodes[i].childNodes.length; n++) {
				switch(tNodes[i].childNodes[n].nodeName) {
					case "author": t.author = me.nodeVal(tNodes[i].childNodes[n]); break;
					case "quote": t.quote = me.nodeVal(tNodes[i].childNodes[n]); break;
				}
			}
			testimonials[i] = t;
		}
		me.testimonialStore = testimonials;
		me.drawTestimonial();
	}
  };

  this.drawTestimonial = function() {
	me.clearNode(me.container);
 	var t = me.testimonialStore[Math.rand(0, me.testimonialStore.length - 1)];
  
	var qImg = document.createElement("img");
	qImg.src = "/lib/images/quote.jpg";
	qImg.style.margin = "10px";
	var p = document.createElement("p");
	p.appendChild(qImg);
	p.appendChild(document.createTextNode(t.quote));
	p.appendChild(document.createElement("br"));
	var span = document.createElement("span");
	span.appendChild(document.createTextNode("- "+t.author));
	span.style.marginLeft = "150px";
        p.appendChild(span);
	me.container.appendChild(p);

	if(me.showTimer) {
		me.showTimer = null;
		clearTimeout(me.showTimer);
	}
	me.showTimer = setTimeout(me.drawTestimonial, me.interval);
  }

  this.showLoadingFor = function(node) {
	me.clearNode(node);
	var img = document.createElement("img");
	img.src="/lib/images/loading-bar.gif";
	img.style.marginLeft="auto";
	img.style.marginRight="auto";
	node.appendChild(img);
  }

  this.recursiveNodeRemove = function(node) {
	var fc;
	while(fc = node.firstChild) {
		me.recursiveNodeRemove(fc);
	}
	node.parentNode.removeChild(node);
  }

  this.clearNode = function(node) {
	while(node.firstChild)
		me.recursiveNodeRemove(node.firstChild);
  }

  this.testDoc = function(doc) {
	if(!doc || !doc.documentElement) {
		return false;
	}
	if(doc.documentElement.nodeName == "exception") {
		if(doc.documentElement.firstChild)
			throw doc.documentElement.firstChild.nodeValue;
		throw "an exception occurred during xml transaction";
	}
	return true;
  };

  this.cleanText = function (str) {
	var ns = "";
	var length = str.length;
	for(var i = 0; i < length; i++) {
		var mychar = str.charCodeAt(i);
		if((mychar < 32 && mychar != 9 && mychar != 10 && mychar != 13) || mychar > 127) continue;
		ns += str.charAt(i); 
	}
	return ns;
  };
	
  this.nodeVal = function(node) {
	if(!node || !node.firstChild || !node.firstChild.nodeValue) return "";
	return node.firstChild.nodeValue;
  };

  var me = this;
  var xmlhttp = null;
  this.interval = interval;
  this.container = container;
  this.startTime = new Date();

  this.testimonialStore = null;
  this.showTimer = null;

  me.getTestimonials();
};

Math.rand = function(min, max)
{
	var 
		n;
					
	max -= min - 1;
	n = Math.round(Math.random() * max);
	if(n == max)
	{
		n = 0;
	}
	return n + min;
}
Array.prototype.keys = function()
{
	var 
		x,
		keys = [];
				
	for(x in this)
	{
		if(x in Array.prototype)
		{
			continue;
		}
		keys.push(x);
	}
	return keys;
}
Array.prototype.indexOf = function(value)
{
	var
		keys = this.keys(),
		i = keys.length;
				
	while(--i >= 0)
	{
		if(this[keys[i]] == value)
		{
			return keys[i];
		}
	}
	return null;
}
Array.prototype.shuffle = function()
{
	var
		shuffled = [],
		rands = [],
		rand,
		keys = this.keys();
					
	while(keys.length != shuffled.length)
	{
		do
		{
			rand = Math.rand(0, keys.length - 1);
		}
		while(rands.indexOf(rand) !== null);
		shuffled.push(this[keys[rand]]);
		rands.push(rand);
	}
	return shuffled;
}

