
/**
 * Peerius class and static methods.
 */
var Peerius={
	rId:-1
	,ign:{} /** ignore html elements */
	,pp:{} /** post parameters */
	,excTxt:false

	,fixXml: function(s){
		s = s.replace(/&/g, "&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;");
		return s;
	}
	,browser:function(){
		var agt=navigator.userAgent.toLowerCase();
		if (agt.indexOf("opera") != -1) return 'Opera';
		if (agt.indexOf("firefox") != -1) return 'Firefox';
		if (agt.indexOf("safari") != -1) return 'Safari';
		if (agt.indexOf("msie") != -1) return 'msie';
	}
	,isIE8:function(){return window.XDomainRequest?true:false;}
	,shallIgnore:function(el,attr)
	{
		if (attr)
		{
			// check attribute ignore
			var a=this.getAttr(el,attr);
			return !(typeof a=='string' && !this.ign['@'+attr] && !this.ign['@'+attr+'='+a]);
		}
		// check element ignore
		var tag=el.tagName.toLowerCase();
		if (this.ign[tag]) return 'ign';
		if (this.ign['-'+tag]) return 'deepign';
		for(var i=0;i<this.attrs.length;i++)
		{
			var attr=this.attrs[i];
			var a=this.getAttr(el,attr);
			if (a && typeof a=='string')
			{
				var ex=tag+'[@'+attr+'='+a+']';
				if(this.ign['-'+ex]) return 'deepign';
				if(this.ign[ex]) return 'ign';
			}
		}
		var ep=el.parentNode
		if(ep){
			var c=0;
			for(var i=0;i<ep.childNodes.length;i++)
			{
				var epc=ep.childNodes[i];
				if (epc==el)
				{
					if (this.ign[tag+'['+c+']']) return 'ign';
					if (this.ign['-'+tag+'['+c+']']) return 'deepign';
				}
				if (epc.nodeType==1) c++;
			}
			var tn=ep.tagName.toLowerCase();
			if(tn=='tbody' || tn=='table')
			{
				if(tag!='tr' && tag!='thead' && tag!='tbody') return 'deepign';//invalid table nodes
			}
		}
		return 'inc';
	}
	,getAttr:function(e,attr)
	{
		var a=e.getAttribute(attr);
		if (attr=='class' && this.browser()=='msie')
		{
			a=e.getAttribute('className');
			if(!a) a=e.getAttribute('class'); //ie8
		}
		return a;
	}
	,attrs:new Array('id','class','value','name','href','src','content')
	/**
	 * this method scans el dom and generates xml out of it.
	 */
	,toXml:function(el){
		switch (el.nodeType) {
		case 1:
			var xml = "";
			var ign=this.shallIgnore(el);
			var tn=el.tagName;
			var ine=(ign=='inc' && tn!="");
			if (ine)
			{
				if(tn.charAt(0)=='/') tn=tn.substring(1);
				xml+="<" + tn;
				for(var i=0;i<this.attrs.length;i++)
				{
					var attr=this.attrs[i];
					var a=this.getAttr(el,attr);
					if (a && !this.shallIgnore(el,attr)) xml+=' '+attr+'="'+this.fixXml(a)+'"';
				}
				xml += ">";
			}
			if(ign!='deepign')
			{
				var nodes = el.childNodes;
				for (var i = 0; i < nodes.length; i++) xml += this.toXml(nodes[i]);
			}
			if(ine) xml += "</" + tn + ">";
			return xml;
		case 3:
			if (this.excTxt) return "";
			return this.fixXml(el.nodeValue);
		}
		return "";
	}

	/**
	 * get's the nth element with the specified tag name
	 */
	,getNth:function(tagName, n) {
		var items = document.getElementsByTagName(tagName);
		return items[n];
	}

	,isArray:function (obj) {
	    return obj.constructor == Array;
	}
	,exists:function(e)
	{
		try { return this.expr(e)!=null; } catch(ex){return false};
	}
	/**
	 * finds the element described in the expr
	 * 
	 * @param expr		i.e. x/table[4]
	 * @return				element, i.e. the 4rth table inside the element with id='x', 
	 * 								or the elements for a multi element expr, i.e. /x/td[]
	 */
	,expr:function (expr,start)
	{
		var a=expr.split('/');
		var cel=start?start:document.body;
		for(var i=0;i<a.length;i++)
		{
			var s=a[i];
			if(s=='html')
			{
				cel=document.getElementsByTagName("html")[0];
			} else if (s.charAt(0)=='$')
			{
				/**
				 * by id
				 */
				cel=document.getElementById(s.substring(1));
				if (cel==null) return null;
			} else
			{
				var sp=s.split('[');
				var tagName=sp[0].toUpperCase();
				var byName=(sp.length==2);
				var pos=byName?parseInt(sp[1].substring(0,sp[1].length-1)):null;
				if(tagName.length==0)
				{
					/**
					 * by position
					 */
					cel=cel.childNodes[pos];
				} else
				{
					if (typeof pos == 'number')
					{
						/**
						 * name and position
						 */
						var els=cel.childNodes;
						cel=null;
						var k=0;
						for (var j=0;j<els.length;j++)
						{
							if (els[j].tagName==tagName)
							{
								if (pos==k) cel=els[j];
								k++;
							}
						}
					} else 
					{
						/**
						 * by name
						 */
						var els=new Array();
						/** doing something like cel.getElementsByTagName(tagName); */
						for(var k=0;k<cel.childNodes.length;k++)
						{
							var z=cel.childNodes[k];
							if (z.tagName==tagName) els[els.length]=z;
						}
						if (i==a.length-1) return els;
						var r=new Array();
						for(var k=0;k<els.length;k++)
						{
							var z=els[k];
							var xr=this.expr(a.slice(i+1).join('/'),z);
							if (this.isArray(xr)) 
							{
								for(var l=0;l<xr.length;l++) r[r.length]=xr[l];
							}
							else r[r.length]=xr;
						}
						return r;
					}
				}
			}
		}
		return cel;
	}

	/**
	 * creates an IFrame and adds it to the parent element
	 * 
	 * @param parentElement			the element where the iframe will be created. Can be null
	 * @return									the iframe dom
	 */
	,iframe:function(parentElement) {
		/* Create the iframe which will be returned */
		var iframe = document.createElement("iframe");
		iframe.style.display = 'none';

		/* If no parent element is specified then use body as the parent element*/
		if (parentElement == null)
			parentElement = document.body;
	
		/* This is necessary in order to initialize the document inside the iframe */
		document.body.insertBefore(iframe, parentElement.firstChild)
		/* Initiate the iframe's document to null */
		iframe.doc = null;
	
		/*
			Depending on browser platform get the iframe's document, this is only
			available if the iframe has already been appended to an element which
			has been added to the document
		*/
		if (iframe.contentDocument) {
			/* Firefox, Opera*/
			iframe.doc = iframe.contentDocument;
		} else if (iframe.contentWindow) {
			/* Internet Explorer */
			iframe.doc = iframe.contentWindow.document;
		} else if (iframe.document) {
			/* Others? */
			iframe.doc = iframe.document;
		}
		/* If we did not succeed in finding the document then throw an exception */
		if (iframe.doc == null) throw "Peerius.iframe(): Document not found";
	
		iframe.doc.open();
		iframe.doc.close();
	
		/* 
		 * Return the iframe, now with an extra property iframe.doc containing the
		 * iframe's document 
		 */
		return iframe;
	}
	/**
	 * creates an input box
	 * @param name		the name of the input
	 * @param value			the value
	 * @param form			the form that this input will be appended
	 * @param doc			the document where the input element will be created
	 * @return					the input dom
	 */
	,input:function(name,value,form,doc)
	{
		var input = doc.createElement("input");
		input.type="text";
		input.name=name;
		input.value=value;
		form.appendChild(input);
		return input;
	}
	,esc:function(s)
	{
		return encodeURIComponent(s);
	}
	/**
	 * sends a message to the method
	 * 
	 * @param method			the server side method that will receive the msg
	 * @param msg				the message
	 * @return						void
	 */
	,send:function(method,msg,serverUrl){
		var sessionId=Peerius.sessionId;
		var user=this.rCookie("peerius_user");
		var mm="method="+method+"&referer="+this.esc(document.location)+"&pageReferrer="+this.esc(document.referrer);
		mm+=(sessionId?"&sessionId="+sessionId:"")+(user?"&user="+this.esc(user):"")+"&msg="+this.esc(msg)+"&rid="+this.rId;
		for(var n in this.pp) mm+="&params['"+n+"']="+this.esc(this.pp[n]);
		mm=mm.replace(/(%20)+/g,'%20');

		var m=serverUrl+"?"+mm;

		var isIE="msie"==this.browser();
		if(window.XDomainRequest)
		{
			// IE 8
			var xdr = new XDomainRequest('application/x-www-form-urlencoded');
			xdr.open("GET", m);
			xdr.send();
		} else if ( (!isIE && m.length<7300) || (isIE && m.length<2047))
		{
			this.runScript(m)
		} else {
			var iframe=this.iframe();
			iframe.id='peeriusIFrame';
			var doc = iframe.doc;
			var form = doc.createElement("form");
			form.method = 'POST';
			form.acceptCharset="UTF-8";
			form.action = serverUrl;
			/*
			 * safari doesn't report the referer for iframes
			 */
			this.input("referer",document.location,form,doc);
			this.input("rid",this.rId,form,doc);
			this.input("pageReferrer",document.referrer,form,doc);
			this.input("method",method,form,doc);
			if (sessionId) this.input("sessionId",sessionId,form,doc);
			if (user) this.input("user",user,form,doc);
			for(var n in this.pp) this.input("params['"+n+"']",this.pp[n],form,doc);
			var textarea = doc.createElement("textarea");
			textarea.name = 'msg';
			textarea.value = msg;
			form.appendChild(textarea);
			doc.body.appendChild(form);
			form.submit();
			
			// fix IE history
			if(isIE) setTimeout(function () 
			{
				try{
				document.body.removeChild(document.getElementById("peeriusIFrame"));
				} catch(e){};
			},1500);
		}
	}
	,runScript:function(url,id){
		var script=document.createElement("script");
		script.src=url;
		script.charset="UTF-8";
		if (id) script.id=id;
		script.type="text/javascript";
		document.getElementsByTagName("head")[0].appendChild(script);
	}
	/**
	 * adds an onload function
	 * 
	 * @param func		the function that will be executed during onload
	 * @return				-
	 */
	,onload:function(func) 
	{
		var oldonload = window.onload;
		if (typeof window.onload != 'function') {
			window.onload = func;
		} else {
			window.onload = function() {
				if (oldonload) {
					oldonload();
				}
				func();
			}
		}
	}
	/**
	 * cookie creation
	 */
	,cCookie:function(name,value,secs) {
		if (secs) {
			var date = new Date();
			date.setTime(date.getTime()+(secs*1000));
			var expires = "; expires="+date.toGMTString();
		}
		else var expires = "";
		document.cookie = name+"="+value+expires+"; path=/";
	}
	/**
	 * reads a cookie
	 * 
	 * @param name		the name of the cookie
	 * @return					the value of the cookie
	 */
	,rCookie:function(name) {
		var nameEQ = name + "=";
		var ca = document.cookie.split(';');
		for(var i=0;i < ca.length;i++) {
			var c = ca[i];
			while (c.charAt(0)==' ') c = c.substring(1,c.length);
			if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
		}
		return null;
	}
	,recsMap:null
	,fixUrls:function(e,serverUrl)
	{
		for(var i=0;i<e.childNodes.length;i++)
		{
			var n=e.childNodes[i];
			if(n.nodeName=='A' && n.href)
			{
				var href=n.href;
				var idx=href.indexOf('//');
				if (idx==-1) throw 'fixUrls: cant find //';
				idx=href.indexOf('/',idx+2);
				href=href.substring(idx);
				if(n.href.indexOf('ignore:')!=0)
				{
					var rid=this.recsMap[href];
					if(!rid) throw 'fixUrls: rid not found for '+href;
					n.href="javascript:Peerius.clickRec('"+serverUrl+"',"+rid+",'"+n.href+"');";
				} else n.href=n.href.substring(7);
			}
			this.fixUrls(n,serverUrl);
		}
	}
	,clickRec:function(serverUrl,rid,href)
	{	
		Peerius.runScript(serverUrl+"/recommendationTrack.page?rId="+rid,'_peerRec');
		setTimeout("document.location='"+href+"'",1000);
	}
	,recExprs:function(xpath)
	{
		var xps=xpath.split(',');
		for(var i=0;i<xps.length;i++)
		{
			try
			{
				if(xps[i]=='ignore') return 'ign';
				var e=this.expr(xps[i]);
				if (e) return e;
			} catch(e) {};
		}
		throw 'Invalid recs xpaths: '+xpath;
	}
	,dynamic:function(){
		var sessionId=Peerius.rCookie("peerius_sess");
		var userId=Peerius.rCookie("peerius_user");
		var s="https://pt.peerius.com/tracker/tracker.page?ref="+this.esc(document.location)+"&r="+new Date().getTime();
		if (sessionId)
		{
			Peerius.cCookie("peerius_sess",sessionId,7200);
			s+='&sessionId='+this.esc(sessionId);
		}
		if(userId) s+="&userId="+this.esc(userId)
		Peerius.cCookie("peerius_ct","t",5); // are cookies enabled?
		if(!Peerius.rCookie("peerius_ct")) s+="&ct=0";
		this.runScript(s,"peeriusScript");
	}
}
if("msie"==Peerius.browser())
{
	var p_p_handler=document.onreadystatechange;
	document.onreadystatechange=function()
	{
		if(document.readyState=='complete' || document.readyState=='interactive')
		{
			document.onreadystatechange=p_p_handler;
			Peerius.dynamic();
		}
		if(p_p_handler) p_p_handler();
	}
} else
{
	Peerius.dynamic();
}