function goUrl(formName,selectName) {
        var form_info = eval("document." + formName+"."+selectName);
        var url = form_info.options[form_info.selectedIndex].value;
        if (url != '') {
                document.location.href=url;
        }
}
function msgUnit(url,w,h) {
messageUnit = window.open(url,'SpecialInfo','width='+w+',height='+h+',scrollbars=no,menubar=no,resizable=no');
messageUnit.focus()
}

function isBrowserOk()
{
        var agent=navigator.userAgent.toLowerCase();
        var is_aol   = (agent.indexOf("aol") != -1);
        var is_win   = ( (agent.indexOf("win")!=-1) || (agent.indexOf("16bit")!=-1) );
        //current restriction is no AOL on PC:
        if (is_aol && is_win) return false;

        return true;
}


function popupCenteredWindow(url,title,width, height, options, giveFocus){
  var winLeft = ((screen.width) / 2) - (width/2);
  var winUp = ((screen.height) / 2) - (height/2);


  var winOpened = window.open(url,title,"left=" + winLeft + ",top=" + winUp + "," + options);
  if (giveFocus)
   winOpened.focus();
  else
   self.focus();
}

function popupWindow(url,title,options){
  var winOpened = window.open(url,title,options);
  winOpened.focus();
}


//
// Tries to set zip code field from cookie value if possible. This will set the
// values of any input fields on the html by the name of zip or zipcode.
// selects, hiddens, dropdowns, radios, checkboxes, and textareas are exlcuded.
//
/* Added global flag for whether or not a valid zip cookie exists */
var hasCookie = false;
function setZipFromCookie() {
  var fs = document.forms;
  var cookie = document.cookie;
  var cookieName = "zip";
  var cookieVal;
  // return false if cookie does not exist.
  if ( cookie == null || cookie.length < 1) return false;

  var len = cookie.length;
  // try to grab cookie val from cookie.
  for ( var i = 0; i < len ; i++ ) {
    var nameEndIndex = i + cookieName.length;
    // if cookie field with appropriate name is found, try to grab value.
    if ( cookie.substring( i, nameEndIndex ) == cookieName ) {
      var cookieEndIndex = cookie.indexOf(";", nameEndIndex );
      if ( cookieEndIndex == -1 ) cookieEndIndex = len;
      cookieVal = unescape(cookie.substring( nameEndIndex+1, cookieEndIndex ));
    }
  }
  // return false if cookie exists, but does not have zip value.
  if ( cookieVal == null || cookieVal.length < 1 ) {
    return false; // exit function
  }
else {
// else a valid cookie exists, so set the hasCookie flag
hasCookie = true;
}
  // iterate through all forms on this page.
  for ( var i = 0; i < fs.length; i++ ) {
    var f = fs[i];
    var es = f.elements;
    // look a for field named zip or zipcode. It must be either a text or number input.
    for ( var j = 0; j < es.length; j++ ) {
      var e = es[j];
      if ( e != null && (e.name.toLowerCase() == "zip" || e.name.toLowerCase() == "zipcode") ) {
      // set value, return true.
      e.value = cookieVal;
      }
    }
  }
  return true;
}


function getCookieVal(name) {
var fs = document.forms;
var cookie = document.cookie;
// default is "" if cookie does not exist.
var cookieVal = "";
if ( cookie == null || cookie.length < name ) return cookieVal;
var len = cookie.length;
// try to grab cookie val from cookie.
for ( var i = 0; i < len ; i++ ) {
var nameEndIndex = i + name.length;
// if cookie field with appropriate name is found, try to grab value.
if ( cookie.substring( i, nameEndIndex ) == name ) {
var cookieEndIndex = cookie.indexOf(";", nameEndIndex );
if ( cookieEndIndex == -1 ) cookieEndIndex = len;
cookieVal = unescape(cookie.substring( nameEndIndex+1, cookieEndIndex ));
break;
}
}
// return false if cookie exists, but does not have zip value.
return cookieVal;
}

function setCookieVal(name, value, expires, path, domain) {

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

}


<!--
var time = new Date();
var randnum= (time.getTime());
//-->



 function isZipValid(zip, zipFormElement, alternateErrorMessage)
 {
         var errorMessage="Please enter a valid 5-digit Zip Code";
         if(alternateErrorMessage!=null) errorMessage= alternateErrorMessage;
         if(zip==null || isNaN(zip)|| zip.length!=5)
         {
                alert(errorMessage);
                if(zipFormElement!=null) zipFormElement.focus();
                return false;
         }
         return true;
 }

// the window will popup 1/[multiplier] times
// ie if multiplier=20, the window will popup 1/20th of the time:

function DLhandler(mult, styleid, zip, tid)
{

  if ( !isBrowserOk() )
    return;
  if ( getCookieVal("vpudlclose") == "true" )
    return;
  var dlParam = styleid + "_" + zip;
  if ( dlParam == getCookieVal("dlparam") )
    return;
  if ( Math.ceil(Math.random()*mult) != 1 )
    return;
  setCookieVal("dlparam", dlParam, null, "/", ".edmunds.com");
  var dlURL = "/apps/dl/dealerlocator.xct?dldisplay=stdalone&styleid=" + styleid + "&zip=" + zip + "&usein=n&setbcode=t&" + tid;
  var winLeft = (screen.width/2) - 350;;
  var winUp = (screen.height/2) - 250;

  if (tid.indexOf('ign') == 4){
  var win = window.open(dlURL, "dlvdppopup", "width=800,height=625,location=no,toolbar=no,menubar=yes,scrollbars=yes,status=yes,left=" + winLeft + ",top=" + winUp+",resizable=yes");
}else{
  var win = window.open(dlURL, "dlvdppopup", "width=610,height=625,location=no,toolbar=no,menubar=yes,scrollbars=yes,status=yes,left=" + winLeft + ",top=" + winUp+",resizable=yes");
  }
  self.focus();
}

//scott decker added August 6, 2003
//onload function add

if(window.global_loaded == null) {
   window.global_loaded = false;
}

var global_usurpFunctionCall;
var global_usurpFunctionCallArray;
var global_usurpFunctionCount = 0;

function global_usurpOnLoad(){
        if (global_usurpFunctionCall) {
                global_usurpFunctionCall();
        }

        if (global_usurpFunctionCallArray)
        {
                //loop through all onload function calls in this array
                for(var i = 0; i < global_usurpFunctionCount; i++)
                        global_usurpFunctionCallArray[i]();

        }
}

function global_addOnLoadFunction(functionToAdd){

        if (!global_usurpFunctionCallArray)
        {
                global_usurpFunctionCallArray = new Array(1);
        }

        global_usurpFunctionCallArray[global_usurpFunctionCount] = functionToAdd;
        global_usurpFunctionCount++;
}

if (window.global_loaded == false) {
        window.global_loaded = true;

        global_usurpFunctionCall = window.onload;
        window.onload = global_usurpOnLoad;
        //end onload function add
}

function dlPopUnder(page, styleid, zip, tid) {
    DLhandler(1,styleid, zip, tid);
    window.location = page;
}

// from trackingscript.js


