/**
 * @fileOverview Handles ad units throughout the site. Displays them in either
 * JavaScript or iFrame formats.
 */

if (typeof YAHOO.Edmunds == 'undefined') {
	YAHOO.Edmunds = {};
}


/**
 *	AdUnit class can be used as a helper to create and output IFrame or Javascrip Ads.
 *
 *	@requires	YAHOO
 *  @requires   YAHOO.Edmunds
 *  @requires   YAHOO.util.Event
 *  @requires   YAHOO.lang
 *	@class		Ad unit manager
 *	@param		string	id					The HTMLElement ID of the ad
 *	@param		bool	readXMLAsStringFlag	Read XML as a string flag? (???????)
 *	@param		string	targetParams		The URL querystring
 *	@param		int		addRandomNum		Add a random number to the querystring?
 *	@param		string	format				"iframe" or "javascript"
 *	@param		int		width				Width of the HTMLElement of ad
 *	@param		int		height				Height of the HTMLElement of ad
 *	@param		string	siteName			Name of the site calling the ad (???????)
 *	@param		string	styleName			The layout style of the ad
 *	@param		string	requestPageUrl		The URL of the page firing off the request
 *	@param		string	target				Where to load that ad content?  // unused - probably now hardcoded in the iframe html.
 *	@return		void
 *	@constructor Initialize the instance variables
 */
YAHOO.Edmunds.AdUnit = function(id, readXMLAsStringFlag, targetParams, addRandomNum, format, width, height, siteName, styleClass, styleName, requestPageUrl, target) {
	this.id = id;
	this.readXMLAsStringFlag = readXMLAsStringFlag;
	this.targetParams = targetParams;
	this.addRandomNum = addRandomNum;
	this.format = format;
	this.width = width;
	this.height = height;
	this.siteName = siteName;
	this.styleClass = styleClass;
	this.styleName = styleName;
	this.requestPageUrl = requestPageUrl;
	this.target = target;
    this.randomNumParam = "";

    // If targetParams doesn't specify the u-value, generate one automatically.
    if (this.targetParams !== '' && YAHOO.lang.isNull(this.targetParams.match(/;u=[^;]+;/))) {
        var userValue = this.generateUserValue(this.targetParams);
        this.targetParams += userValue;
    }
    // Map name=!PARAMs to their PARAM values.
    this.targetParamsOnce = this.replaceAdVariablesOnce(this.targetParams, this.requestPageUrl);
    this.targetParams = this.replaceAdVariablesRefresh(this.targetParamsOnce);
};


