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

/**
 * @class Handles user tracking on the Edmunds site
 * @author Edmunds.com
 * @version 0.0.6
 * @static
 */
YAHOO.Edmunds.UserTrack = {
    /**
     * @property Class version
     * @static
     */
    VERSION: "0.0.6",
    /**
     * Initialize the class
     *
     * @memberOf YAHOO.Edmunds.UserTrack
     * @param void
     * @return void
     * @static
     */
    ini: function() {
        this.root_path = "/";
        this.edmunds_cookie_name = "edmunds";
        this.edmunds_domain = ".edmunds.com";
        this.zip_cookie_name = "zip";
        this.dma_cookie_name = "dma";
        this.edw_cookie_name = "edw";
        this.apache_cookie_name = "Apache";
        this.edw_timestamp_cookie_name = "edwtimestamp";
        this.state_cookie_name = "state";
        this.countyfips_cookie_name = "countyfips";
        // EDMID is the identity cookie
        this.session = new YAHOO.Edmunds.Cookie("EDMID", -1);
        this.oneYear = new YAHOO.Edmunds.Cookie("EdmundsYear", 60*60*24*365*1);
        this.thirtyMinute = new YAHOO.Edmunds.Cookie("EdmundsThirtyMinute", 60*30);

        // Combined cookie delimiter.  See UserTrack.  Single char.
        this.DELIM = "&";
    },
    /**
     * @memberOf YAHOO.Edmunds.UserTrack
     * @param object t XMLHttpRequest object
     * @return void
     * @static
     */
    setStateCountyInfo: function(t) {
        var stateTags = t.responseXML.getElementsByTagName("state");
        if(stateTags && stateTags[0] && stateTags[0].childNodes[0]) {
          this.setCookieValue(this.state_cookie_name, stateTags[0].childNodes[0].nodeValue, this.oneYear);
        }
        var countyTags = t.responseXML.getElementsByTagName("county-fips");
        if(countyTags && countyTags[0] && countyTags[0].childNodes[0]) {
          this.setCookieValue(this.countyfips_cookie_name, countyTags[0].childNodes[0].nodeValue, this.oneYear);
        }

        // Retrieve DMA info corresponding to the zip code entered
        var dmaTags = t.responseXML.getElementsByTagName("dma");
        if(dmaTags && dmaTags[0] && dmaTags[0].childNodes[0]) {
          this.setCookieValue(this.dma_cookie_name, dmaTags[0].childNodes[0].nodeValue, this.oneYear);
        }

        this.doneFlag = true;
    },
    /**
     * @memberOf YAHOO.Edmunds.UserTrack
     * @param object t XMLHttpRequest
     * @return void
     * @static
     */
    setDMAInfo: function(t) {
        // Retrieve DMA info corresponding to the zip code entered
        var dmaTags = t.responseXML.getElementsByTagName("dma");
        if(dmaTags && dmaTags[0] && dmaTags[0].childNodes[0]) {
          this.setCookieValue(this.dma_cookie_name, dmaTags[0].childNodes[0].nodeValue, this.oneYear);
        }

        this.dmaDoneFlag = true;
    },
    /**
     * @memberOf YAHOO.Edmunds.UserTrack
     * @param void
     * @return void
     * @static
     */
    displayError: function() {
        this.doneFlag = true;
    },
    /**
     * @memberOf YAHOO.Edmunds.UserTrack
     * @param void
     * @return void
     * @static
     */
    displayDmaError: function() {
        this.dmaDoneFlag = true;
    },
    /**
     * @memberOf YAHOO.Edmunds.UserTrack
     * @param void
     * @return void
     * @static
     */
    getAjaxRequest: function() {
        var req = false;
        // ignore ajax calls for certain hosts.
        // (why can't this be inclusive?  just www?)
        if (location.hostname == 'townhall-talk.edmunds.com' ||
            location.hostname == 'blogs.edmunds.com' ||
            location.hostname == 'answers.edmunds.com' ||
            location.hostname == 'carspace.com' ||
            location.hostname == 'www.carspace.com' ||
            location.hostname == 'secure.edmunds.com') {
            return(req);
        }
        // branch for native XMLHttpRequest object
        if(window.XMLHttpRequest && !(window.ActiveXObject)) {
            try {
                req = new XMLHttpRequest();
            } catch(e) {
                req = false;
            }
        // branch for IE/Windows ActiveX version
        } else if(window.ActiveXObject) {
            try {
                req = new ActiveXObject("Msxml2.XMLHTTP");
            } catch(e) {
                try {
                    req = new ActiveXObject("Microsoft.XMLHTTP");
                } catch(e) {
                    req = false;
                }
            }
        }
        return req;
    },
    /**
     * @memberOf YAHOO.Edmunds.UserTrack
     * @param int zipcode Zipcode
     * @return void
     * @static
     */
    queryStateCountyInfo: function(zipcode) {
        var req = this.getAjaxRequest();
        if (req) {
            var _this = this;
            this.doneFlag = false;
            req.open("GET", "/zipcode/queryZIP.jsp?zipcode="+zipcode, false);
            req.onreadystatechange=function(){
                if (req.readyState==4){_this.setStateCountyInfo(req);}
                else {_this.displayError(req);}
            };
            req.send(null);
        }
    },
    /**
     * @memberOf YAHOO.Edmunds.UserTrack
     * @param void
     * @return void
     * @static
     */
    queryDMAByInetAddr: function() {
        var req = this.getAjaxRequest();
        if (req) {
            var _this = this;
            this.doneFlag = false;
            req.open("GET", "/zipcode/queryDMA.jsp", false);
            req.onreadystatechange=function(){
                if (req.readyState==4){_this.setDMAInfo(req);}
                else {_this.displayDmaError(req);}
            };
            req.send(null);
        }
    },
    /**
     * @memberOf YAHOO.Edmunds.UserTrack
     * @param void
     * @return string
     * @static
     */
    getEdmundsCookie: function() {
        var edmundsCookie = this.getCookieValue(this.edmunds_cookie_name, true);
        if (edmundsCookie == null || edmundsCookie == "") {
            return this.getCookieValue(this.apache_cookie_name, true);
        } else {
            return edmundsCookie;
        }
    },
    /**
     * @memberOf YAHOO.Edmunds.UserTrack
     * @param void
     * @return string
     * @static
     */
    getEdwCookie: function() {
        return this.getCookieValue(this.edw_cookie_name, true);
    },
    /**
     * @memberOf YAHOO.Edmunds.UserTrack
     * @param void
     * @return string
     * @static
     */
    getEdwTimestampCookie: function() {
        return YAHOO.Edmunds.Core.timestamp;
    },
    /**
     * @memberOf YAHOO.Edmunds.UserTrack
     * @param void
     * @return void
     * @deprecated
     * @static
     */
    setEdwTimestamp: function() {
    },
    /**
     * @memberOf YAHOO.Edmunds.UserTrack
     * @param void
     * @return string
     * @static
     */
    getEdwTimestamp: function() {
        return YAHOO.Edmunds.Core.timestamp;
    },
    /**
     * @memberOf YAHOO.Edmunds.UserTrack
     * @param void
     * @return string
     * @static
     */
    getZipCookie: function() {
        var retval = this.getCookieValue(this.zip_cookie_name, false);
        if (retval == null) {
            return "";
        }
        return retval;
    },
    /**
     * @memberOf YAHOO.Edmunds.UserTrack
     * @param string zip Zipcode
     * @return string
     * @static
     */
    setZipCookie: function(zip) {
        this.queryStateCountyInfo(zip);
        return(this.setCookieValue(this.zip_cookie_name, zip, this.oneYear));
    },
    /**
     * @memberOf YAHOO.Edmunds.UserTrack
     * @param void
     * @return string
     * @static
     */
    getDmaCookie: function() {
        var retval = this.getCookieValue(this.dma_cookie_name, false);
        if (retval == null) {
            var zip = this.getZipCookie();
            if (zip.length>0){
                this.queryStateCountyInfo(zip);
                retval = this.getCookieValue(this.dma_cookie_name, false);
            } else {
                this.queryDMAByInetAddr();
                retval = this.getCookieValue(this.dma_cookie_name, false);
           }
        } else if (retval.split(':')[1]=='IP'){
            var zip = this.getZipCookie();
            if (zip.length>0){
                this.queryStateCountyInfo(zip);
                retval = this.getCookieValue(this.dma_cookie_name, false);
            }
        }
        if (retval != null){
            retval = retval.split(':')[0];
        } else {
            retval = "";
        }
        return retval;
    },
    /**
     * @memberOf YAHOO.Edmunds.UserTrack
     * @param string dma
     * @return string
     * @static
     */
    setDmaCookie: function(dma) {
        return(this.setCookieValue(this.dma_cookie_name, dma, this.oneYear));
    },
    /**
     * @memberOf YAHOO.Edmunds.UserTrack
     * @param string cookieName Cookie name
     * @param bool storeSeparate Store the cookie separately?
     * @return string
     * @static
     */
    getCookieValue: function(cookieName, storeSeparate) {
        var dc = document.cookie;

      if (dc == null || dc.length == 0) {
        return null;
      }

      if (storeSeparate) {
        return(this.getCookie(cookieName));
      } else {

        var edmundsSessionData = this.getCookieValue(this.session.getCookieName(), true);
        if (edmundsSessionData != null) {
          var cookieData = this.getEdmundsData(cookieName, edmundsSessionData);
          if (cookieData != null) {
        return(unescape(cookieData));
          }
          // Do not return null here.  We must check year cookie.
        }

        var edmundsYearData = this.getCookieValue(this.oneYear.getCookieName(), true);
        if (edmundsYearData != null) {
          var cookieData = this.getEdmundsData(cookieName, edmundsYearData);
          if (cookieData != null) {
        return(unescape(cookieData));
          }
        }
      }

      return null;
    },
    /**
     * @memberOf YAHOO.Edmunds.UserTrack
     * @param string cookieName Cookie name
     * @param string val Value
     * @param obj cookieLife time-to-live value
     * @return string
     * @static
     */
    setCookieValue: function(cookieName, val, cookieLife, storeSeparate) {
      if (!val || val == '' || val == 'null') {
        return null;
      }
      if (storeSeparate) {
        // Store as an individual cookie.
        var expdate = new Date();
        if (cookieLife && cookieLife.getTimeToLive() == -1) {
          // session cookies have no expire date.
          expdate = false;
        } else {
          // Add TTL (milliseconds) to current time.
          var exptime = expdate.getTime();
          exptime += cookieLife.getTimeToLive()*1000;
          expdate.setTime(exptime);
        }
        return(this.setCookie(cookieName, val, expdate, this.root_path, this.edmunds_domain));

      } else {
        // Store in the "cookieLife" (session or year) combined cookie.

        // Get the value of the combined cookie.
        // Delimiters will be decoded, but the individual values still encoded.
        var combinedData = this.getCookieValue(cookieLife.getCookieName(), true);
        var new_combinedData = "";

        // Escape any curious characters (space, |, etc).
        // We will match this with unescape in getCookieValue().
        val = escape(val);

        if (combinedData === null) {
          // This is the first value in the combined cookie
          // A leading delimiter makes searching easy later.
          new_combinedData = this.DELIM + cookieName + "=" + val;
        } else {
          // Try to find the cookieName in the combined cookie (eg: "&sq_data=10002,10003&...")
          var begin = combinedData.indexOf(this.DELIM + cookieName + "=");
          if (begin != -1) {
        // Use Regular Expressions on new browsers, substring on old ones.
        if (RegExp) {
          var oldvalue = new RegExp(cookieName + "=[^" + this.DELIM + "]*");
          var newvalue = cookieName + "=" + val;
          new_combinedData = combinedData.replace(oldvalue, newvalue);
        } else {
          // Backwards compatibility for old browsers that might
          // not support Regular Expressions.
          var end = combinedData.indexOf(this.DELIM, begin + 1);
          new_combinedData = this.DELIM + cookieName + "=" + val;
          if (begin === 0 && end === -1) {
            // we replace the whole cookie.
          } else if (begin === 0) {
            // replaced cookie was at the beginning of the string.
            new_combinedData += combinedData.substring(end);
          } else if (end == -1) {
            // replaced cookie was at the end of the string.
            new_combinedData += combinedData.substring(0, begin);
          } else {
            // replace cookie was in middle of the string.
            new_combinedData += combinedData.substring(0, begin);
            new_combinedData += combinedData.substring(end);
          }
        }
          } else {
        // Cookie is not in the combined string, so just append it.
        new_combinedData = combinedData + this.DELIM + cookieName + "=" + val;
          }

        }
        // Recurse this routine to update the combined cookie.
        // Note the storeSeparate parameter is "true", storing the combined cookie.
        return(this.setCookieValue(cookieLife.getCookieName(), new_combinedData, cookieLife, true));

      }
      //return null;
    },
    /**
     * @memberOf YAHOO.Edmunds.UserTrack
     * @param string cookieName Cookie name
     * @param obj cookieLife combined cookie object
     * @return string
     * @static
     */
    deleteCookieValue: function(cookieName, cookieLife) {
        // Get the value of the combined cookie.
        // Delimiters will be decoded, but the individual values still encoded.
        var combinedData = this.getCookieValue(cookieLife.getCookieName(), true);

        // Nothing to delete.
        if (combinedData === null) {
            return null;
        }

        // Try to find the cookieName in the combined cookie (eg: "&sq_data=10002,10003&...")
        var begin = combinedData.indexOf(this.DELIM + cookieName + "=");
        if (begin == -1) {
            return null;
        }

        // Use Regular Expressions on new browsers, substring on old ones.
        var new_combinedData = "";
        if (RegExp) {
          var oldvalue = new RegExp(this.DELIM + cookieName + "=[^" + this.DELIM + "]*");
          var newvalue = '';
          new_combinedData = combinedData.replace(oldvalue, newvalue);
        } else {
          // Backwards compatibility for old browsers that might
          // not support Regular Expressions.
          var end = combinedData.indexOf(this.DELIM, begin + 1);
          if (begin === 0 && end === -1) {
            // we delete the whole cookie.
            new_combinedData = "";
          } else if (begin === 0) {
            // replaced cookie was at the beginning of the string.
            new_combinedData = combinedData.substring(end);
          } else if (end == -1) {
            // replaced cookie was at the end of the string.
            new_combinedData = combinedData.substring(0, begin);
          } else {
            // replace cookie was in middle of the string.
            new_combinedData = combinedData.substring(0, begin);
            new_combinedData += combinedData.substring(end);
          }
        }
        // If null, delete the cookie otherwise set new value.
        if (new_combinedData == '') {
            return(this.removeCookie(cookieLife.getCookieName(), '', this.root_path, this.edmunds_domain));
        } else {
            return(this.setCookieValue(cookieLife.getCookieName(), new_combinedData, cookieLife, true));
        }
    },
    /**
     * @memberOf YAHOO.Edmunds.UserTrack
     * @param string cookieName Cookie name
     * @param string combinedData Cookie data
     * @return string
     * @static
     */
    getEdmundsData: function(cookieName, combinedData) {
      var prefix = cookieName + "=";
      var begin = combinedData.indexOf(this.DELIM + prefix);
      if (begin == -1) {
        return null;
      } else {
        begin++;  // skip past the delimiter. (XXX this.DELIM.length)
      }

      var end = combinedData.indexOf(this.DELIM, begin);
      if (end == -1) { end = combinedData.length; }
      return(combinedData.substring(begin + prefix.length, end));

    },
    /**
     * @memberOf YAHOO.Edmunds.UserTrack
     * @param string name Cookie name
     * @return string
     * @static
     */
    getCookie: function(name) {
      var dc = "; " + document.cookie;
      var prefix = name + "=";
      var begin = dc.indexOf("; " + prefix);
      if (begin == -1) {
        return null;
      } else {
        begin += 2;  // skip past the delimiter.
      }

      // Find the end of this cookie value.
      var end = dc.indexOf(";", begin);
      // If the last cookie, grab through the end of the string.
      if (end == -1) { end = dc.length; }
      return(dc.substring(begin + prefix.length, end));
    },
    /**
     * @memberOf YAHOO.Edmunds.UserTrack
     * @param string name Cookie name
     * @param string value Cookie value
     * @param int expires When cookie expires in seconds
     * @param string path Domain path in which the cookie lives
     * @param string domain Cookie domain
     * @param bool secure Is this cookie secured?
     * @return string
     * @static
     */
    setCookie: function(name, value, expires, path, domain, secure) {
      if(!domain) {
          domain = this.edmunds_domain;
      }

      document.cookie = escape(name) + "=" + value +
        ((expires) ? "; expires=" + expires.toGMTString() : "") +
        ((path) ? "; path=" + path : "") +
        ((domain) ? "; domain=" + domain : "") +
        ((secure) ? "; secure" : "");

      return document.cookie;
    },

    removeCookie: function(name, value, path, domain, secure) {
      var expires = new Date(1);
      document.cookie = escape(name) + "=" + value +
        ((expires) ? "; expires=" + expires.toGMTString() : "") +
        ((path) ? "; path=" + path : "") +
        ((domain) ? "; domain=" + domain : "") +
        ((secure) ? "; secure" : "");

      return document.cookie;
    },

    removeDuplicateCookie: function(name) {
        // first we'll split this cookie up into name/value pairs
        // note: document.cookie only returns name=value, not the other components
        var a_all_cookies = document.cookie.split( ';' );
        var cookie_count = 0;
        var cookie_value = null;

        for (var i = 0; i < a_all_cookies.length; i++ )
        {
          // now we'll split apart each name=value pair
          var a_temp_cookie = a_all_cookies[i].split( '=' );


          // and trim left/right whitespace while we're at it
          var cookie_name = a_temp_cookie[0].replace(/^\s+|\s+$/g, '');

          // if the extracted name matches passed check_name
          if ( cookie_name == name )
          {
            cookie_count++;

            if ( a_temp_cookie.length > 1 )
            {
                cookie_value = a_all_cookies[i].substring(a_all_cookies[i].indexOf("=") + 1);
            }
          }
          a_temp_cookie = null;
          cookie_name = '';
        }
        if ( cookie_count > 1 )
        {
          for(var remove_count = 0; remove_count < cookie_count; remove_count++) {
              this.removeCookie(name, "", null, null, null);
          }

          if(cookie_value) {
              this.setCookieValue(name, cookie_value, this.oneYear, true);
          }

          return;
        }
    },

    /**
     * @memberOf YAHOO.Edmunds.UserTrack
     * @param void
     * @return void
     * @static
     */
    migrateCookies: function() {
      // check for broken edmunds cookie
      var edmundsCookie = this.getCookie("edmunds");
      if (edmundsCookie && (edmundsCookie == 'null' || edmundsCookie == '')) {
        this.removeCookie("edmunds", "", this.root_path);
      }

      var zip = this.getCookie("zip");
      if (zip) {
        this.setZipCookie(zip);
        this.removeCookie("zip", "", this.root_path);
      }
      // check delete zip @ www.edmunds.com?  how common?

      // AL is handled by DCMCommon
      // FN, LN, CID, EMAIL, THSN, THA, ET, savedcar
      var old_cookies = ["FN", "LN", "CID", "EMAIL", "THSN", "THA", "ET", "savedcar"];
      for (var i = 0; i < old_cookies.length; i++) {
        var name = old_cookies[i];
        var val = this.getCookie(name);
        if (val) {
          this.setCookieValue(name, val, this.oneYear, false);
          this.removeCookie(name, "", this.root_path);
        }
      }

      // delete old bad domain cookies
      this.removeDuplicateCookie("EdmundsYear");
      this.removeDuplicateCookie("EdmundsSession");
      this.removeDuplicateCookie("EdmundsThirtyMinute");
    }
};

YAHOO.Edmunds.Cookie.Session = new YAHOO.Edmunds.Cookie("EDMID", -1);
YAHOO.Edmunds.Cookie.OneYear = new YAHOO.Edmunds.Cookie("EdmundsYear", 60*60*24*365*1);
YAHOO.Edmunds.Cookie.ThirtyMinute = new YAHOO.Edmunds.Cookie("EdmundsThirtyMinute", 60*30);
YAHOO.Edmunds.UserTrack.ini();
YAHOO.Edmunds.UserTrack.migrateCookies();