function setTID(value){
//document.cookie="tid=" + escape(value);

var today = new Date();
//var expdate = new Date(today.getTime() +  5000); //expired in 5 seconds
var expdate = new Date(today.getTime() +  30000); //expired in 30 seconds

if (value.indexOf('edmunds') == 0){
document.cookie="tid=" + escape(value) + "; expires=" + expdate.toGMTString() + ";path=/;domain=.edmunds.com";
}else{
  document.cookie="tid=" + escape(value) + "; expires=" + expdate.toGMTString();
}
 }

function getTID(){

var url = window.location.href;
var TIDfromQueryString =  getParameter(url, 'tid');

if(TIDfromQueryString == "null"){

var dc = document.cookie;
var prefix = "tid=";
var begin = dc.indexOf("; " + prefix);

    if (begin == -1)
    {
        begin = dc.indexOf(prefix);
        if (begin != 0) return "";
    }
    else
    {
        begin += 2;
    }
var end = document.cookie.indexOf(";", begin);
    if (end == -1)
    {
        end = dc.length;
    }

    var TIDfromCookie = unescape(dc.substring(begin + prefix.length, end));

    // Delete cookie immediately after retrieving for purpose of avoiding receiving incorrect
    // TID value in case of calling previous page from browserˇ¦s address field.
    //document.cookie= "tid=" + escape("");
    //DeleteCookie("tid", TIDfromCookie);

    return TIDfromCookie;

    }else{
      return TIDfromQueryString;
    }
 }



function getParameter ( queryString, parameterName ) {

var parameterName = parameterName + "=";
if ( queryString.length > 0 ) {

begin = queryString.indexOf ( parameterName );

if ( begin != -1 ) {

begin += parameterName.length;

end = queryString.indexOf ( "&" , begin );
if ( end == -1 ) {
end = queryString.length
}

var cookieValue = queryString.substring ( begin, end );
//document.cookie= "tid=" + escape(cookieValue);
return unescape (cookieValue);
}

return "null";
}
}

function DeleteCookie (name, value) {
var exp = new Date();
exp.setTime (exp.getTime() - 1);

if(name != null){
document.cookie = name + "=" + value + "; expires=" + exp.toGMTString();
 }
}


function popupPhoto(pageId, pictureId,make,model,synpartner,pageCode,usein,showLead) {

                var useuseflag = '';
                var adareaname = '';
                if (usein == 'e' && pageCode == 'roadtests') {
                        usein = 'n';
                        pageCode = '';
                        adareaname = 'roadmainindex';
                        useuseflag= 'false';
                }

                if (!showLead) {
                    showLead = false;
                }

                window.open('/apps/vdpcontainers/do/PhotoFlipper?pictureId=' + pictureId + '&pageId=' + pageId +
                '&pageCode=' + pageCode +
                '&make=' + make +
                '&synpartner=' + synpartner +
                '&model=' + model +
                '&usein=' + usein +
                '&useuseflag=' + useuseflag +
                '&adareaname=' + adareaname +
                '&showLead=' + showLead,
                '', 'fullscreen=no,toolbar=no,status=yes,menubar=no,scrollbars=no,resizable=no,directories=no,location=no,width=705,height=680');

}

function popupPhotoInsideline(pageId, pictureId,make,model,synpartner,pageCode,usein, showLead) {

                var useuseflag = '';
                var adareaname = '';
                if (usein == 'e' && pageCode == 'roadtests') {
                        usein = 'n';
                        pageCode = '';
                        adareaname = 'roadmainindex';
                        useuseflag= 'false';
                }

                if (!showLead) {
                    showLead = false;
                }

                window.open('/insideline/do/PhotoFlipper?pictureId=' + pictureId + '&pageId=' + pageId +
                '&pageCode=' + pageCode +
                '&make=' + make +
                '&synpartner=' + synpartner +
                '&model=' + model +
                '&usein=' + usein +
                '&useuseflag=' + useuseflag +
                '&adareaname=' + adareaname +
                '&showLead=' + showLead,
                '', 'fullscreen=no,toolbar=no,status=yes,menubar=no,scrollbars=no,resizable=no,directories=no,location=no,width=705,height=680');

}


//from /scripts/pagescript.jsp

function popPffCalc(pffsrcid)
{
url = "http://applications.edmunds.com/servlets/PartnerLogServlet?url=http%3A%2F%2Fwww.peoplefirst.com%2Fdefault.cfm%3FPFFSRCID%3DSRED02CALCPOPTL*TL0003***&partner=PPLFIRST&contract=People+First+Referrals&source=PF.PRICE.CALC.T";
browserVer      = parseInt(navigator.appVersion);
if ( (browserVer >= 3) && (navigator.appName.indexOf("WebTV") == -1) )
{
        this.name       = "main";
        calcWindow      = window.open(url,'calcWin','toolbar=0,location=0,directories=0,status=1,menubar=0,scrollbars=1,resizable=1,copyhistory=0,height=440,width=450');
        if (window.focus && (navigator.appVersion.indexOf("MSIE 4") < 0 ))
                setTimeout("calcWindow.focus()",10);
        return(false);
}
else
{
        return(true);
}

}

function popup(popupID) {
url = "http://www.edmunds.com/partners/peoplefirst/financingpopup.html?id=" + popupID;
newWindow = window.open(url,'popup','width=550,height=480,scrollbars=yes,menubar=yes,resizable')
}

function checkEnter(event, formName)
{
        var code = 0;
        var formObject = eval("document." + formName);

        //alert("checkEnter:" + event.keyCode);

        if (event.which)
                code = event.which;
        else
                code = event.keyCode;
        if (code==13)
        {
                //alert("true");
                return true;
        }
        else
        {
                //alert("false");
                return false;
        }
}

var ADD_ZIPCODE = true;
var POPUP_WIDTH = "660";
var POPUP_HEIGHT = "480";

function popupCookiedWindow(cookieName, cookieValue, url, title, options, giveFocus){
        if (getCookieVal(cookieName) == cookieValue)
        {
                //don't do anything
                //they have all ready had a popup
        }
        else
        {
                //set the cookie
                //setCookieVal(cookieName,cookieValue,null,"/",".edmunds.com");
                if (giveFocus == null)
                        giveFocus = false;
                popupCenteredWindow(url,title,options,giveFocus);
        }

}

function popupCenteredWindow(url,title,options, giveFocus){
  var winLeft = (screen.width) / 2;
  var winUp = (screen.height) / 2;


  var winOpened = window.open(url,title,"left=" + winLeft + ",top=" + winUp + "," + options);
  if (giveFocus)
        winOpened.focus();
  else
        self.focus();
}

function powershopperPopupWindow(url,title,options){
  //popDLUnder(1);
  //if (dlPopupWindow)
  //{
  //            dlPopupWindow.focus();
  //            dlPopupWindow = null;
  //}
  popupWindow(url,title,options);
}

function powershopperPopupZipWindow(url,title,options, formObject){
  //popDLUnder(1);
  //if (dlPopupWindow)
  //    dlPopupWindow.focus();
  popupZipWindow(url,title,options, formObject);
}

function popupZipWindow(url,title,options, formObject){
 //get the form object's zip value

 var formObj = eval("document." + formObject);


 if (formObj)
 {
    if (formObj.zip)
   {


     if (!(url.lastIndexOf("&") == url.length))
     {
        popupWindow(url + "&zip="+formObj.zip.value,title,options);
    }
    else
    {
      popupWindow(url + "zip="+formObj.zip.value,title,options);
    }
  }
  else
  if (formObj.zipcode)
   {

     if (!(url.lastIndexOf("&") == url.length))
     {
        popupWindow(url + "&zipcode="+formObj.zipcode.value,title,options);
    }
    else
    {
      popupWindow(url + "zipcode="+formObj.zipcode.value,title,options);
    }
  }
 }
}