YAHOO.Edmunds.AdUnit.prototype = {
	/**
	 *	Refresh the ad after an AJAX call is made
	 *
	 *	@memberOf YAHOO.Edmunds.AdUnit
	 *	@param	void
	 *	@return	void
	 */
	notify: function() {
	    this.targetParams = this.replaceAdVariablesRefresh(this.targetParamsOnce);
        // Replace the adframe's src with the now-loaded image url.
        var adFrame = document.getElementById(this.id);
        if(adFrame.contentWindow){
           adFrame.contentWindow.location.replace(this.getAdUrl());
        } else if(adFrame.contentDocument){
           adFrame.contentDocument.location.replace(this.getAdUrl());
        }
    },
	/**
	 *	Manually set the random number parameter of this object
	 *
	 *	@memberOf YAHOO.Edmunds.AdUnit
	 *	@param	int	randomParam	Random number
	 *	@return	void
	 */
	setRandomNum: function(randNumParam) {
		this.randomNumParam = randNumParam;
	},
	/**
	 *	Return the URL of this object
	 *
	 *	@memberOf YAHOO.Edmunds.AdUnit
	 *	@param	void
	 *	@return	string		The ad URL
	 */
	getAdUrl: function () {
		var randNum = this.randomNumParam === '' ? ((this.addRandomNum)? "ord=" + globalRandNum : "") : this.randomNumParam;
		var adTargetParams = (typeof facetsTargetParams != "undefined" && facetsTargetParams !== null) ? this.targetParams + ";" + facetsTargetParams : this.targetParams;
		//

		return "http://ad.doubleclick.net/" + ((this.format == "iframe")? "adi/":"adj/") +
					this.siteName + "/;" + adTargetParams +
					";sz=" + this.width + "x" + this.height + ";" + randNum;
	},
	/**
	 *	Create a Javascript configured Ad and echo it into the DOM
	 *
	 *	@memberOf YAHOO.Edmunds.AdUnit
	 *	@param	void
	 *	@return	void
	 */
	outputAdJS: function () {
		var src = this.getAdUrl('javascript');
	  	if(this.styleName !== null && this.styleName !== '') {
			this.styleName = "name=\"" + this.styleName + "\"";
	  	} else {
			this.styleName = "";
	  	}

	  	var content = "<script language=\"Javascript1.1\" src=\"" + src + "\" class=\"" + this.styleClass + "\" width=\"" + this.width +
                       "\" height=\"" + this.height + "\" frameborder=\"no\" border=\"0\" marginwidth=\"0\" marginheight=\"0\" scrolling=\"no\">" +
					   "</script> <noscript>" +
					   "<a href=\"" + src + "\">" +
					   "<img src=\"" + src + "\" width=\"" + this.width + "\" height=\"" + this.height + "\" border=\"0\">" +
					   "</a> </noscript>";

		document.write(content);
	},
	/**
	 *	Registers this Ad to update content on globalAjax refreshAds calls
	 *
	 *	@memberOf YAHOO.Edmunds.AdUnit
	 *	@param	void
	 *	@return	void
	 */
	registerAd: function() {
		if (window.g_AJAXHelper){
    		g_AJAXHelper.registerAd(this);
  		}
	},
	/**
	 *	Writes out the Ad in one of two ways, depending on the format
	 *
	 *	@memberOf YAHOO.Edmunds.AdUnit
	 *	@param	void
	 *	@return	void
	 */
	outputAd: function() {
		 if (this.format == 'iframe') {
			// Finds an IFrame and updates its src location to point to the URL of the passed AdUnit Object
			var updateContent = function(evt, adUnitObj) {
				var adFrame = document.getElementById(adUnitObj.id);
			  	if(adFrame.contentWindow){
					adFrame.contentWindow.location.replace(adUnitObj.getAdUrl());
			  	} else if(adFrame.contentDocument){
					adFrame.contentDocument.location.replace(adUnitObj.getAdUrl());
			  	}
			};
			if (!document.getElementById(this.id)) {
                YAHOO.util.Event.addListener(window, 'load', updateContent, this);
            } else {
                updateContent('', this);
            }
		} else {
			this.outputAdJS();
		}
	},
	/**
	 *	Create a Javascript configured Ad and echo it into the DOM
	 *
	 *	@memberOf YAHOO.Edmunds.AdUnit
	 *	@param	string	targetParams	The URL querystring
	 *	@param	string	requestUrl		The URL in which the ad container lives
	 *	@return	string	The updated URL querystring
	 */
	replaceAdVariablesOnce: function(targetParams, requestPageUrl) {
		//regular expressions for replacement variable names to be used
		var pageurlKey = /(!PAGEURL)/g;
		var zipKey = /(!ZIP)/g;
		var dmaKey = /(!DMA)/g;
		var edmundsKey = /(!EDMUNDSID)/g;
		var resisegKey = /(!RSISEG)/g;
		var edwKey = /(!EDW)/g;
        var stateKey = /(!STATE)/g;
		var countyFipKey = /(!COUNTYFIP)/g;

		//if target parameters has content then check for replacement variables
		if(targetParams !== ''){

			//replace the page url with value from the request
			if(requestPageUrl!='null'){
				//replace all instances of PAGEURL variable
				targetParams = targetParams.replace(pageurlKey, requestPageUrl);
			}

			//check to see if zip cookie exists
			if (!YAHOO.lang.isNull(targetParams.match(zipKey))){
				var zipValue = YAHOO.Edmunds.UserTrack.getZipCookie();
				if(zipValue !== ''){
					//replace all instances of ZIP variable
					targetParams = targetParams.replace(zipKey, zipValue);
				}
			}

			//check to see if state cookie exists
			if (!YAHOO.lang.isNull(targetParams.match(stateKey))){
				var stateValue = YAHOO.Edmunds.UserTrack.getCookieValue(YAHOO.Edmunds.UserTrack.state_cookie_name);
				if(stateValue !== '') {
				  //replace all instances of ZIP variable
				  targetParams = targetParams.replace(stateKey, stateValue);
				}
			}

			//check to see if county fip cookie exists
			if (!YAHOO.lang.isNull(targetParams.match(countyFipKey))){
				var countyFipValue = YAHOO.Edmunds.UserTrack.getCookieValue(YAHOO.Edmunds.UserTrack.countyfips_cookie_name);
				if(countyFipValue !== '') {
				  //replace all instances of ZIP variable
				  targetParams = targetParams.replace(countyFipKey, stateValue + countyFipValue);
				}
			}

			//check to see if edmunds id cookie exists
			if (!YAHOO.lang.isNull(targetParams.match(edmundsKey))){
				var edmundsIdValue = YAHOO.Edmunds.UserTrack.getEdmundsCookie();
				if(edmundsIdValue !== '' && !YAHOO.lang.isNull(edmundsIdValue)){
					//replace all instances of EDMUNDSID variable
					targetParams = targetParams.replace(edmundsKey, edmundsIdValue);
				}
			}

			//check to see if rsi_segs cookie exists
			if (!YAHOO.lang.isNull(targetParams.match(resisegKey))){
				var resisegValue = YAHOO.Edmunds.UserTrack.getCookie("rsi_segs");
				if(resisegValue !== '' && !YAHOO.lang.isNull(resisegValue)) {
					//reformat the resiseg value
					resisegValue = resisegValue.replace(/B05501_(\d+)\|?/g, "rs=$1;");
					resisegValue = resisegValue.replace(/((rs=\d+;){10}).*/, "$1");
					targetParams = targetParams.replace(resisegKey, resisegValue);
				} else {

					//check to see if DMSEG cookie exists
					resisegValue = YAHOO.Edmunds.UserTrack.getCookie("DMSEG");
					if(resisegValue !== '' && !YAHOO.lang.isNull(resisegValue)){
						//reformat the resiseg value
						resisegValue = reformatResisegCookie(resisegValue);
						//replace all instances of RESISEG variable
						targetParams = targetParams.replace(resisegKey, resisegValue);
					}
				}
			}

			//check to see if edw cookie exists
			if (!YAHOO.lang.isNull(targetParams.match(edwKey))){
				var edwValue = YAHOO.Edmunds.UserTrack.getCookie("edw");
				if(edwValue !== '' && !YAHOO.lang.isNull(edwValue)){
					//replace all instances of EDW variable
					targetParams = targetParams.replace(edwKey, edwValue);
				}
			}

            // Replace all instances of DMA variable, even if dmaValue
			// is an empty string.
			if (!YAHOO.lang.isNull(targetParams.match(dmaKey))){
				var dmaValue = YAHOO.Edmunds.UserTrack.getDmaCookie();
				targetParams = targetParams.replace(dmaKey, dmaValue);
			}
		}
		return targetParams;
	},

	/**
     *      Create a Javascript configured Ad and echo it into the DOM.  This method is called every time the ad is refreshed
     *      @method replaceAdVariablesRefresh
     *      @param  string  targetParams    The URL querystring
     *      @return string  The updated targetParams querystring
     */
    replaceAdVariablesRefresh: function(targetParams) {
    	//regular expressions for replacement variable names to be used
        var edwTimestampKey = /(!TIMESTAMP)/g;

        //if target parameters has content then check for replacement variables
        if(targetParams !== ''){
        	if (!YAHOO.lang.isNull(targetParams.match(edwTimestampKey))){
            	var edwTimestampValue = YAHOO.Edmunds.Core.timestamp;
                if(edwTimestampValue !== '') {
                	//replace all instances of TIMESTAMP variable
                    targetParams = targetParams.replace(edwTimestampKey, edwTimestampValue);
                }
            }
        	return targetParams;
        }
    },

    /**
     * @memberOf YAHOO.Edmunds.AdUnit
     * @method generateUserValue
     * @param object paramHash    key/value hash of ad parameters
     * @return string    the u-value string
     *
     * The form of the u-value is:
     *     u=[KEY_VALUE:...]|ED_COOKIE|EDW_COOKIE|TIMESTAMP|URL|ZIP;
     * The valid key_value components are:
     *     [dma, cty] - from cookie values
     *     ["make", "mdl", "page", "pos", "sect",  "seg", "theme", "type"] - from page parameters
     */        
    generateUserValue: function(targetParams) {
        var uvalStr = "u=make_X:mdl_X:page_X:pos_X:sect_X:seg_X:theme_X:type_X:cty_!COUNTYFIP:dma_!DMA|!EDMUNDSID|!EDW|!TIMESTAMP|!PAGEURL|!ZIP;";

        // Decompose targetParams into key/value pairs and build a map.
        var paramHash = {};
        var paramRe = /([^=]+)=([^;]+);/g;
        while (paramRe.test(targetParams)) {
            paramHash[paramRe.$1] = paramRe.$2;
        }

        // RE function to replace name_PARAMs from paramHash or remove.
        function replaceUval(matchstr, p1) {
            if (paramHash[p1]) {
                return(p1 + "_" + paramHash[p1] + ":");
            } else {
                return("");
            }
        }

        // Map all name_X: strings to their name_value: or delete.
        uvalStr = uvalStr.replace(/([a-z]+)_X:/g, replaceUval);
        return(uvalStr);
    }

};

