function md5(str){var xl;var rotateLeft=function(lValue,iShiftBits){return(lValue<<iShiftBits)|(lValue>>>(32-iShiftBits))};var addUnsigned=function(lX,lY){var lX4,lY4,lX8,lY8,lResult;lX8=(lX&0x80000000);lY8=(lY&0x80000000);lX4=(lX&0x40000000);lY4=(lY&0x40000000);lResult=(lX&0x3FFFFFFF)+(lY&0x3FFFFFFF);if(lX4&lY4){return(lResult^0x80000000^lX8^lY8)}if(lX4|lY4){if(lResult&0x40000000){return(lResult^0xC0000000^lX8^lY8)}else{return(lResult^0x40000000^lX8^lY8)}}else{return(lResult^lX8^lY8)}};var _F=function(x,y,z){return(x&y)|((~x)&z)};var _G=function(x,y,z){return(x&z)|(y&(~z))};var _H=function(x,y,z){return(x^y^z)};var _I=function(x,y,z){return(y^(x|(~z)))};var _FF=function(a,b,c,d,x,s,ac){a=addUnsigned(a,addUnsigned(addUnsigned(_F(b,c,d),x),ac));return addUnsigned(rotateLeft(a,s),b)};var _GG=function(a,b,c,d,x,s,ac){a=addUnsigned(a,addUnsigned(addUnsigned(_G(b,c,d),x),ac));return addUnsigned(rotateLeft(a,s),b)};var _HH=function(a,b,c,d,x,s,ac){a=addUnsigned(a,addUnsigned(addUnsigned(_H(b,c,d),x),ac));return addUnsigned(rotateLeft(a,s),b)};var _II=function(a,b,c,d,x,s,ac){a=addUnsigned(a,addUnsigned(addUnsigned(_I(b,c,d),x),ac));return addUnsigned(rotateLeft(a,s),b)};var convertToWordArray=function(str){var lWordCount;var lMessageLength=str.length;var lNumberOfWords_temp1=lMessageLength+8;var lNumberOfWords_temp2=(lNumberOfWords_temp1-(lNumberOfWords_temp1%64))/64;var lNumberOfWords=(lNumberOfWords_temp2+1)*16;var lWordArray=new Array(lNumberOfWords-1);var lBytePosition=0;var lByteCount=0;while(lByteCount<lMessageLength){lWordCount=(lByteCount-(lByteCount%4))/4;lBytePosition=(lByteCount%4)*8;lWordArray[lWordCount]=(lWordArray[lWordCount]|(str.charCodeAt(lByteCount)<<lBytePosition));lByteCount++}lWordCount=(lByteCount-(lByteCount%4))/4;lBytePosition=(lByteCount%4)*8;lWordArray[lWordCount]=lWordArray[lWordCount]|(0x80<<lBytePosition);lWordArray[lNumberOfWords-2]=lMessageLength<<3;lWordArray[lNumberOfWords-1]=lMessageLength>>>29;return lWordArray};var wordToHex=function(lValue){var wordToHexValue="",wordToHexValue_temp="",lByte,lCount;for(lCount=0;lCount<=3;lCount++){lByte=(lValue>>>(lCount*8))&255;wordToHexValue_temp="0"+lByte.toString(16);wordToHexValue=wordToHexValue+wordToHexValue_temp.substr(wordToHexValue_temp.length-2,2)}return wordToHexValue};var x=[],k,AA,BB,CC,DD,a,b,c,d,S11=7,S12=12,S13=17,S14=22,S21=5,S22=9,S23=14,S24=20,S31=4,S32=11,S33=16,S34=23,S41=6,S42=10,S43=15,S44=21;str=this.utf8_encode(str);x=convertToWordArray(str);a=0x67452301;b=0xEFCDAB89;c=0x98BADCFE;d=0x10325476;xl=x.length;for(k=0;k<xl;k+=16){AA=a;BB=b;CC=c;DD=d;a=_FF(a,b,c,d,x[k+0],S11,0xD76AA478);d=_FF(d,a,b,c,x[k+1],S12,0xE8C7B756);c=_FF(c,d,a,b,x[k+2],S13,0x242070DB);b=_FF(b,c,d,a,x[k+3],S14,0xC1BDCEEE);a=_FF(a,b,c,d,x[k+4],S11,0xF57C0FAF);d=_FF(d,a,b,c,x[k+5],S12,0x4787C62A);c=_FF(c,d,a,b,x[k+6],S13,0xA8304613);b=_FF(b,c,d,a,x[k+7],S14,0xFD469501);a=_FF(a,b,c,d,x[k+8],S11,0x698098D8);d=_FF(d,a,b,c,x[k+9],S12,0x8B44F7AF);c=_FF(c,d,a,b,x[k+10],S13,0xFFFF5BB1);b=_FF(b,c,d,a,x[k+11],S14,0x895CD7BE);a=_FF(a,b,c,d,x[k+12],S11,0x6B901122);d=_FF(d,a,b,c,x[k+13],S12,0xFD987193);c=_FF(c,d,a,b,x[k+14],S13,0xA679438E);b=_FF(b,c,d,a,x[k+15],S14,0x49B40821);a=_GG(a,b,c,d,x[k+1],S21,0xF61E2562);d=_GG(d,a,b,c,x[k+6],S22,0xC040B340);c=_GG(c,d,a,b,x[k+11],S23,0x265E5A51);b=_GG(b,c,d,a,x[k+0],S24,0xE9B6C7AA);a=_GG(a,b,c,d,x[k+5],S21,0xD62F105D);d=_GG(d,a,b,c,x[k+10],S22,0x2441453);c=_GG(c,d,a,b,x[k+15],S23,0xD8A1E681);b=_GG(b,c,d,a,x[k+4],S24,0xE7D3FBC8);a=_GG(a,b,c,d,x[k+9],S21,0x21E1CDE6);d=_GG(d,a,b,c,x[k+14],S22,0xC33707D6);c=_GG(c,d,a,b,x[k+3],S23,0xF4D50D87);b=_GG(b,c,d,a,x[k+8],S24,0x455A14ED);a=_GG(a,b,c,d,x[k+13],S21,0xA9E3E905);d=_GG(d,a,b,c,x[k+2],S22,0xFCEFA3F8);c=_GG(c,d,a,b,x[k+7],S23,0x676F02D9);b=_GG(b,c,d,a,x[k+12],S24,0x8D2A4C8A);a=_HH(a,b,c,d,x[k+5],S31,0xFFFA3942);d=_HH(d,a,b,c,x[k+8],S32,0x8771F681);c=_HH(c,d,a,b,x[k+11],S33,0x6D9D6122);b=_HH(b,c,d,a,x[k+14],S34,0xFDE5380C);a=_HH(a,b,c,d,x[k+1],S31,0xA4BEEA44);d=_HH(d,a,b,c,x[k+4],S32,0x4BDECFA9);c=_HH(c,d,a,b,x[k+7],S33,0xF6BB4B60);b=_HH(b,c,d,a,x[k+10],S34,0xBEBFBC70);a=_HH(a,b,c,d,x[k+13],S31,0x289B7EC6);d=_HH(d,a,b,c,x[k+0],S32,0xEAA127FA);c=_HH(c,d,a,b,x[k+3],S33,0xD4EF3085);b=_HH(b,c,d,a,x[k+6],S34,0x4881D05);a=_HH(a,b,c,d,x[k+9],S31,0xD9D4D039);d=_HH(d,a,b,c,x[k+12],S32,0xE6DB99E5);c=_HH(c,d,a,b,x[k+15],S33,0x1FA27CF8);b=_HH(b,c,d,a,x[k+2],S34,0xC4AC5665);a=_II(a,b,c,d,x[k+0],S41,0xF4292244);d=_II(d,a,b,c,x[k+7],S42,0x432AFF97);c=_II(c,d,a,b,x[k+14],S43,0xAB9423A7);b=_II(b,c,d,a,x[k+5],S44,0xFC93A039);a=_II(a,b,c,d,x[k+12],S41,0x655B59C3);d=_II(d,a,b,c,x[k+3],S42,0x8F0CCC92);c=_II(c,d,a,b,x[k+10],S43,0xFFEFF47D);b=_II(b,c,d,a,x[k+1],S44,0x85845DD1);a=_II(a,b,c,d,x[k+8],S41,0x6FA87E4F);d=_II(d,a,b,c,x[k+15],S42,0xFE2CE6E0);c=_II(c,d,a,b,x[k+6],S43,0xA3014314);b=_II(b,c,d,a,x[k+13],S44,0x4E0811A1);a=_II(a,b,c,d,x[k+4],S41,0xF7537E82);d=_II(d,a,b,c,x[k+11],S42,0xBD3AF235);c=_II(c,d,a,b,x[k+2],S43,0x2AD7D2BB);b=_II(b,c,d,a,x[k+9],S44,0xEB86D391);a=addUnsigned(a,AA);b=addUnsigned(b,BB);c=addUnsigned(c,CC);d=addUnsigned(d,DD)}var temp=wordToHex(a)+wordToHex(b)+wordToHex(c)+wordToHex(d);return temp.toLowerCase()}function utf8_encode(argString){var string=(argString+'');var utftext="",start,end,stringl=0;start=end=0;stringl=string.length;for(var n=0;n<stringl;n++){var c1=string.charCodeAt(n);var enc=null;if(c1<128){end++}else if(c1>127&&c1<2048){enc=String.fromCharCode((c1>>6)|192)+String.fromCharCode((c1&63)|128)}else{enc=String.fromCharCode((c1>>12)|224)+String.fromCharCode(((c1>>6)&63)|128)+String.fromCharCode((c1&63)|128)}if(enc!==null){if(end>start){utftext+=string.slice(start,end)}utftext+=enc;start=end=n+1}}if(end>start){utftext+=string.slice(start,stringl)}return utftext}