//for used
var buySell = 0;
function checkBuySell() {
if (buySell == 0)
  {
        //alert("Please click on the buy or sell button");
        return true;
  } else {
        return true;
  }
  return false;
}

/* Checks cookie now before setting upsAction */
function clickBuySell(val) {
  buySell = 1;

  //alert("buy and sell upsaction:" + document.UPS.upsAction);
// if a valid zip code cookie exists then post the upsaction field
  if (hasCookie) document.UPS.upsAction.value = val;
  document.UPS.submit();
}
/* Checks cookie now before setting upsAction */
function clickBuySell2(val) {
        buySell2 = 1;
        // if a valid zip code cookie exists then post the upsaction field
        if (hasCookie) document.UPS2.upsAction.value = val;
        document.UPS2.submit();
}

/* Checks cookie now before setting upsAction */
function clickBuySell3(val) {
  buySell3 = 1;
// if a valid zip code cookie exists then post the upsaction field
  if (hasCookie) document.UPS3.upsAction.value = val;
  document.UPS3.submit();
}
/* Checks cookie now before setting upsAction */
function clickBuySell4(val) {
        buySell4 = 1;
        // if a valid zip code cookie exists then post the upsaction field
        if (hasCookie) document.UPS4.upsAction.value = val;
        document.UPS4.submit();
}

function clickBuySellGeneric(val, f) {
buySell = 1;
  var dform=f;
  //alert("form:" + dform);
  //alert("form ups:" + dform.upsAction.value);

// if a valid zip code cookie exists then post the upsaction field
  if (hasCookie) dform.upsAction.value = val;
  //alert("got here");
  dform.submit();
}

function popupVideo(popupUrl, width, height) {
    var features = 'fullscreen=no,toolbar=no,status=yes,menubar=no,scrollbars=no,resizable=yes,directories=no,location=no,width='
        + width + ',height=' + height;
    window.open(popupUrl, '', features);
    return true;
}

function submitForm(formName, modelSelectName, zipName) {
  var form = eval("document." + formName);
  var verify = true;
  var errorMessage;
  var selectObject = eval("document." + formName + "." + modelSelectName);
  var zipObject = eval("document." + formName + "." + zipName);
  //alert("selected " + modelSelectName + " equals " + selectObject.options[selectObject.selectedIndex].value);
  if (selectObject.options[selectObject.selectedIndex].value == "") {
    //do nothing, just the select a model index
    errorMessage = "You need to select a make and a model.";
    verify = false;
  } else if (zipObject.value.length != 5 || isNaN(zipObject.value)) {
    verify = false;
    errorMessage = "Please enter a valid 5-digit ZIP Code.  (This application only supports ZIP Codes located in one of the 50 states or the District of Columbia.)";
  }

  if (verify) {
      info = mm_getAllFromModelIndex(selectObject.options[selectObject.selectedIndex].value);
      year = mm_getYearFromIndex(info[2]);
      form.model.value = mm_getNiceName(info[0]);
      form.make.value = mm_getNiceName(mm_getMakeFromIndex(info[1]));
      form.submit();
  } else {
      alert(errorMessage);
  }
}

/*Flash functions to fix firefox issue */
function setFlashWidth(divid, newW){
    document.getElementById(divid).style.width = newW+"px";
}
function setFlashHeight(divid, newH){
    document.getElementById(divid).style.height = newH+"px";
}
function setFlashSize(divid, newW, newH){
    if (document.getElementById(divid)){
        setFlashWidth(divid, newW);
        setFlashHeight(divid, newH);
    }
}

var globalRandNum = Math.floor(Math.random() * 999999999);
function resetGlobalRandNum(){
    globalRandNum = Math.floor(Math.random() * 999999999);
}

/*
 *Counts the remaining allowed characters in a textarea and updates a span with the value.
 *Contents of the textarea are also truncated to fall within the max allowed characters.
 */
function updateCharacterCount(textAreaId, counterSpanId, maxChars, errorMessageSpanId, errorMessage) {
    var theTextArea = document.getElementById(textAreaId);
    var theCounterSpan = document.getElementById(counterSpanId);
    var errorMessageSpan = null;
    if(errorMessageSpanId != null) {
        errorMessageSpan = document.getElementById(errorMessageSpanId);
    }
    var remainingChars = maxChars - theTextArea.value.length;
    if(remainingChars < 0) {
        theCounterSpan.innerHTML="<font color='red'>0</font>"
        if(errorMessageSpan != null) {
            errorMessageSpan.innerHTML="<font color='red'>"+errorMessage+"</font>";
        }
        theTextArea.value = theTextArea.value.substring(0, maxChars);
    } else if(remainingChars ==  0) {
        theCounterSpan.innerHTML="<font color='red'>0</font>"
    } else {
        theCounterSpan.innerHTML=remainingChars;
        if(errorMessageSpan != null) {
            errorMessageSpan.innerHTML="";
        }
    }
}

HashMap = function() {
    this.map = {};
    this.length = 0;
};

HashMap.prototype = {
    constructor: HashMap,
    add: function (key, value) {
        if (typeof(key) != "undefined" && key != null) {
            if (typeof(this.map[key]) == "undefined") {
                this.length++;
            }
            this.map[key] = value;
        }
    },

    remove: function (key) {
        if (typeof(key) != "undefined" && key != null &&
            typeof(this.map[key]) != "undefined") {
            this.length--;
            delete this.map[key];
        }
    },

    size: function() {
        return this.length;
    },

    contains: function(key) {
        return typeof this.map[key] != "undefined";
    },

    clear: function() {
        this.map = {};
        this.length = 0;
    },

    each: function(fn) {
        for (var key in this.map) {
            fn.call(window, key, this.map[key]);
        }
    },

    keys: function(){
      var results = [];
      for (var key in this.map) {
            results.push(key);
      }
      return results;
    },

    toQueryString: function(){
      var parts = [];
      this.each(function(key, value) {
          if (!key) {
              return;
          } else {
            var val = (typeof value != undefined && value != null)? encodeURIComponent(value):"";
            parts.push(encodeURIComponent(key) + '=' + val);
        }
      });
      return parts.join('&');
    }
};

/* 
 * imported from DL pagescripts.js
*/
function doYearSubmit(){
    var psForm = document.dealerLocatorForm;
    if (psForm == null) psForm = document.powerShopperForm;
    isPs = (document.powerShopperForm != null);
    psForm.make.value = 'None';
    psForm.model.value = 'None';
    psForm.trim.value = 'None';
    if ( isPs == false )  psForm.action = '';
    psForm.submit();
}

function doMakeSubmit(){
    var psForm = document.dealerLocatorForm;
    if (psForm == null) psForm = document.powerShopperForm;
    isPs = (document.powerShopperForm != null);
    psForm.model.value = 'None';
    psForm.trim.value = 'None';
    if ( isPs == false )  psForm.action = '';
    psForm.submit();
}