/**
 * @property Class version
 * @type string
 * @static
 */
YAHOO.Edmunds.AdUnit.VERSION = "0.0.8";

/**
 * @property Array of ad units
 * @type array
 * @static
 */
YAHOO.Edmunds.AdUnit.ad_units = [];

/**
 *	Populate the ad_units array
 *
 *	@memberOf YAHOO.Edmunds.AdUnit
 *	@param	mixed	ad_obj	Arra of AdUnit objects or a single AdUnit object
 *	@return	void
 *	@static
 */
YAHOO.Edmunds.AdUnit.add = function(ad_obj) {
	if (ad_obj.constructor == Array) {
		for(var i=0; i < ad_obj.length; i++) {
			YAHOO.Edmunds.AdUnit.ad_units.push(ad_obj[i]);
		}
	} else {
		YAHOO.Edmunds.AdUnit.ad_units.push(ad_obj);
	}
};

/**
 *	Get an AdUnit object from the ad_units array or return the whole array
 *
 *	@memberOf YAHOO.Edmunds.AdUnit
 *	@param	string(?)	The ID of the AdUnit that's required
 *	@return	mixed		AdUnit object or the full ad_units array
 *	@static
 */
YAHOO.Edmunds.AdUnit.get = function() {
	if (arguments.length) {
		return YAHOO.Edmunds.AdUnit.ad_units[YAHOO.Edmunds.Util.getKey(YAHOO.Edmunds.AdUnit.ad_units, arguments[0])];
	} else {
		return YAHOO.Edmunds.AdUnit.ad_units;
	}
};

