/* Namespace setting */
if (typeof expediaNS === "undefined"){
	var expediaNS = {};
}

if (typeof expediaNS.namespace === "undefined"){
	expediaNS.namespace = function() {
		var a=arguments, o=null, i, j, d;
		for (var i=0; i<a.length; i=i+1) {
			d=a[i].split(".");
			o=expediaNS;
			for (var j=(d[0] == "expediaNS") ? 1 : 0; j<d.length; j=j+1) {
				o[d[j]]=o[d[j]] || {};
				o=o[d[j]];
			}
		}
		return o;
	};
}

expediaNS.namespace("expediaNS.ads.google");
/* End of Namespace setting */

/* The loader is only instanciated if it hasn't been already*/
if(typeof expediaNS.ads.google.loader === "undefined") {
	expediaNS.ads.google.loader = function() {
	    /* private members*/
		var obj = {};
		var called = false;
	
	    /* public members */	
		obj.template = null;
		obj.headerText = null;
		obj.url = null;
		obj.nbPlacementsToBeInPage = null;		
		obj.productType = null;
		obj.adsToShow = null; // Should be using this pattern : b3d3 (3 in bcol then 3 in dcol), d2b6 (2 in dcol then 6 in bcol)
		
		var bColFirst = null;
		var nbAdsInFirstContainer = null;
		var nbAdsInSecondContainer = null;
		
		/* private method to format 
		args : arguments array
		1st contains the string to format that contain placeholder : {0}, {1}, etc...
		all other items are the string to go in the placeholders
		*/
		var format = function(args) {
			for(var i = 1; i < arguments.length; i++) {
				var strRep = "{" + (i - 1) + "}";
				while (args.indexOf(strRep) != -1) {
					args = args.replace(strRep, arguments[i]);
				}
			}
			return args;
		}

		/* private method to render an ad based on a template
		ad : a google ad build by google code, contains the following string members : url, line1, line2, line3, visible_url
		*/		
		var renderAd = function(ad) {
			if (obj.template != null) {
			    var visibleUrl = ad.visible_url;
			    // adding visible url shortening if needed
			    visibleUrl = shortenUrlIfNeeded(visibleUrl);
				return format(obj.template, ad.url, ad.line1, ad.line2, ad.line3, visibleUrl);
			}
			else {
				return "";
			}
		}
		
        var shortenUrlIfNeeded = function(url) {
		    var ret = url;
			var removeSubDomain  = false;
			var dotCoUrl = false;
			
			var urlFirstPart = ret;
			try {
				urlFirstPart = (ret.split("/"))[0];
			} catch (e) {
			}
			var dotCoUrl = (urlFirstPart.indexOf(".co.") > -1);
		    
			var maxNumberDots = (dotCoUrl?2:1);			
			
			var arr = urlFirstPart.split(".");			
			if ((arr.length-1) > maxNumberDots) {
				removeSubDomain = true;
			}
			
			if (removeSubDomain) {
				// remove sub domain + trailing slash and everything that comes after...
				ret = ret.replace( new RegExp( '(^[a-zA-Z]+\.)|(\/.+$)', "gi" ), "" );
			} else {
				// remove only trailing slash and everything that comes after...
				ret = ret.replace( new RegExp( '(\/.+$)', "gi" ), "" );
			}
			return ret;
		}
		
		/* private method to gather the data and build the query
		only used for AFS, we assume we have comment tags with ids gtl_origin and gtl_destination in the DOM
		*/
		var getQuery = function() {			
			var orig = "";
			var desti = "";
			
			//window.parent will reference the page itself in case no iframe is there
			var destiElt = window.parent.document.getElementById("gtl_destination");
			if (destiElt) {
				desti = destiElt.getAttribute("value");
				// Getting string before the comma
				if ((desti.split(",").length) > 0) {
					desti = (desti.split(","))[0];
				}
			}
			var res = null;
			res = orig
				+ (((orig != "") && (desti != "")) ? " " : "")
				+ desti
				+ ((((desti != "") || (orig != "")) && (obj.productType != null)) ? " " : "")
				+ ((obj.productType != null) ? obj.productType : "");
            return res;
		}
		
		/*
		private callback function that receive the ads array
		google_ads : array of ads sent by google
		*/
		var callBack = function(google_ads) {
			var google_num_ads = google_ads.length;
			if (google_num_ads <= 0) 
				return;
			
			var firstContainerAds = "";
			var secondContainerAds = "";
			var hText ="";
			if (obj.headerText) {
			    hText = "<div class=\"ad_header\">" + obj.headerText + "</div>";
		    }
			
			// Building the 2 ads groups
			for(var i = 0; i < google_num_ads; i++){
				if (i<nbAdsInFirstContainer) {
					firstContainerAds += renderAd(google_ads[i]);
				}
				else {
					secondContainerAds += renderAd(google_ads[i]);					
				}
			}
			
			// Adding the placements title
			if (firstContainerAds != "") {
				firstContainerAds = hText + firstContainerAds;
			}
			if (secondContainerAds != "") {
				secondContainerAds = hText + secondContainerAds;
			}
			
			// Searching the container in the DOM
			var bColContainer = findElement("bColGoogleAdsContainer");
			// search for DOM element in the current windows and the parents
			var dColContainer = findElement("dColGoogleAdsContainer");
			if (dColContainer == null) {
				dColContainer = findElementInChild("dColGoogleAdsContainer", window);
			}
			
			// Appending the ads in the containers
			if (bColFirst) {
				if (bColContainer) {
					bColContainer.innerHTML = firstContainerAds;
				}
				if (dColContainer) {
					dColContainer.innerHTML = secondContainerAds;
				}
			} else {
				if (bColContainer) {
					bColContainer.innerHTML = secondContainerAds;
				}
				if (dColContainer) {
					dColContainer.innerHTML = firstContainerAds;
				}
			}
			
			// .com specific code for showing the dcol ads container
			showDcolAdsContainer();
		}
		
		/*
		search for DOM element in the current windows and the child windows
		*/
		var findElementInChild = function(id, win) {
			var element;
			try {
				element = win.document.getElementById(id);
				if (element){
					return element;
				}
			}
			catch(e) {
				return null; // this will occur for IFrame on different domains   
			}
			for(var i = 0 ; i < win.frames.length; i++) {
				element = findElementInChild(id, win.frames[i] );
				if(element) {
					return element;
				}
			}
		}


		/*
		search for DOM element in the current windows and the parents
		*/
		var findElement = function(id) {
			var win = window;
			var elementFound = false;
			var element = null;
			
			while (win && !elementFound) {								
				element = win.document.getElementById(id);				
				if (element) {
					elementFound = true;
					break;
				} else {					
					if (win !== win.parent) {
						win = win.parent;
					} else {
						win = null;
					}
				}								
			}
			return element;
		}
		
		var getAdsToShow = function() {
			try {
				var adsPosParsingRegEx = new RegExp(/[bd]\d{1,2}/g);		
				var matchings = obj.adsToShow.match(adsPosParsingRegEx);
				// setting footer ads comes first or not
				if (matchings[0].substr(0,1) == "b") {
					bColFirst = true; // footer ads come first
				}
				if (matchings[0].substr(0,1) == "d") {
					bColFirst = false; // dcol ads come first
				}
				// setting number of ads in first container
				nbAdsInFirstContainer = parseInt(matchings[0].substr(1), 10);
				// setting number of ads in second container
				if (matchings.length == 2) {					
					nbAdsInSecondContainer = parseInt(matchings[1].substr(1), 10);
				}
				return true;
			} catch (ex) {				
				return false;
			}
		}
		
		var setAdsToShowByDefault = function() {
			bColFirst = true;
			
			nbAdsInFirstContainer = 3;
			nbAdsInSecondContainer = 3;			
			var nbAds = (nbAdsInFirstContainer + nbAdsInSecondContainer);
			
			if ((typeof google_max_num_ads  !== "undefined") && (google_max_num_ads == null)) {
				google_max_num_ads = nbAds;
			}
			if ((typeof google_afs_ad !== "undefined") && (google_afs_ad == null)) {
				google_afs_ad = 'n' + nbAds;
			}
		}

		
		/* public method that make the call to google Js
		the call is done only if: 
		    - js url definded
		    - the number of ads supposed to be in the page have been reached
		    - the call hasn't been done already
		*/
		obj.call = function() {
		    window.parent.nbPlacementsInPage ++;
			if (obj.url != null) {
				if ((window.parent.nbPlacementsInPage == obj.nbPlacementsToBeInPage) && (!called)) {
					if (!getAdsToShow()) {
						setAdsToShowByDefault();
					}
					google_afs_query = getQuery();					
					called = true;
					var sc = "script";
					document.write("<" + sc +" language=\"JavaScript\" src=\"" + obj.url + "\"></" + sc + ">");
				}
			}
		}
		
		// gets .com specif dcol ads container
		var findUsDcolAdContainer = function() {
			var usDcolAdContainer = findElement("du_midtop");
			if (usDcolAdContainer == null) {
				usDcolAdContainer = findElementInChild("du_midtop", window);
			}
			return usDcolAdContainer;
		}
		
		// hide .com dcol ads container
		var hideDcolAdsContainer = function() {
			var container = findUsDcolAdContainer();
			if (container) {
				container.style.display = "none";
			}
		}
		
		// show .com dcol ads container
		var showDcolAdsContainer = function() {
			var container = findUsDcolAdContainer();
			if (container) {
				container.style.display = "block";
			}
		}
		
		/*
		called on init
		- set the google call back function for both AFS and AFC		
		*/
		var init = function() { 
			// increment the count
			if ((typeof window.parent.nbPlacementsInPage == "undefined") || (typeof window.parent.nbPlacementsInPage == null) ){
				window.parent.nbPlacementsInPage = 0;
			}
			google_ad_request_done = callBack;
            google_afs_request_done = callBack;			
			
			// .com specific code for hiding the dcol ads container
			hideDcolAdsContainer();
		}
	
		init();
		
		return obj;
    }();
}