function doModelSubmit(){
    var psForm = document.dealerLocatorForm;
    if (psForm == null) psForm = document.powerShopperForm;
    isPs = (document.powerShopperForm != null);
    psForm.trim.value = 'None';
    if ( isPs == false )  psForm.action = '';
    psForm.submit();
}

function doTrimSubmit(){
}

function doDLSubmit(){
    var psForm = document.dealerLocatorForm;
    if (psForm == null) psForm = document.powerShopperForm;

    if ( psForm.stepPage != null) {
        psForm.stepPage.value = "step1";
    }

    if (psForm.year.value == '' || psForm.year.value == 'None' || psForm.make.value == '' || psForm.make.value == "None" || psForm.model.value == '' || psForm.model.value == 'None'){
        return false;
    }

    if ( psForm.zip.value.length != 5 ) {
        alert("The zip code must contain 5 digits.");
        return false;
    } else {
        if ( psForm.setzip != null ) psForm.setzip.value = psForm.zip.value;
    }
    return true;
}

function doPreferredDLPopup(url,targetName) {
    if ( url == null ) alert("A url is a required parameter.");

    if ( targetName == null ) targetName = "dlsubmit";
    var win = null;
    win = window.open(url,targetName,
                'width=660,height=480,location=no,toolbar=yes,menubar=yes,scrollbars=yes,resizable=yes');
    if ( win != null ) win.focus();
}

function dlistingGenericPopup(partnerURL) {
    if ( partnerURL != null ) {
        if ( new RegExp("^/apps").test(partnerURL) == true ) {
            window.open(partnerURL ,"powershopper", 'width=770,height=480,location=no,toolbar=yes,menubar=yes,scrollbars=yes,resizable=yes');
        }
        else {
            window.open("/apps/dl/" + partnerURL ,"powershopper", 'width=770,height=480,location=no,toolbar=yes,menubar=yes,scrollbars=yes,resizable=yes');
        }
    } else {
        alert("partnerURL is null.");
    }
}


function mapitImpression(franchiseId,url,args,synpartner,idx,tid) {
    if ( idx == null ) idx = "";
    var imageName = "hiddenImage" + idx;
    var image = document.images[imageName];
    if ( image == null ) {
        alert("Cannot find image with name='" + imageName + "'");
        return;
    }
    var origImageSrc = image.src;
    var imageUrl = impressionImage(franchiseId, "mapit", synpartner, tid);
    image.src = imageUrl;

    if (tid != null) {
        setTID(tid);
    }

    var win = window.open(url,'mapit',args);
    image.src = origImageSrc;
    win.focus();
}

function doPSSubmit(partnerName,partnerURL) {
    var f = document.powerShopperForm;
    if ( f == null ) f = document.dealerLocatorForm;
    if ( f == null ) f = document.PSVDP;
    if ( partnerURL != null ) {
        var params = "&stepPage=ps";
        if (f.bannercode != null && f.bannercode.value != null) {
            setTID(f.bannercode.value);
        }

        window.open("/apps/dl/" + partnerURL + params,"powershopper",
                    'width=770,height=480,location=no,toolbar=yes,menubar=yes,scrollbars=yes,resizable=yes');
        return false;
    } else {
        alert("partnerURL is null.");
    }
}

function Tests() {
  this.tests = new Array();
  this.idx = 0;
  this.addTest = function addTest(name,code,msg) {
    var test = new Object();
    test.name = name;
    test.test = new Function("str","return (" + code + ")");
    test.msg = new Function("name","alert(\"" + msg + "\".replace('%name',name))");
    this.tests[this.tests.length] = test;
  }
  this.next = function() { return ( this.idx < this.tests.length ) ? this.tests[this.idx++] : null; }
}

function createTests(tests) {
  // first arg is the test, where str will be the string value of the first or last name
  // second arg is the message if the test fails, where %name will be replaced with "First Name" or "Last name"
  tests.addTest("repeat", "!(/(.)(\\1){2}/).test(str)","%name cannot contain the same 3 letters concurrently.");
  tests.addTest("min", "str.length > 1","%name must contain at least 2 characters.");
  tests.addTest("numeric", "!(/[0-9]/).test(str)","%name cannot contain numeric values (0 to 9).");
  tests.addTest("concurrent", "!(/[bcdfghjklmnpqrstvwxz]{7}/).test(str)","%name cannot contain 7 concurrent consonants.");
  tests.addTest("vowel","(/A|E|I|O|U|Y|a|e|i|o|u|y|(Ng)|(ng)|(NG)/).test(str)","%name must include a vowel.");
  tests.addTest("special","!(/\\*|\\^|<|>|\\\\|\"|\\.|;|:|[|]|!|@/).test(str)","%name cannot contains special characters (\\*\\^<>\\\\\\\"\\.\\;\\:[]!@).");
}

