

var _listingAdPreViewportWidth = 1024;
var adServerURL = 'http://ads.trademe.co.nz';

// Remove the prefix from the domain so adserver iframes can interact with the main window.
currentDomain = document.domain;
currentDomainSplit = currentDomain.split('.');
currentSiteName = currentDomainSplit[currentDomainSplit.length - 3].toLowerCase();
if(currentSiteName == "trademe") document.domain = "trademe.co.nz";
else if(currentSiteName == "findsomeone") document.domain = "findsomeone.co.nz";
else if(currentSiteName == "oldfriends") document.domain = "oldfriends.co.nz";
else if(currentSiteName == "travelbug") document.domain = "travelbug.co.nz";

var Ads = function() {

	// List of adrequests on the page.
	var adRequests = [];

	//	Temporary storage place for the html that is injected into IFrames (when using the InlineIFrame display type)
	var inlineIFrameHtml = [];
   
    // List of callback functions to notify when an ad is loaded.
    var adLoadedEventCallbacks = [];
    
	// Some contants used by the toJSON functions.
	var _escapeable = /["\\\x00-\x1f\x7f-\x9f]/g;
	var _meta = {'\b': '\\b','\t': '\\t','\n': '\\n','\f': '\\f','\r': '\\r','"' : '\\"','\\': '\\\\' }
	
	// Used to keep track of how many external scripts are still to load, for each ad.
	var _numScriptsRemaining = [];
	
	return {
	
		// Records the existence of an ad on the page that we'll have to render later.
		registerAd : function(targetElementID, type, customParameters) {
			var adRequest = {};
			adRequest.ID = targetElementID;
			adRequest.Type = type;
			if (customParameters) 
				adRequest.CustomParameters = customParameters.split(',');
			else
				adRequest.CustomParameters = [];
			adRequests.push(adRequest);
		},
		
		// Allows a page hosting ads to react to an ad being loaded.
		subscribeToAdLoadedEvent : function(callback) {
		    adLoadedEventCallbacks.push(callback);
		},
		
		// Notifies all subscribers that the ad has been loaded.
		fireAdLoadedEvent : function(ad) {
		    for (var i=0; i < adLoadedEventCallbacks.length; i++)
		        adLoadedEventCallbacks[i](ad);
		},

		// All ads on the page have been registered, so request the ad content from the adserver.
		populateAds : function (context) {
		    if (adRequests.length > 0)
			    jQuery.ajax({
				    url: adServerURL + '/GetMultipleAds.aspx?jsoncallback=?&c=' + encodeURIComponent(context) + '&a=' + encodeURIComponent(Ads.base64Encode(Ads.toJSON(adRequests))),
				    dataType: "script",
				    type: "GET", 
				    cache: false });			
		},
		
		// Called when we recieve the response from the adserver. Handles the rendering of the ad content.
		getMultipleAdsCallback : function(ads) {
			for (var i=0; i < ads.length; i++) {
				var ad = ads[i];
				switch (ad.DisplayType) {
					case 'Div' : Ads.renderDivAd(ad); break;
					case 'InlineIFrame' : Ads.renderInlineIFrame(ad); break;
					case 'FullIFrame' : Ads.renderFullIFrame(ad); break;
				}
				Ads.fireAdLoadedEvent(ad);
			}
		},

		// Render the ad by dumping the returned html straight into the div.		
		renderDivAd : function(ad) {
	        
			// If there are external scripts to load.
			if (ad.ExternalScripts && ad.ExternalScripts.length > 0) {		
			    _numScriptsRemaining[ad.ID] = ad.ExternalScripts.length;
			    jQuery.ajaxSetup({cache: true});
			    for (var i=0; i < ad.ExternalScripts.length; i++)
		            jQuery.getScript(ad.ExternalScripts[i],  function() { Ads.externalScriptLoadedCallback(ad); });
			    jQuery.ajaxSetup({cache: false});
			}
			else {
			    jQuery('#' + ad.ID).html(ad.Html);
			}
		},
		
		// Called when an external script has loaded.
		externalScriptLoadedCallback : function (ad) {
		    // Decrement the count of the number of scripts still to load. 
		    if (--_numScriptsRemaining[ad.ID] == 0) {
		        // No scripts left to load, so insert the html.
			    jQuery('#' + ad.ID).html(ad.Html);
		    }
		},
		        
		// Render the ad by dumping the html into an iframe using JavaScript.
		renderInlineIFrame : function(ad) {
			inlineIFrameHtml[ad.ID] = ad.Html;
			
			var iframe = document.createElement("iframe");
			iframe.scrolling = "no";
			iframe.frameBorder ="0";
			iframe.allowTransparency = "true";
			iframe.width = ad.Width + 'px';
			iframe.height = ad.Height + 'px'
			iframe.src="javascript:parent.Ads.getInlineIFrameHtml('" + ad.ID + "')"
			jQuery("#" + ad.ID).append(iframe);
		},
		
		// Render the ad by creating an iframe and setting its src to the value returned from the adserver.
		renderFullIFrame : function(ad) {
			var iframe = document.createElement("iframe");
			iframe.scrolling = "no";
			iframe.frameBorder ="0";
			iframe.allowTransparency = "true";
			iframe.width = ad.Width + 'px';
			iframe.height = ad.Height + 'px'
			iframe.src = ad.Src;
			jQuery("#" + ad.ID).append(iframe);
		},
		
		// Used by renderInlineIFrame to get the html to inject into the iframe.
		getInlineIFrameHtml : function(id) {
			return inlineIFrameHtml[id];
		},
        
		// Base 64 encodes the string. Used to construct the adserver request URL.
		_keyStr : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
		base64Encode : function (input) {
			var output = "";
			var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
			var i = 0;

			while (i < input.length) {

				chr1 = input.charCodeAt(i++);
				chr2 = input.charCodeAt(i++);
				chr3 = input.charCodeAt(i++);

				enc1 = chr1 >> 2;
				enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
				enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
				enc4 = chr3 & 63;

				if (isNaN(chr2)) {
					enc3 = enc4 = 64;
				} else if (isNaN(chr3)) {
					enc4 = 64;
				}

				output = output +
				this._keyStr.charAt(enc1) + this._keyStr.charAt(enc2) +
				this._keyStr.charAt(enc3) + this._keyStr.charAt(enc4);

			}

			return output;
		},

		// Converts an object to JSON. A cut down version of the jQuery JSON Plugin, version: 2.1 (2009-08-14) http://code.google.com/p/jquery-json/
		toJSON : function(o)
		{
			var type = typeof(o);

			if (o === null)
				return "null";

			if (type == "undefined")
				return undefined;

			if (type == "number" || type == "boolean")
				return o + "";

			if (type == "string")
				return Ads.quoteString(o);

			if (type == 'object')
			{
				if (typeof o.toJSON == "function") 
					return Ads.toJSON( o.toJSON() );

				if (o.constructor === Date)
				{
					var month = o.getUTCMonth() + 1;
					if (month < 10) month = '0' + month;

					var day = o.getUTCDate();
					if (day < 10) day = '0' + day;

					var year = o.getUTCFullYear();

					var hours = o.getUTCHours();
					if (hours < 10) hours = '0' + hours;

					var minutes = o.getUTCMinutes();
					if (minutes < 10) minutes = '0' + minutes;

					var seconds = o.getUTCSeconds();
					if (seconds < 10) seconds = '0' + seconds;

					var milli = o.getUTCMilliseconds();
					if (milli < 100) milli = '0' + milli;
					if (milli < 10) milli = '0' + milli;

					return '"' + year + '-' + month + '-' + day + 'T' +
								 hours + ':' + minutes + ':' + seconds + 
								 '.' + milli + 'Z"'; 
				}

				if (o.constructor === Array) 
				{
					var ret = [];
					for (var i = 0; i < o.length; i++)
						ret.push( Ads.toJSON(o[i]) || "null" );

					return "[" + ret.join(",") + "]";
				}

				var pairs = [];
				for (var k in o) {
					var name;
					var type = typeof k;

					if (type == "number")
						name = '"' + k + '"';
					else if (type == "string")
						name = Ads.quoteString(k);
					else
						continue;  //skip non-string or number keys

					if (typeof o[k] == "function") 
						continue;  //skip pairs where the value is a function.

					var val = Ads.toJSON(o[k]);

					pairs.push(name + ":" + val);
				}

				return "{" + pairs.join(", ") + "}";
			}
		},

		quoteString : function(string)
		{
			if (_escapeable.test(string))
			{
				return '"' + string.replace(_escapeable, function (a) 
				{
					var c = _meta[a];
					if (typeof c === 'string') return c;
					c = a.charCodeAt();
					return '\\u00' + Math.floor(c / 16).toString(16) + (c % 16).toString(16);
				}) + '"';
			}
			return '"' + string + '"';
		}
	}
}();