/**
 *	Populate the ad_units array
 *
 *	@memberOf YAHOO.Edmunds.AdUnit
 *	@param	void
 *	@return	void
 *	@static
 */
YAHOO.Edmunds.AdUnit.process = function() {
    var obj, src, adFrame;
    if (arguments.length && arguments[0].constructor == Object) {
		YAHOO.Edmunds.AdUnit.add(arguments[0]);
		obj = arguments[0];
		src = obj.getAdUrl('iframe');
		adFrame = document.getElementById(obj.id);
		if(adFrame.contentWindow) {
			adFrame.contentWindow.location.replace(src);
		} else if(adFrame.contentDocument) {
			adFrame.contentDocument.location.replace(src);
		} else {

		}
		if (window.g_AJAXHelper) {
			g_AJAXHelper.registerAd(obj);
		}
	}
	else {
		for(var i=0; i < YAHOO.Edmunds.AdUnit.ad_units.length; i++) {
			obj = YAHOO.Edmunds.AdUnit.ad_units[i];
			src = obj.getAdUrl('iframe');
			adFrame = document.getElementById(obj.id);
			if(adFrame.contentWindow) {
				adFrame.contentWindow.location.replace(src);
			} else if(adFrame.contentDocument) {
				adFrame.contentDocument.location.replace(src);
			} else {

			}
			if (window.g_AJAXHelper) {
				g_AJAXHelper.registerAd(obj);
			}
		}
	}
};