function checkRequired() {
  var isPs = (document.powerShopperForm != null);
  var psForm = document.powerShopperForm;

  if ( psForm == null ) psForm = document.dealerLocatorForm;

  var checkedDealerCount = 0;
  var hasDealer = false;
  var dealerCount = 0;
  for ( i = 0; i < psForm.elements.length; i++ ) {
    var e = psForm.elements[i];
    if ( e.name == 'emailblastdealers' &&
         e.type == 'checkbox' ) {
      hasDealer = true;
      dealerCount++;
      if ( e.checked == true )
        checkedDealerCount++;
    }
  }

  var checkStreetAddress = false;
  var synpartner = psForm.synpartner.value;

//  COMMENTED OUT DUE TO DCX
//  if (psForm.make.value == 'Dodge' || psForm.make.value == 'Chrysler' || psForm.make.value == 'Jeep' || psForm.make.value == 'Saab' || psForm.make.value == 'Audi' || psForm.make.value == 'Buick' || psForm.make.value == 'Cadillac' || psForm.make.value == 'Chevrolet' || psForm.make.value == 'GMC' || psForm.make.value == 'HUMMER' || psForm.make.value == 'Pontiac' || psForm.make.value == 'Saturn') {
  if (psForm.make.value == 'Saab' || psForm.make.value == 'Audi' || psForm.make.value == 'Buick' || psForm.make.value == 'Cadillac' || psForm.make.value == 'Chevrolet' || psForm.make.value == 'GMC' || psForm.make.value == 'HUMMER' || psForm.make.value == 'Pontiac' || psForm.make.value == 'Saturn') {
      checkStreetAddress = true;
  } 
  
  var iChars = "!@#$%^&*()+=-[]\\\';,./{}|\":<>?";
  if (checkStreetAddress == true) {
      if (psForm.make.value == 'Audi' ) {
          if (psForm.street1 && psForm.street1.value != '') {
               for (var i = 0; i < psForm.street1.value.length; i++) {
                    if (iChars.indexOf(psForm.street1.value.charAt(i)) != -1) {
                        alert ("Street Address cannot contains special characters (!@#$%^&*()+=-[]\\\';,./{}|\":<>?");
                        return false;
                    }
               }
          } 
          /*
          // commented out for audi 6 month trial of no address validation (8/11/09)
          else if (psForm.address && psForm.address.value == '') {
               for (var i = 0; i < psForm.address.value.length; i++) {
                    if (iChars.indexOf(psForm.address.value.charAt(i)) != -1) {
                        alert ("Street Address cannot contains special characters (!@#$%^&*()+=-[]\\\';,./{}|\":<>?");
                        return false;
                    }
               }
          }
          */
          // Can't return true from here as it causes problems with other validation checks.
      }
      else if ( (psForm.street1 && psForm.street1.value == '') || (psForm.address && psForm.address.value == '') ||
           (psForm.street1 && psForm.street1.value == '1 Not Available') || (psForm.address && psForm.address.value == '1 Not Available')) {

          if(psForm.street1) {
               psForm.street1.value = '';
          }
          if(psForm.address) {
               psForm.address.value = '';
          }

          alert("Please enter your street address.");
          return false;
      }
  }


  if ( hasDealer && checkedDealerCount < 1 ) {
    if ( dealerCount == 1 ) {
        alert("At least one dealer must be selected.");
    }
    else if ( dealerCount > 1 ) {
        alert("Select up to " + dealerCount + " dealers for free price quotes.");
    }
    window.clickedAgain = 0;
    return false;
  }

  var tests = new Tests();
  var name = new Array( psForm.firstName , psForm.lastName );

  // see createTests for tests to run
  createTests(tests);

  // run all tests created in create tests.
  for (var test = null; (test = tests.next() ) != null; ) {
    for ( var j = 0 ; j < 2; j++ ) {
      // trims value
      name[j].value = trimAll(name[j].value);
      if ( test.test(name[j].value) == false ) {
        // do the following if validation fails ...
        test.msg((j==0?"First Name":"Last Name"));
        window.clickedAgain = 0;
        name[j].focus();
        return false;
      }
    }
  }

  /*if (psForm.street1.value.length != 0)
  {
     if (!addressCheck(psForm.street1.value)) {
         window.clickedAgain = 0;
             return false;
     }
  }
  */

  //Saturn
  if ( psForm.partner != null )
  {
    if ( psForm.partner.value == 'SATURN' )
    {
     if ( (psForm.formZip.value.length == 0) || (psForm.formZip.value.length < 5))
         {
            alert("please enter your zip code.");
            window.clickedAgain = 0;
            return false;
    }//end if

    if (psForm.city.value.length == 0)
        {
            alert("please enter your city.");
            window.clickedAgain = 0;
            return false;
    }//end if

    }
  }

  //imotors partners
  if ( psForm.partner != null )
  {
    if ( psForm.partner.value == 'IMOT' )
    {
     if ( (psForm.formZip.value.length == 0) || (psForm.formZip.value.length < 5))
         {
            alert("please enter your zip code.");
            window.clickedAgain = 0;
            return false;
    }//end if

    if (psForm.street1.value.length == 0)
        {
            alert("please enter your address.");
            window.clickedAgain = 0;
            return false;
    }//end if
    }
  }

  // forddirect partners
  if ( psForm.partner != null ) {
    if ( psForm.partner.value == 'FORDDIRECT'
         || psForm.partner.value == 'LINCOLN'
         || psForm.partner.value == 'MERCURY'
         || psForm.partner.value == 'LANDROVER'
         || psForm.partner.value == 'JAGUAR' ) {
      checkState(psForm);
    }
  }

  // audi
  if ( psForm.partner != null ) {
    if ( psForm.partner.value == 'AUDI' ) {
      if ( psForm.interiorColor.value.length == 0 ) {
        alert("Please enter interior color.");
        window.clickedAgain = 0;
        return false;
      }
      if ( psForm.exteriorColor.value.length == 0 ) {
        alert("Please enter exterior color.");
        window.clickedAgain = 0;
        return false;
      }
      if ( psForm.timeLine.value.length == 0 ) {
        alert("Please enter purchase status.");
        window.clickedAgain = 0;
        return false;
      }

     if ( (psForm.formZip.value.length == 0) || (psForm.formZip.value.length < 5)){
            alert("please enter your zip code.");
            window.clickedAgain = 0;
            return false;
        }//end if
     /*
          // commented out for audi 6 month trial of no address validation (8/11/09)

     if (psForm.street1.value.length == 0){
            alert("please enter your address.");
            window.clickedAgain = 0;
            return false;
        }//end if
      */        
    }
  }

  // abt, autoweb, carsmart
  if ( psForm.partner != null ) {
    if ( psForm.partner.value == 'ABT'
         || psForm.partner.value == 'AUTOWEB'
         || psForm.partner.value == 'CARSMART' ) {
      if ( psForm.city.value.length == 0 ) {
        alert("Please enter your city.");
        window.clickedAgain = 0;
        return false;
      }
      checkState(psForm);

      if (psForm.street1.value.length == 0){
            alert("please enter your address.");
            window.clickedAgain = 0;
            return false;
        }//end if

      if ( (psForm.formZip.value.length == 0) || (psForm.formZip.value.length < 5)){
            alert("please enter your zip code.");
            window.clickedAgain = 0;
            return false;
        }//end if

    }
  }

  // autonation
  if ( psForm.partner != null ) {
    if ( psForm.partner.value == 'AUTONATION' ) {
      if ( psForm.city.value.length == 0 ) {
        alert("Please enter your city.");
        window.clickedAgain = 0;
        return false;
      }
      checkState(psForm);
      if ( psForm.interiorColor.value.length == 0 ) {
        alert("Please enter interior color.");
        window.clickedAgain = 0;
        return false;
      }
      if ( psForm.exteriorColor.value.length == 0 ) {
        alert("Please enter exterior color.");
        window.clickedAgain = 0;
        return false;
      }
      if ( psForm.timeLine.value.length == 0 ) {
        alert("Please enter purchase status.");
        window.clickedAgain = 0;
        return false;
      }
      if ( psForm.bestContactTime.value.length == 0 ) {
        alert("Please enter your best contact time.");
        window.clickedAgain = 0;
        return false;
      }
    }
  }

  // honda/acura
  if ( psForm.partner != null ) {
    if ( psForm.partner.value == 'HONDA'
         || psForm.partner.value == 'ACURA' ) {
      if ( psForm.city.value.length == 0 ) {
        alert("Please enter your city.");
        window.clickedAgain = 0;
        return false;
      }
      checkState(psForm);
      if ( psForm.country.value.length == 0 ) {
        alert("Please enter your country.");
        window.clickedAgain = 0;
        return false;
      }
     if (psForm.street1.value.length == 0){
            alert("please enter your address.");
            window.clickedAgain = 0;
            return false;
        }//end if
    }
  }

  // dealix
  if ( psForm.partner != null ) {
    if ( (psForm.partner.value == 'DEALIX')|| (psForm.partner.value == 'ABUSA') ) {
      if ( psForm.street1.value.length == 0) {
        alert("Please enter your address.");
        window.clickedAgain = 0;
        return false;
      }

      if ( psForm.city.value.length == 0 ) {
        alert("Please enter your city.");
        window.clickedAgain = 0;
        return false;
      }
      checkState(psForm);
      if ( (psForm.formZip.value.length == 0) || (psForm.formZip.value.length < 5)){
            alert("Please enter your zip code.");
            window.clickedAgain = 0;
            return false;
        }
    }
  }

  //stoneage
  if (psForm.partner != null) {
    if (psForm.partner.value == 'STONEAGE') {
      if (psForm.street1.value.length == 0) {
        alert("Please enter your address.");
        window.clickedAgain = 0;
        return false;
      }

      if (psForm.city.value.length == 0) {
        alert("Please enter your city.");
        window.clickedAgain = 0;
        return false;
      }
      if (psForm.formZip.value.length == 0) {
        alert("Please enter your zip code.");
        window.clickedAgain = 0;
        return false;
      }
      if (psForm.email.value.length == 0) {
    alert("Please enter your email address.");
    window.clickedAgain = 0;
      return false;
      }

   }
 }

  // MITSUBPS
  if ( psForm.partner != null ) {
    if ( psForm.partner.value == 'MITSUBPS' ) {
      if ( psForm.street1.value.length == 0) {
        alert("Please enter your address.");
        window.clickedAgain = 0;
        return false;
      }

      if ( psForm.city.value.length == 0 ) {
        alert("Please enter your city.");
        window.clickedAgain = 0;
        return false;
      }
      checkState(psForm);
      if ( (psForm.formZip.value.length == 0) || (psForm.formZip.value.length < 5)){
            alert("Please enter your zip code.");
            window.clickedAgain = 0;
            return false;
      }
      if ( psForm.timeLine.value.length == 0 ) {
        alert("Please enter purchase status.");
        window.clickedAgain = 0;
        return false;
      }
      if ( psForm.add_equip_text.value.length > 1024 ) {
        alert("Please limit comments to under 1024 characters.");
        window.clickedAgain = 0;
        return false;
      }
    }
  }

  if ( !email_valid() ) {
    //alert("Please enter a valid email address.");
    window.clickedAgain = 0;
    return false;
  }

  if((psForm.areaCode.value.length == 0) || (psForm.phonePrefix.value.length == 0) || (psForm.phoneSuffix.value.length == 0)) {
    alert("Please enter your phone number.");
    window.clickedAgain = 0;
    return false;
  }

  if((psForm.areaCode.value.length != 0) || (psForm.phonePrefix.value.length != 0) || (psForm.phoneSuffix.value.length != 0)) {
    if (!validatePhone()) {
      alert("Phone Number was considered INVALID, please re-enter a valid 10 digit telephone number.");
      window.clickedAgain = 0;
      return false;
    }
  }

  // blacklist validation
  var emailPat=/^(.+)@(.+)$/;
  var matchArray=psForm.email.value.match(emailPat);
  var domain=matchArray[2];

  var values = new Array();
  values[0] = 'FIRST_NAME=' + escape(psForm.firstName.value);
  values[1] = 'LAST_NAME=' + escape(psForm.lastName.value);
  values[2] = 'EMAIL=' + escape(psForm.email.value);
  values[3] = 'EMAIL_DOMAIN=' + escape(domain.substring(domain.lastIndexOf(".") + 1));

  if (!validateBlacklist(values)) {
    window.clickedAgain = 0;
    return false;
  }

  if (window.clickedAgain == 1) {
    alert("Your request is currently being processed");
    return false;
  }

  window.clickedAgain = 1;
  return true;
}

