//2008-01 johnv Added DMA for NON-www hosts.  
// DO NOT ALTER THIS WITHOUT TALKING TO JOHNV!

////////////////////////////////////////////////////////
//
// EdmundsCookieLife 
//
////////////////////////////////////////////////////////

// object constructor
function EdmundsCookieLife(cookieName, timeToLiveSeconds) {
     this.cookieName = cookieName;
     this.timeToLiveSeconds = timeToLiveSeconds;
     this.getTimeToLive = fnGetTimeToLive;
     this.getCookieName = fnGetCookieName;
}

function fnGetTimeToLive() {
  return this.timeToLiveSeconds;
}

function fnGetCookieName() {
  return this.cookieName;
}

////////////////////////////////////////////////////////
//
// UserTrack
//
////////////////////////////////////////////////////////

function UserTrack() {
  if (window.location.href.toLowerCase().indexOf("edmunds.nytimes.com") != -1) {
      this.edmunds_domain = "edmunds.nytimes.com";
  } else {
      this.edmunds_domain = ".edmunds.com";
  }
  this.root_path = "/";
  this.edmunds_cookie_name = "edmunds";
  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";

  this.session = new EdmundsCookieLife("EdmundsSession", -1);
  this.oneYear = new EdmundsCookieLife("EdmundsYear", 60*60*24*365);
  this.thirtyMinute = new EdmundsCookieLife("EdmundsThirtyMinute", 60*30);  
    
  // Combined cookie delimiter.  See UserTrack.  Single char.
  this.DELIM = "&";
 
  this.getDmaCookie = fnGetDmaCookie;
  this.getEdmundsCookie = fnGetEdmundsCookie;
  this.getEdwCookie = fnGetEdwCookie;
  this.setZipCookie = fnSetZipCookie;
  this.getZipCookie = fnGetZipCookie;
  this.getCookieValue = fnGetCookieValue;
  this.setCookieValue = fnSetCookieValue;
  this.getEdmundsData = fnGetEdmundsData;
  this.getCookie = fnGetCookie;
  this.setCookie = fnSetCookie;
  this.getEdwTimestamp = fnGetEdwTimestamp;
  this.setEdwTimestamp = fnSetEdwTimestamp;
  this.getEdwTimestampCookie = fnGetEdwTimestampCookie;
}

// Don't do ajax here.  This is for non www.edmunds.com hosts.
function fnGetDmaCookie() {
        var dma = this.getCookieValue(this.dma_cookie_name, false);
        if (dma == null || dma == "") { return ""; }
        return(dma.split(':')[0])
}

function fnGetEdmundsCookie() {
  var edmundsCookie = this.getCookieValue(this.edmunds_cookie_name, true);
  if (edmundsCookie == null || edmundsCookie == "") {
    return this.getCookieValue(this.apache_cookie_name, true);
  } else {
    return edmundsCookie;
  }
} 

// Retrieve the edw cookie value.
function fnGetEdwCookie() {
  return this.getCookieValue(this.edw_cookie_name, true);
}

// Retrieve the timestamp cookie value.
function fnGetEdwTimestampCookie() {
  return this.getCookieValue(this.edw_timestamp_cookie_name, true);
}

// set a timestamp to help tie pageview and data (edw and dart snap logs)
function fnSetEdwTimestamp(ts) {    
  timestamp = ts;    
}

// get a timestamp to help tie pageview and ad data (edw and dart snap logs)
// to be used once all pages are being served via Day.
function fnGetEdwTimestamp() {
  return window.timestamp || new Date().getTime();
}

// Retrieve the zip cookie value from the EdmundsYear combined cookie.
// If no zip cookie value, return an empty string.
function fnGetZipCookie() {
  var retval = this.getCookieValue(this.zip_cookie_name, false);
  if (retval == null) {
    return "";
  }
  return retval;
}

// Set the zip cookie value in the EdmundsYear combined cookie.
function fnSetZipCookie(zip) {
  return(this.setCookieValue(this.zip_cookie_name, zip, this.oneYear));     
}

// getCookieValue(string, boolean)
// Retrieve a cookie value
//  From a individual named cookie (eg: edmunds, edw)
// or if not separate cookie
//  From the EdmundsSession combined cookie
// or
//  From the EdmundsYear combined cookie
// Returns a cookie value or null if no such cookie exists.
function fnGetCookieValue(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;
}

// setCookieValue(string, string, EdmundsCookieLife Object, boolean)
// Set a cookie as a separate (if storeSeparate == true)
// Or as part of the combined cookie cookieLife.
function fnSetCookieValue(cookieName, val, cookieLife, storeSeparate) {
  if (!val || val == '' || val == 'null') {
    return;
  }
  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));  
    
  }    
}

// getEdmundsData(string, string)
// combinedData is the delimited string from one of the combined cookies (year or session).
// Finds the specified name and returns the associated value.
// Returns null if the name does not exist.
function fnGetEdmundsData(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));
  
}

// getCookie(string)
// Get an individual cookie from the browser.
// Cookies are delimited by "; " (eg: "edw=101; edmunds=500b; zip=06226")
// Returns null if cookie does not exist.
// Otherwise returns the value from cookie string ("06226" from "zip=06226")
function fnGetCookie(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));
}

// setCookie(string, string, DATE, string, string, boolean)
// Set an individual cookie in the browser.
// expires must be a date object.
// (Can this ever return false?)
function fnSetCookie(name, value, expires, path, domain, secure) {
  var cookie_str = escape(name) + "=" + value +
    ((expires) ? "; expires=" + expires.toGMTString() : "") +
    ((path) ? "; path=" + path : "") +
    ((domain) ? "; domain=" + domain : "") +
    ((secure) ? "; secure" : "");    
  //alert("Setting: " + cookie_str);
  return(document.cookie = cookie_str);
}

/////////////////////////////////////////////////////////
EdmundsCookieLife.Session = new EdmundsCookieLife("EdmundsSession", -1);
EdmundsCookieLife.OneYear = new EdmundsCookieLife("EdmundsYear", 60*60*24*365);
EdmundsCookieLife.ThirtyMinute = new EdmundsCookieLife("EdmundsThirtyMinute", 60*30);
var userTrack = new UserTrack();
var timestamp;