var Adcell = {};

/**
 * objekt dass informationen aus dem user-rechner auslesen kann
 * @returns {AdcellUser}
 */
Adcell.User = function (){
	/**
	 * key der von aussen vom server gesetzt werden kann
	 * @var string userKey 
	 */
	this.userKey = '';
	
	/**
	 * hält die partnerid des users vor
	 * @var string partnerid
	 */
	this.partnerId = '';
	
	/**
	 * ads die dem user angezeigt werden
	 * @var object iserAds
	 */
	this.userAds = new Object();
	
	/**
	 * setzt den extern ermittelten userkey
	 * @param string newUserKey 
	 */
	this.setUserKey = function(newUserKey){
		this.userKey = newUserKey;
	};
	
	/**
	 * ermittelt aus diversen vom browser lesbaren rechner-eigenschaften einen MD5 schlüssel
	 * @returns string
	 */
	this.getFingerprint = function(){
		var viewKey = this.userKey;
		viewKey += window.screen.availWidth;
		viewKey += window.screen.availHeight;
		viewKey += window.screen.colorDepth;
		viewKey += window.navigator.appCodeName;
		viewKey += window.navigator.appName;
		viewKey += window.navigator.appVersion;
		viewKey += window.navigator.buildID;
		viewKey += window.navigator.userAgent;
		viewKey += window.navigator.product;
		viewKey += window.navigator.platform;
		viewKey += window.navigator.vendor;
		viewKey += window.navigator.vendorSub;
		viewKey += window.navigator.javaEnabled();
		for(i = 0; i < window.navigator.mimeTypes.length; i++){
			viewKey += window.navigator.mimeTypes[i].description + " = " + window.navigator.mimeTypes[i].type + "(" + window.navigator.mimeTypes[i].suffixes + ")";
		}
		for(i = 0; i < window.navigator.plugins.length; i++){
			viewKey += window.navigator.plugins[i].name + ", mimes = " + window.navigator.plugins[i].length;
		}
		
		return md5(viewKey);
	};
	
	/**
	 * fügt eine werbung zum user hinzu, setzt den fp und gibt das ad-objekt zurück
	 * @param AdcellUserAd ad
	 * @returns AdcellUserAd
	 */
	this.addAd = function(ad){
		ad.setFingerprint(this.getFingerprint());
		this.userAds[ad.getBid()] = ad;  
		return ad;
	};
	
	/**
	 * setzt die partnerid
	 * @param string partnerId
	 */
	this.setPartnerId = function(partnerId){
		this.partnerId = partnerId;
	};
	
	/**
	 * holt ein werbemittel von adcell dynamisch
	 * 
	 * obj kann folgende Eigenschaften haben:
	 * 	string wid:			Id des Werbemittels. 
	 * 						Erster Teil der ehemaligen "bid=1234-5678-abcd"
	 * 	string partnerId:	optionale Id des Kunden. 
	 * 						Zweiter Teil der ehemaligen "bid=1234-5678-abcd"
	 * 						kann global mit "Adcell.user.setPartnerId('5678');" gesetzt werden
	 * 	string subid:		optionaler String der ein genaueres Tracken von Transaktionen ermöglicht
	 * 						Dritter Teil der ehemaligen "bid=1234-5678-abcd"
	 * 	string id : 		optionale ID des DOM-Elements in welches das Werbemittel eingefügt wird, 
	 * 						ohne id wird das Werbemittel an der Stelle des Aufrufs mit document.write ausgegeben
	 * 
	 * @param object obj
	 */
	this.getAd = function(obj){
		var idString = '';
		if(typeof(obj.id) != "undefined"){
			idString = '&id='+obj.id;
		}
		var subidString = '';
		if(typeof(obj.subid) != "undefined"){
			subidString = '-'+obj.subid;
		}
		var partnerId = this.partnerId; 
		if(typeof(obj.partnerId) != "undefined"){
			partnerId = obj.partnerId;
		}
		
		document.write('<script type="text/javascript" src="'+window.location.protocol+'//www.adcell.de/jsad.php?bid=' + obj.wid + '-' + partnerId + subidString + idString + '"></script>');
	};	
	
	/**
	 * tracken einer Transaktion
	 * @param object obj
	 */
	this.track = function(obj){
		var params = '';
		for(param in obj){
			params += '&' + param + '=' + obj[param];  
		}
		
		document.write('<script type="text/javascript" src="'+window.location.protocol+'//www.adcell.de/jsevent.php?' + params + '"></script>');
	};
}