function email_valid() {
  var psForm = document.dealerLocatorForm;
  if (psForm == null) psForm = document.powerShopperForm;
  var field = psForm.email;
  var str = field.value;
  var retval = isEmailFormatValid(str);
  if ( retval == false ) field.focus();
  return retval;
}


function DLChangeZip(target) {
  if ( target == null || target.length == 0 ) {
    target = document.location;
  }
  var newZip = document.dealerLocatorForm.zip.value;
  var hasbc = ( document.dealerLocatorForm.bannercode != null &&
                document.dealerLocatorForm.bannercode.value != null &&
                document.dealerLocatorForm.bannercode.value.length != 0 );
  var bannercode = document.dealerLocatorForm.bannercode.value;
  var dest = target + '?setzip=' + newZip;
  if ( hasbc == true )
    dest += '&bannercode=' + bannercode;
  document.location=dest;
}

// phone validaion functions
function validatePhone() {
  var psForm = document.dealerLocatorForm;
  if (psForm == null) psForm = document.powerShopperForm;
  var acode = psForm.areaCode;
  var pfix = psForm.phonePrefix;
  var sfix = psForm.phoneSuffix;

  var acode_deny = new Array
    ("222",
     "333",
     "411",
     "444",
     "456",
     "500",
     "555",
     "666",
     "777",
     "911",
     "900",
     "999");
  var acode_accept = new Array
    ("800",
     "876",
     "877",
     "888");

  var pfix_deny = new Array
    ("411",
     "555",
     "611",
     "911");

  var pfix_accept = new Array();
  var sfix_deny = new Array();
  var sfix_accept = new Array();

  var phone_concat_deny = new Array
    ("0000000000",
     "1111111111",
     "2222222222",
     "3333333333",
     "4444444444",
     "5555555555",
     "6666666666",
     "7777777777",
     "8888888888",
     "9999999999");

  var numbersOnly = /^[0-9]+$/;
  if ( numbersOnly.test(acode.value) == false ) return false;
  if ( numbersOnly.test(pfix.value) == false ) return false;
  if ( numbersOnly.test(sfix.value) == false ) return false;

  // validate area code
  if(!validate_phone_field(acode, 3, acode_deny, acode_accept)) {
    return false;
  }

  // validate prefix
  if(!validate_phone_field(pfix, 3, pfix_deny, pfix_accept)) {
    return false;
  }

  // validate suffix
  if(!validate_phone_field(sfix, 4, sfix_deny, sfix_accept)) {
    return false;
  }

  var phone_concat = acode.value + pfix.value + sfix.value;
  if (value_is_in_array(phone_concat, phone_concat_deny)) {
    return false;
  }

  // last 7 digits cannot be all of the same value;
  if ( phone_concat.length != 10 ) {
     return false;
  } else {
     // if last 7 digits all the same value
     if ( (/^(.)(\1)+$/).test(phone_concat.substring(3)) ) {
        return false;
     }
  }

  // area code prefix cannot start with 0 or 1
  if ( (/^[01]/).test(pfix) || (/^[01]/).test(acode)  ) {
    return false;
  }

  return true;
}

function validate_phone_field(field, field_len, arr_deny, arr_accept) {
  var val = field.value;
  if (val.length != field_len) {
    return false;
  } else if(value_is_in_array(val, arr_deny)) {
    return false;
  } else if(value_is_in_array(val , arr_accept)) {
    return true;
  } else if(field_len == 3 && starts_with_0_or_1(val)) {
    return false;
  }
  return true;
}

function starts_with_0_or_1(value) {
  var char1 = new String(value).charAt(0);
  return (char1 == 0 || char1 == 1);
}

function value_is_in_array(val, array){
  for (i = 0; i < array.length; i++) {
    if (array[i] == val) {
      return true;
    }
  }
  return false;
}
// end of phone validation

function addressCheck (addressStr) {
  var addressPat=new RegExp("[*^<>\\?:\\[\\]!@]+");
  if (addressStr.match(addressPat)) {
    alert("Street address cannot contain special characters (*^<>\\?:[]!@).");
    return false;
  }

  return true;
}

function isEmailFormatValid(emailText) {
  return emailCheck(emailText);
}

function emailCheck (emailStr) {
  var specialChars="\\(\\)<>@,;!:\\\\\\\"\\.\\[\\]";
  var validChars="\[^\\s" + specialChars + "\]";
  var quotedUser="(\"[^\"]*\")";
  var atom=validChars + '+';
  var word="(" + atom + "|" + quotedUser + ")";
  var emailPat=new RegExp("^(.+)@(.+)$");

  if (!emailPat.test(emailStr)) {
    alert("Email address cannot be blank and must have an @ symbol.");
    return false;
  }

  var matchPat=new RegExp("^([^@]+)@([^@]+)$");
  if(!matchPat.test(emailStr)) {
      alert("Email address cannot contain more than one @ symbol.");
      return false;
  }

  var splitPat=new RegExp("@");
  var matchArray=emailStr.split(splitPat);
  if(matchArray == null && matchArray.length < 2) {
      alert("Email address cannot be blank and must have an @ symbol.");
      return false;
  }

  var user=matchArray[0];
  var domain=matchArray[1];    

  var displaySpecialChars = "()<>\";:[]!";
  var userPat=new RegExp("^" + word + "(\\." + word + ")*$");
  if (!userPat.test(user)) {
    alert("Email address handle cannot contain special characters (e.g. " + displaySpecialChars + ")");
    return false;
  }

  var domainPat=new RegExp("^" + atom + "(\\." + atom +")*$");
  if (!domainPat.test(domain)) {
    alert("Email address domain cannot contain special characters (e.g. " + displaySpecialChars + ")");
    return false;
  }

  var domainDotPat = new RegExp("[.]");
  if (!domainDotPat.test(domain)) {
    alert("Email address domain must have a period (.).");
    return false;
  }

  return true;
}

function checkState(f) {
  if ( f != null && f.state != null ) {
    var st = f.state[f.state.selectedIndex].value;
    if ( (st == null || st.length == 0) ) {
      alert("Please enter your state.");
      window.clickedAgain = 0;
      return false;
    }
  }
}

// Validation AJAX service starts here

var sUrl = "/apps/dl/ValidationServlet";
//number of errors is set to none to begin with
var http = getHTTPObject();

function validateBlacklist(variables) {

    if (http)
    {
            //get value inside of input field
        var parameters = "?";

        for (i = 0; i < variables.length; i++) {
            parameters = parameters + variables[i] + "&";
        }

            var url = sUrl + parameters;

            //sends the rules and value to the asp page to be validated
            http.open("GET", url, false);

            // handle what to do with the feedback
            http.send(null);

            if (http.status == 200)
            {
            if (http.responseText == '<valid />')
            {
                return true;
            } else {

                var error_string = http.responseText;
                var start_tag = "<invalid>";
                var end_tag = "</invalid>";

                error_string = error_string.replace(start_tag, "");
                error_string = error_string.replace(end_tag, "");

                var errors = error_string.split(",");

                var error_message = "";
                for (i=0; i <errors.length; i++) {

                    var error_arguments = errors[i].split("=");

                    var error_type_argument = error_arguments[0];
                    var error_value_argument = error_arguments[1];

                    if (error_type_argument == 'FIRST_NAME') {
                        error_message = error_message + "The first name cannot be '" + error_value_argument + "'.\n";
                    }
                    if (error_type_argument == 'LAST_NAME') {
                        error_message = error_message + "The last name cannot be '" + error_value_argument + "'.\n";
                    }
                    if (error_type_argument == 'EMAIL') {
                        error_message = error_message + "Email address cannot be '" + error_value_argument + "'.\n";
                    }
                    if (error_type_argument == 'EMAIL_DOMAIN') {
                        error_message = error_message + "Email address top level domain cannot be '" + error_value_argument + "'.\n";
                    }
                }

                if (error_message == "") {
                    error_message = "One of the form values is invalid.";
                }

                alert(error_message);
                return false;
            }
            }

            return false;
    }

    return true;
}

function getHTTPObject() {
        // IE support
        if (window.ActiveXObject && !window.XMLHttpRequest)
        {
            var msxmls = new Array(
              'Msxml2.XMLHTTP.5.0',
              'Msxml2.XMLHTTP.4.0',
              'Msxml2.XMLHTTP.3.0',
              'Msxml2.XMLHTTP',
              'Microsoft.XMLHTTP');
            for (var i = 0; i < msxmls.length; i++)
            {
              try
                {
                return new ActiveXObject(msxmls[i]);
                }
                catch (e)
                {
                }
            }
            return null;
        }
        // Gecko support
        // Opera support
        if (window.opera && !window.XMLHttpRequest) {
          window.XMLHttpRequest = function() {
            this.readyState = 0; // 0=uninitialized,1=loading,2=loaded,3=interactive,4=complete
            this.status = 0; // HTTP status codes
            this.statusText = '';
            this._headers = [];
            this._aborted = false;
            this._async = true;
            this._defaultCharset = 'ISO-8859-1';
            this._getCharset = function() {
              var charset = _defaultCharset;
              var contentType = this.getResponseHeader('Content-type').toUpperCase();
              val = contentType.indexOf('CHARSET=');
              if (val != -1) {
                charset = contentType.substring(val);
              }
              val = charset.indexOf(';');
              if (val != -1) {
                charset = charset.substring(0, val);
              }
              val = charset.indexOf(',');
              if (val != -1) {
                charset = charset.substring(0, val);
              }
              return charset;
            };
            this.abort = function() {
              this._aborted = true;
            };
            this.getAllResponseHeaders = function() {
              return this.getAllResponseHeader('*');
            };
            this.getAllResponseHeader = function(header) {
              var ret = '';
              for (var i = 0; i < this._headers.length; i++) {
                if (header == '*' || this._headers[i].h == header) {
                  ret += this._headers[i].h + ': ' + this._headers[i].v + '\n';
                }
              }
              return ret;
            };
            this.getResponseHeader = function(header) {
              var ret = getAllResponseHeader(header);
              var i = ret.indexOf('\n');
              if (i != -1) {
                ret = ret.substring(0, i);
              }
              return ret;
            };
            this.setRequestHeader = function(header, value) {
              this._headers[this._headers.length] = {h:header, v:value};
            };
            this.open = function(method, url, async, user, password) {
              this.method = method;
              this.url = url;
              this._async = true;
              this._aborted = false;
              this._headers = [];
              if (arguments.length >= 3) {
                this._async = async;
              }
              if (arguments.length > 3) {
                opera.postError('XMLHttpRequest.open() - user/password not supported');
              }
              this.readyState = 1;
              if (this.onreadystatechange) {
                this.onreadystatechange();
              }
            };
            this.send = function(data) {
              if (!navigator.javaEnabled()) {
                alert("XMLHttpRequest.send() - Java must be installed and enabled.");
                return;
              }
              if (this._async) {
                setTimeout(this._sendasync, 0, this, data);
                // this is not really asynchronous and won't execute until the current
                // execution context ends
              } else {
                this._sendsync(data);
              }
            }
            this._sendasync = function(req, data) {
              if (!req._aborted) {
                req._sendsync(data);
              }
            };
            this._sendsync = function(data) {
              this.readyState = 2;
              if (this.onreadystatechange) {
                this.onreadystatechange();
              }
              // open connection
              var url = new java.net.URL(new java.net.URL(window.location.href), this.url);
              var conn = url.openConnection();
              for (var i = 0; i < this._headers.length; i++) {
                conn.setRequestProperty(this._headers[i].h, this._headers[i].v);
              }
              this._headers = [];
              if (this.method == 'POST') {
                // POST data
                conn.setDoOutput(true);
                var wr = new java.io.OutputStreamWriter(conn.getOutputStream(), this._getCharset());
                wr.write(data);
                wr.flush();
                wr.close();
              }
              // read response headers
              // NOTE: the getHeaderField() methods always return nulls for me :(
              var gotContentEncoding = false;
              var gotContentLength = false;
              var gotContentType = false;
              var gotDate = false;
              var gotExpiration = false;
              var gotLastModified = false;
              for (var i = 0; ; i++) {
                var hdrName = conn.getHeaderFieldKey(i);
                var hdrValue = conn.getHeaderField(i);
                if (hdrName == null && hdrValue == null) {
                  break;
                }
                if (hdrName != null) {
                  this._headers[this._headers.length] = {h:hdrName, v:hdrValue};
                  switch (hdrName.toLowerCase()) {
                    case 'content-encoding': gotContentEncoding = true; break;
                    case 'content-length'  : gotContentLength   = true; break;
                    case 'content-type'    : gotContentType     = true; break;
                    case 'date'            : gotDate            = true; break;
                    case 'expires'         : gotExpiration      = true; break;
                    case 'last-modified'   : gotLastModified    = true; break;
                  }
                }
              }
              // try to fill in any missing header information
              var val;
              val = conn.getContentEncoding();
              if (val != null && !gotContentEncoding) this._headers[this._headers.length] = {h:'Content-encoding', v:val};
              val = conn.getContentLength();
              if (val != -1 && !gotContentLength) this._headers[this._headers.length] = {h:'Content-length', v:val};
              val = conn.getContentType();
              if (val != null && !gotContentType) this._headers[this._headers.length] = {h:'Content-type', v:val};
              val = conn.getDate();
              if (val != 0 && !gotDate) this._headers[this._headers.length] = {h:'Date', v:(new Date(val)).toUTCString()};
              val = conn.getExpiration();
              if (val != 0 && !gotExpiration) this._headers[this._headers.length] = {h:'Expires', v:(new Date(val)).toUTCString()};
              val = conn.getLastModified();
              if (val != 0 && !gotLastModified) this._headers[this._headers.length] = {h:'Last-modified', v:(new Date(val)).toUTCString()};
              // read response data
              var reqdata = '';
              var stream = conn.getInputStream();
              if (stream) {
                var reader = new java.io.BufferedReader(new java.io.InputStreamReader(stream, this._getCharset()));
                var line;
                while ((line = reader.readLine()) != null) {
                  if (this.readyState == 2) {
                    this.readyState = 3;
                    if (this.onreadystatechange) {
                      this.onreadystatechange();
                    }
                  }
                  reqdata += line + '\n';
                }
                reader.close();
                this.status = 200;
                this.statusText = 'OK';
                this.responseText = reqdata;
                this.readyState = 4;
                if (this.onreadystatechange) {
                  this.onreadystatechange();
                }
                if (this.onload) {
                  this.onload();
                }
              } else {
                // error
                this.status = 404;
                this.statusText = 'Not Found';
                this.responseText = '';
                this.readyState = 4;
                if (this.onreadystatechange) {
                  this.onreadystatechange();
                }
                if (this.onerror) {
                  this.onerror();
                }
              }
            };
          };
        }


        // ActiveXObject emulation
        if (!window.ActiveXObject && window.XMLHttpRequest) {
          window.ActiveXObject = function(type) {
            switch (type.toLowerCase()) {
              case 'microsoft.xmlhttp':
              case 'msxml2.xmlhttp':
              case 'msxml2.xmlhttp.3.0':
              case 'msxml2.xmlhttp.4.0':
              case 'msxml2.xmlhttp.5.0':
                return new XMLHttpRequest();
            }
            return null;
          };
        }

        try
        {
            return new XMLHttpRequest();
        }
        catch(e)
        {
            return null;
        }
}