/**
 * zuständig für die Rückgabe der werbung
 * @returns {AdcellUserAd}
 */
Adcell.Ad = function (bid){
	this.bid = bid;
	/**
	 * MD5fp des users
	 * @var string 
	 */
	this.fingerprint = '';
	
	/**
	 * dieser string wird im ad-code durch den fp ersetzt
	 * @var string 
	 */
	this.fingerprintPlaceholder = '@@fp@@';
	
	/**
	 * quellcode des ads
	 * @var string
	 */
	this.code = '';
	
	/**
	 * setzt den fingerprint für das ad
	 * @param string newFingerprint
	 */
	this.setFingerprint = function(newFingerprint){
		this.fingerprint = newFingerprint;
	};
	
	/**
	 * leert den code
	 * notwendig bei mehreren ad-aufrufen
	 */
	this.resetCode = function(){
		this.code = '';
	};
	
	/**
	 * setzt den code des ads 
	 * achtung - js kann nur einzeilige strings - string muss also vorbereitet werden
	 * @param string newCode
	 */
	this.setCode = function(newCode){
		this.code = newCode;
	};
	
	/**
	 * fügt eine zeile an den ad-code an
	 * @param string codeLine
	 */
	this.addCodeLine = function(codeLine){
		this.code += codeLine;
	};
	
	/**
	 * ausgabe des code. 
	 * wenn eine id gesetzt, dann in das element hinein, andernfalls direkte ausgabe
	 * @param string id
	 * 
	 * @todo use document.createElement('') ?
	 */
	this.print = function(id){
		this.code = this.injectFingerPrint(this.code);
		if(typeof(id) != "undefined"){
			document.getElementById(id).innerHTML = this.code;
		} else {
			document.write(this.code);
		}
	};
	
	/**
	 * hilfsfunktion zum ersetzen des fingerprint im adcode.
	 * in den adcode muss man nur "@@fp@@" schreiben um dort stattdessen den echten code "&fp=244534534" zu erhalten
	 * @param string input
	 * @returns string
	 */
	this.injectFingerPrint = function(input){
		var search = this.fingerprintPlaceholder;
		var replace = '&fp='+this.fingerprint;
		var subject = input;
		var count = false;
		
		//ab hier: inhalt der funktion str_replace aus phpjs 
		var i=0,j=0,temp='',repl='',sl=0,fl=0,f=[].concat(search),r=[].concat(replace),s=subject,ra=r instanceof Array,sa=s instanceof Array;s=[].concat(s);if(count){this.window[count]=0;}
		for(i=0,sl=s.length;i<sl;i++){if(s[i]===''){continue;}
		for(j=0,fl=f.length;j<fl;j++){temp=s[i]+'';repl=ra?(r[j]!==undefined?r[j]:''):r[0];s[i]=(temp).split(f[j]).join(repl);if(count&&s[i]!==temp){this.window[count]+=(temp.length-s[i].length)/f[j].length;}}}
		return sa?s:s[0];
	};
	
	this.getBid = function(){
		return this.bid;
	};
};

Adcell.user = new Adcell.User();