function ismaxlength(obj) {
    var mlength=obj.getAttribute? parseInt(obj.getAttribute("maxlength")) : ""
    if(obj.getAttribute && obj.value.length>mlength)
        obj.value=obj.value.substring(0,mlength);
}

function inventoryImpression(franchiseId,url,args,synpartner,idx) {
        if ( idx == null ) idx = "";
        var imageName = "hiddenImage" + idx;
        var image = document.images[imageName];
        if ( image == null ) {
             alert("Cannot find image with name='" + imageName + "'");
             return;
        }
        var origImageSrc = image.src;
        var imageUrl = impressionImage(franchiseId,"inventory", synpartner, null);
        image.src = imageUrl;
        var win = window.open(url,'internetspecials',args);
        image.src = origImageSrc;
        win.focus();
}


function redirectWithImpression(franchiseId,url,synpartner,idx,tid) {
    imgImpression(franchiseId,'website',synpartner, tid);
    setTimeout("document.location=\""+url+"\"",1000);
}

function redirectWithImpressionPopup(franchiseId,url,args,synpartner,idx,tid) {
    if ( idx == null ) idx = "";
    var imageName = "hiddenImage" + idx;
    var image = document.images[imageName];
    if ( image == null ) {
        alert("Cannot find image with name=" + imageName + "");
        return;
    }
    var origImageSrc = image.src;
    var imageUrl = impressionImage(franchiseId, "dealer_website", synpartner, tid);
    image.src = imageUrl;

    if(tid != null) {
        setTID(tid);
    }

    var win = window.open(url,'dealer_website',args);
    image.src = origImageSrc;
    win.focus();
}

function imgImpression(franchiseId,type,synpartner, tid)
{
    var imageName = "hiddenImage";
    var image = document.images[imageName];
    if ( image == null ) {
         alert("Cannot find image with name='" + imageName + "'");
         return;
    }
    var origImageSrc = image.src;
    var imageUrl = impressionImage(franchiseId,"inventory",synpartner, tid);

    if (tid != null) {
         setTID(tid);
    }

    image.src = imageUrl;
    image.src = origImageSrc;
    setTimeout("",1000);
    return true;
}

function impressionImage(franchiseId, pageValue, synpartner, tid) {
        // constants
  var gifUrl = "http://dl.edmunds.com/media/trans1x1.gif";
  var fidName = "pdlfranid";
  var pageName = "page";
  var tidParam = "";
  //if ( tid == null )
  //  tidParam = '';
  //else
  //  tidParam = '&tid=' + tid;
  if ( synpartner == null ) synpartner = 'edmunds';
  var imageUrl = gifUrl + '?' + fidName + '=' + franchiseId + '&' + pageName + '=' + pageValue + '&synpartner=' + synpartner + tidParam;
  return imageUrl;
}

function writeImpression(franchiseId,pageValue,synpartner) {
    var imageUrl = impressionImage(franchiseId,pageValue,synpartner,null);
    document.write("<img src=\"" + imageUrl + "\" />");
}

function trimAll(str) {
    return str.replace(/^\s+/g, '').replace(/\s+$/g, '');
}

// US4361 - clean up ms smartquotes in submitted reviews.
function cleanSmartQuotes(textarea_id) {
    var textarea_obj = document.getElementById(textarea_id);
    if (textarea_obj == null) { return; }
    var val = textarea_obj.value;
    if (val) {
        val = val.replace(/[\u2018\u2019]/g, "\'");
        val = val.replace(/[\u201c\u201d]/g, "\"");
        val = val.replace(/\u2013/g, "-");
        val = val.replace(/\u2014/g, "--");
        val = val.replace(/\u2026/g, "...");
        textarea_obj.value = val;
    }
}

