function getFlashMovie(movieName) {
    //var isIE = navigator.appName.indexOf("Microsoft") != -1;
    var isMSIE = /*@cc_on!@*/false;
    var mov;
    if (isMSIE) { 
        mov = window[movieName];
    } else {
        mov = document[movieName];
        if (mov && mov[1]) {
            mov = mov[1];
        }
    }
    return mov;
}

function flashCall() {
    var mov = getFlashMovie("home_flash");
    mov.callToFlash();
}

function showFooterPromo() {
    var mov = getFlashMovie("home_flash");
    //var mov = Home_Flash;
    //console.log("show footer promo have mov %o method type %o",mov,typeof mov.ctfShowFooter);
    if (mov && ((typeof mov.ctfShowFooter === "function") || (typeof mov.ctfShowFooter === "object"))) {
	    if (($.browser.msie) && ($.browser.version < 7)) {
            var waitABit = setTimeout(function(){
                //alert("ctfShowFooter");
                mov.ctfShowFooter();
            },500);
        } else {
            //alert("++Standards browsers ctfShowFooter");
            mov.ctfShowFooter();
        }
    } else {
        //alert("failed to find ctfShowFooter");
    }
}

function hideFooterPromo() {
    var mov = getFlashMovie("home_flash");
    //var mov = Home_Flash;
    //console.log("have mov method %o",mov.ctfHideFooter);
    if (mov) {
        if ((typeof mov.ctfHideFooter === "function") || (typeof mov.ctfHideFooter === "object")) {
	        if (($.browser.msie) && ($.browser.version < 7)) {
                var waitABit = setTimeout(function(){
                    //alert("ctfHideFooter");
                    mov.ctfHideFooter();
                },500);
            } else {
                //alert("++Standards browsers ctfHideFooter");
                mov.ctfHideFooter();
            }
        } else {
            //alert("failed to find ctfHideFooter");
        }
    }
}

function getQueryString() {
    var query = window.location.search;
    return query.substring(1,query.length); 
}

function getQueryVal(options) {
    var mode = false;
    var queryStr = getQueryString();
    var queries = queryStr.split("&");
    var idx;
    var key;
    var val;
    for (i=0, j=queries.length; i<j; i++) {
        idx = queries[i].indexOf("=");
        key = queries[i].substring(0,idx);
        val = queries[i].substring(idx+1,queries[i].length);
        if (key === options.key) {
            mode = val;
        }
    }
    return mode;
}

/*
function parseFlashMode() {
    var mode = false;
    var queryStr = getQueryString();
    var queries = queryStr.split("&");
    var idx;
    var key;
    var val;
    for (i=0, j=queries.length; i<j; i++) {
        idx = queries[i].indexOf("=");
        key = queries[i].substring(0,idx);
        val = queries[i].substring(idx+1,queries[i].length);
        if (key === "mode") {
            mode = val;
        }
    }
    return mode;
}*/

function introVideoComplete() {
    //console.log("introVideoComplete()....");
    helpCenterInit();
}

function flashCallComplete(methodName) {
    //alert('Flash call completed: "'+methodName+'"');
}

function afterFlashLoaded() {
    var targetRef = "home_flash";
    var target = $("#"+targetRef);
    if (target[0]) {
      //var flashMode = parseFlashMode();
      var flashMode = getQueryVal({ key: "mode" });
      //console.log("have flashMode %o, flashModeNew %o",flashMode,flashModeNew);
      if (flashMode === "si") {
          helpCenterInit();
      }
    }
}

function swfObjectEmbedComplete(e) {
    afterFlashLoaded();
    //console.log("swfObjectEmbedComplete(%o)...",e);
    if (e.success) {
        $(document).ready(function(){
            // update body and page backgrounds for Flash
            $("body").css("background-color","#1d1d1d");
            $("#page").css("background","#191817 url(../images/backgrounds/page.jpg) repeat-x 0 149px");
        });
    } else {
      //console.log("NO Flash");
      $("#content_no_javascript").hide();
      $("#content_no_flash").show();
    }
}

function NHRA_flashEmbedComplete(e) {
    var msg;
    if (e.success) {
      msg = "NHRA Flash embed complete.";
    } else {
      msg = "Warning: NHRA Flash did not embed sucessfully.";
    }
    if (console && console.log) {
      console.log(msg);
    }
}

/* fancybox / Youtube fix for Firefox Windows */
$(document).ready(function(){
    var pageHasVideos = ($("#page").hasClass("legacy") || $("#page").hasClass("tortureTest"));
    var clientIsFFWin = (navigator.userAgent.match(/Firefox/) && navigator.userAgent.match(/Windows/));
    //console.log("pageHasVideos %o",pageHasVideos);
    if (pageHasVideos && clientIsFFWin) {
        $(window).scroll(function(){
            var fancyBoxEmbed = $("#fancy_div object")[0];
            //console.log("window scroll, targeting %o",fancyBoxEmbed);
            if (fancyBoxEmbed) {
              $(fancyBoxEmbed).css({ position: "relative", top: "1px" });
              var waitABit = setTimeout(function(){
                  $(fancyBoxEmbed).css({ top: "0" });
              },500);
            }
        });
    }
});

$(document).ready(function(){
    $("#footer_promo_chopper").fancybox();
    $("#footer_promo_torture_tests").fancybox({"frameWidth": 640,
                                               "frameHeight":505,
                                               "hideOnContentClick": false });
});
function doFooterPromo(promoName) {
    //console.log("doFooterPromo(%o)",promoName);
    switch(promoName) {
      case "chopper":
        $("#footer_promo_chopper").trigger("click");
        break;
      case "torture":
        $("#footer_promo_torture_tests").trigger("click");
        break;
    }
}
	
/* General Page Load Events */
$(document).ready(function(){
		
    if (!(jQuery('#carousel').hasClass("jcarousel-list"))) {
        jQuery('#carousel').jcarousel({
            scroll: 1, 
            visible: 4
        });
        // for article page layouts, pad the #content so carousel in
        // open state doesn't hide content below the scroll
        var pageIsBatterySelector = $('#page').hasClass("batterySelector");
        var pageIsLegacy = $('#page').hasClass("legacy");
        var pageHasStickyCarousel = (($('#recProducts').length) && (!pageIsLegacy)) ? true : false;
			if (!pageIsBatterySelector && pageHasStickyCarousel) {
            $("#content").css("padding-bottom",85);
        }
    }
		
    $('.distances').formGroup();

		$('.printShare .print').click(function() {
			$('#printStylesheet').attr("href", "/stylesheets/printChecklist.css");
			window.print();
			var t = setTimeout(function() {
				$('#printStylesheet').attr("href", "/stylesheets/print.css");
			}, 1000);
		});
		
		$('#locator_header').click(function() {
			$("#address_zipcode").eq(0).focus();	
		});
    $('#footer li.legalClose').hide();
		$('#footer li.legal a').click(function() {
        legalToggle();
		});	
		$('#footer li.legalClose a').click(function() {
        legalToggle();
		});
		
    function legalToggle() {
        var pageIsBatterySelector = $('#page').hasClass("batterySelector");
        var pageIsLegacy = $('#page').hasClass("legacy");
        var pageIsHome = $('#page').hasClass("home");
        var pageHasStickyCarousel = (($('#recProducts').length) && (!pageIsLegacy)) ? true : false;
        var stickyCarouselActive = $("#outer").next("#recProductsControl").hasClass("controlOpen");
        var docHeightOrig = (pageHasStickyCarousel) ? 0 : 50;
        //console.log("legalToggle().... stickyCarouselActive %o",stickyCarouselActive);
        var footerMargin = 0;
        var footerHeight = 0;
        var legalHeight = 37;
        var carouselHeight = 85;
        var combinedHeight = legalHeight + carouselHeight;
        var carouselPosition = 0;

		$('#footer .footerLegal').toggle();
        $('#footer li.legalClose').toggle();

        if ($('#footer .footerLegal').css("display") === "none") {
          footerMargin = 21;
          footerHeight = "21px";
			  if (stickyCarouselActive) {
              //console.log("adding combinedHeight %o to content padding",combinedHeight);
              documentPad = carouselHeight;
          } else {
              //console.log("adding legalHeight %o to content padding",legalHeight);
              documentPad = 0;
          }
        } else {
          footerMargin = 58;
          footerHeight = "auto";
			  if (stickyCarouselActive) {
              //console.log("adding combinedHeight %o to content padding",combinedHeight);
              documentPad = combinedHeight;
          } else {
              //console.log("adding legalHeight %o to content padding",legalHeight);
              documentPad = legalHeight;
          }
        }
        documentPad += docHeightOrig;
			$('#footer').css('margin-top',-footerMargin+"px").css("height",footerHeight);
        $("#content").css("padding-bottom",documentPad+"px");
        if (pageIsHome) {
            if (typeof ViewPortUtil === "object") {
                ViewPortUtil.heightAdjust();
            }
        } 
        setCarouselPosition(footerMargin);
    }
    function setCarouselPosition(footerHeight) {
        var pageIsLegacy = $('#page').hasClass("legacy");
        var pageHasStickyCarousel = (($('#recProducts').length) && (!pageIsLegacy)) ? true : false;
        //console.log("pageIsLegacy %o, pageHasStickCarousel %o",pageIsLegacy,pageHasStickyCarousel);
        var carouselHeight = (pageHasStickyCarousel) ? 85: 0;
        var combinedHeights = footerHeight + carouselHeight;
			if (!($('#page').hasClass("batterySelector"))) {
				$('#recProducts').css("bottom",footerHeight+"px");
				if ($('#recProductsControl').hasClass("controlOpen")) {
					$('#recProductsControl.controlOpen').css("bottom",combinedHeights+"px");
				} else {
					$('#recProductsControl').css("bottom",footerHeight+"px");
				}
        }
    }

    var pageIsBatterySelector = $('#page').hasClass("batterySelector");
    var pageIsLegacy = $('#page').hasClass("legacy");

    if (!pageIsBatterySelector && !pageIsLegacy) {
      animatedcollapse.addDiv('recProducts', 'fade=1,speed=75');
      animatedcollapse.init();
    }
	$('#recProductsControl a').click(function(e) {
        //carouselToggle_stickyFooter();
        carouselToggle();
        e.preventDefault();
    });	
});

/* Products Carousel */
function doCarousel() {
    //$('#footer').toggleClass("footerOpen");
    $('#recProductsControl').toggleClass("controlOpen");
}

carouselToggle = function() {
  doCarousel();
  var carouselHeight = 85;
  var carouselHeight_new = 0;
  var footerHeight = 58;
  var clientIsMSIE6 = /MSIE 6/i.test(navigator.userAgent);
  var clientIsMSIE7 = /MSIE 7/i.test(navigator.userAgent);
  //var controlPositionDefault = (clientIsMSIE6) ? 143 : 85;
  //var carouselPosition = (clientIsMSIE6) ? 58 : 0;
  var controlPositionDefault = 143;
  var carouselPosition = 58;
  var contentPadding = 0;
  if (!($('#page').hasClass("batterySelector"))) {
    if (($('#recProducts').css("display") == "block")) {
    // carousel shown, hide it
        controlPosition = carouselPosition;
        carouselHeight_new = 0;
    } else {
    // carousel hidden, show it
        controlPosition = controlPositionDefault;
        carouselHeight_new = 58;
    }
    animatedcollapse.toggle('recProducts'); 
    if (clientIsMSIE6) {
        var helpCenterHeight = $("#helpCenterTab").height();
        var pageHeight = $("#page").height() + 20 + carouselHeight_new + helpCenterHeight;
        //alert("carouselToggle(): set #contain to new height "+pageHeight);
        $("#contain").css("height",pageHeight+"px");
        $("#outer").css("height",pageHeight+"px");
    }
    //$('#content').css("padding-bottom",contentPadding+"px");
    //$('#recProductsControl').css("bottom",controlPosition+"px");
  }
}

carouselToggle_stickyFooter = function() {
  doCarousel();
  var carouselHeight = 85;
  var footerHeight = 21;
  var legalHeight = 37;
  var controlPositionDefault = 106;
  //console.log("footer margin %o",$('#footer').css("margin-top"));
  var carouselPosition = 0;
  var contentPadding = 0;

  if (!($('#page').hasClass("batterySelector"))) {
  //console.log("conditionals footer legal %o, carousel %o",($(".footerLegal").css("display") === "block"),($("#recProducts").css("display") === "block"));
    if (($('.footerLegal').css("display") == "block") && 
      ($('#recProducts').css("display") == "block")) {
      carouselPosition = footerHeight + legalHeight;
      contentPadding = legalHeight;
      //alert("hiding carousel, putting control position at "+carouselPosition);
      controlPosition = carouselPosition;
    } else if 
    (($('.footerLegal').css("display") == "block") && 
    ($('#recProducts').css("display") == "none")) {
      carouselPosition = footerHeight + carouselHeight + legalHeight;
      contentPadding = carouselHeight + legalHeight;
      //alert("showing carousel, putting control position at "+(controlPositionDefault+legalHeight));
      controlPosition = controlPositionDefault + legalHeight;
    } else if 
    (($('.footerLegal').css("display") == "none") && 
    ($('#recProducts').css("display") == "none")) {
      carouselPosition = footerHeight + carouselHeight;
      contentPadding = carouselHeight;
      //alert("showing carousel, putting control position at "+controlPositionDefault);
      controlPosition = controlPositionDefault;
    } else if 
    (($('.footerLegal').css("display") == "none") && 
    ($('#recProducts').css("display") == "block")) {
      carouselPosition = footerHeight;
      contentPadding = 0;
      //alert("zero content pad? hiding carousel, putting control position at "+carouselPosition);
      controlPosition = carouselPosition;
    }
    animatedcollapse.toggle('recProducts'); 
    $('#content').css("padding-bottom",contentPadding+"px");
    $('#recProductsControl').css("bottom",controlPosition+"px");
  }
}
    
/* Liveperson Popup */
$(document).ready(function(){
  $(".livePersonCallout").click(function(e){
      window.open('https://sales.liveperson.net/hc/37457093/?cmd=file&file=visitorWantsToTalk&site=37457093&byhref=1&SESSIONVAR!skill=sears-automotive-voice-sales-english&SESSIONVAR!staticButton=diehardvoice','chat37457093','width=475,height=275,resizable=yes');
      if ((typeof omniture_pageName != "undefined") && (typeof omniture_sectionName != "undefined")) {
          $(buttonPrint).click(function(){
              //console.log("button click %o, doing Omniture call...",this);
              clicked = this; 
              var linkName = omniture_sectionName + " > Speak to Assistant";
              doOmnitureEvent({ pageName: omniture_pageName, 
                                channel:  omniture_sectionName, 
                                linkName: linkName,
                                clicked:  clicked });
          });
      }
      e.preventDefault();
  });
});

$(document).ready(function(){
      if ((typeof omniture_pageName != "undefined") && (typeof omniture_sectionName != "undefined")) {
          var btns = [  { DOMel: $("#helpCenterButton_jump"),     title: " > Help Center > Jump a Battery" },
                        { DOMel: $("#helpCenterButton_install"),  title: " > Help Center > Install a Battery" },
                        { DOMel: $("#helpCenterButton_locator"),  title: " > Help Center > Find a Retailer" }
                     ];
          for (var i=0, j=btns.length; i<j; i++) {
              var btn = btns[i].DOMel;
              var title = btns[i].title;
              if (btn) {
                  $(btn).click(function(titleScoped){
                      return function() {
                          //alert("title: '"+titleScoped+"'");
                          //console.log("button click %o, doing Omniture call...",this);
                          clicked = this; 
                          var linkName = omniture_sectionName + titleScoped;
                          doOmnitureEvent({ pageName: omniture_pageName, 
                                            channel:  omniture_sectionName, 
                                            linkName: linkName,
                                            clicked:  clicked });
                      };
                  }(title));
              }
          }
      }
});
/* Sidebar callouts PNG alpha fix */
$(document).ready(function() {
	//$(".serviceLiveCallout span").pngFix();
	$(".serviceLiveCallout").mouseover(function() {
		$(".serviceLiveCallout span").css("margin-top","-44px");
	}); 
	$(".serviceLiveCallout").mouseout(function() {
		$(".serviceLiveCallout span").css("margin-top","0");								   
	});
	//$(".autoCenterCallout span").pngFix();
	$(".autoCenterCallout").mouseover(function() {
		$(".autoCenterCallout span").css("margin-left","-172px");
	}); 
	$(".autoCenterCallout").mouseout(function() {
		$(".autoCenterCallout span").css("margin-left","0");								   
	});
	$(".livePersonCallout").mouseover(function() {
		$(".livePersonCallout span").css("margin-left","-172px");
	}); 
	$(".livePersonCallout").mouseout(function() {
		$(".livePersonCallout span").css("margin-left","0");								   
	});
});

/* Safari fix for products section */
$(document).ready(function() {
	if ($.browser.safari) {
		
		$("#topNav li.products ul li a").css("height","19px").css("padding-top","10px");
		
		$("#topNav li ul li.chargers a").css("height","23px").css("padding-top","6px");
		
		$("#tabs ul").css("margin-bottom","-1px");
	}	
});

/* Legacy Lightbox */
$(document).ready(function(){
    $(".legacy #carousel li a").fancybox({"frameWidth": 640,
                                          "frameHeight":505,
                                          "hideOnContentClick": false });
});

/* Torture Test Page */
var tortureVideos = [ ];
   	tortureVideos.push({  DOMRef: "#tortureLightboxLinks li a.extremeKeyboard",     
                          queryVal: "keyboard",  
                          title: "Extreme Keyboard"
                       }); 
    tortureVideos.push({  DOMRef: "#tortureLightboxLinks li a.extremeHeat",       
                          queryVal: "heat",    
                          title: "Extreme Heat"  
                       });
	tortureVideos.push({  DOMRef: "#tortureLightboxLinks li a.extremeToughness",     
		                  queryVal: "toughness",  
		                  title: "Extreme Toughness"
		                   });
    tortureVideos.push({  DOMRef: "#tortureLightboxLinks li a.extremePower",       
                          queryVal: "power",    
                          title: "Extreme Power"  
                       }); 
    tortureVideos.push({  DOMRef: "#tortureLightboxLinks li a.extremeHeadlights",  
                          queryVal: "headlights", 
                          title: "Extreme Headlights" 
                       }); 
    tortureVideos.push({  DOMRef: "#tortureLightboxLinks li a.extremeJumpstart",   
                          queryVal: "jumpstart",
                          title: "Extreme Jumpstart" }); 

var reinitializeAddThis_OLD = function() {
  if (window.addthis){
      window.addthis.ost = 0;
      window.addthis.ready();
  }
}
var insertAddThis = function() {
    var addThisHTML = [];
    addThisHTML.push('<div class="addthis_lightbox addthis_toolbox addthis_default_style">');
    addThisHTML.push('    <div><a class="addthis_button_compact"> Share</a></div>');
    //addThisHTML.push('    <span class="addthis_separator"></span>');
    addThisHTML.push('    <div><a class="addthis_button_email"></a></div>');
    addThisHTML.push('    <div><a class="addthis_button_print"></a></div>');
    addThisHTML.push('    <div><a class="addthis_button_facebook"></a></div>');
    addThisHTML.push('    <div><a class="addthis_button_twitter"></a></div>');
    addThisHTML.push('</div>');
    var lightboxEl = $("#fancy_inner")[0];
    if (lightboxEl) {
      //$(lightboxEl).prepend(addThisHTML);
      $(lightboxEl).append(addThisHTML.join("\n"));
    }
}
var addthis_config = {
    username: "xa-4b2f9a4f209bb706"
};
var reInitAddThis = function(){
    //alert("reinit addthis");

    /* Remove previous addthis JS */
    if ( $("#script_addthis_pageload")[0] ) {
         $("#script_addthis_pageload").remove();
    }

    /* Insert addthis JS back into the DOM */
    var head = document.getElementsByTagName('head')[0];
    var script = document.createElement('script');
    script.id = "script_addthis_pageload";
    script.type= "text/javascript";
    //script.src= "http://s7.addthis.com/js/250/addthis_widget.js#username=xa-4b2f9a4f209bb706";
    script.src= "http://s7.addthis.com/js/250/addthis_widget.js";

    var addThisComplete = function() {
        //console.log("re-inserted the addthis script %o",$("#script_addthis_pageload"));
        addthis.toolbox(".addthis_toolbox");
        //alert("re-inserted the addthis script!");
        //reinitializeAddThis_OLD();
    }
    script.onreadystatechange= function () {
          if (this.readyState == 'complete') 
            addThisComplete();
    }
    script.onload = addThisComplete;
    head.appendChild(script); 
}

var tortureLightBoxClosed = function(){
    var protocol = window.location.protocol;
    var host = window.location.host;
    var path = window.location.pathname;
    var page = protocol + "//" + host + path;

    /* Go to same page but without query string */
    window.location = page;
}

var tortureLightBoxShown = function(){
    var btnNavLeft = $("#fancy_left_ico")[0];
    var btnNavRight = $("#fancy_right_ico")[0];
    if (btnNavLeft && btnNavRight) {
        //console.log("tortureLightboxShown()....");
        var videoQuery = getQueryVal({ key: "video" });
        if (videoQuery) {
            for (var i=0, j=tortureVideos.length; i<j; i++) {
                if (videoQuery === tortureVideos[i].queryVal) {
                    var thisVidQuery = tortureVideos[i].queryVal;
                    var idx;

                    if (i > 0) { 
                      idx = i-1;
                    } else { 
                      idx = tortureVideos.length-1;
                    }  
                    var prevVidQuery = tortureVideos[idx].queryVal;

                    if (i < (tortureVideos.length-1)) {
                        idx = [i+1];
                    } else {
                        idx = 0;
                    }
                    var nextVidQuery = tortureVideos[idx].queryVal; 
                    //console.log("this vid %o, prev %o, next %o",thisVidQuery,prevVidQuery,nextVidQuery);
                }
            }

            $(btnNavLeft).unbind("click");
            $(btnNavRight).unbind("click");
            var protocol = window.location.protocol;
            var host = window.location.host;
            var path = window.location.pathname;
            var page = protocol + "//" + host + path;

            $(btnNavLeft).click(function(e){
                //console.log("left nav %o clicked, prev %o",this,prevVidQuery);
                window.location = page + "?video=" + prevVidQuery;
                //$(this).unbind("click");
                //e.preventDefault();
            });
            $(btnNavRight).click(function(e){
                //console.log("right nav %o clicked, next %o",this,nextVidQuery);
                window.location = page + "?video=" + nextVidQuery;
                //$(this).unbind("click");
                //e.preventDefault();
            });
        }
    }
    //var addThisHTML = '<div class="addthis_lightbox"><a class="addthis_button" href="http://www.addthis.com/bookmark.php?v=250&amp;username=xa-4b2f9a4f209bb706"><img src="http://s7.addthis.com/static/btn/sm-share-en.gif" width="83" height="16" alt="Bookmark and Share" style="border:0"/><script type="text/javascript" src="http://s7.addthis.com/js/250/addthis_widget.js#username=xa-4b2f9a4f209bb706"></script></div>';

    /* Create and insert addthis HTML into the lightbox */
    insertAddThis();

    /* Re-initialize addthis JS for button added to lightbox */
    reInitAddThis();

}
$(document).ready(function(){
    /* initialize the addthis JS for page load *//*

    /* Can't initialize addthis anytime before a * 
     * lightbox is shown or it breaks in IE      */
    var isMSIE = /*@cc_on!@*/false;
    if (!isMSIE) {
        reInitAddThis();
    }
});

$(document).ready(function(){

    /* Register Fancybox lightbox plugin for torture buttons
    $("#tortureList li a").fancybox({ "frameWidth": 853,
                                      "frameHeight":505,
                                      "hideOnContentClick": false,
                                      "callbackOnShow": tortureLightBoxShown
                                      });
                                      */
    var videoQuery = getQueryVal({ key: "video" });
    //console.log("have video %o",videoQuery);
    if (videoQuery) {
        $("#tortureLightboxLinks li a").fancybox({ "frameWidth": 853,
                                          "frameHeight":505,
                                          "hideOnContentClick": false,
                                          "callbackOnShow": tortureLightBoxShown,
                                          "callbackOnClose": tortureLightBoxClosed
                                          });
        for (var i=0, j=tortureVideos.length; i<j; i++) {
            if (videoQuery === tortureVideos[i].queryVal) {
                //console.log("have match!! between page query %o and video %o",videoQuery,tortureVideos[i].queryVal);

                /* update page title with the video title */
                var separator = (i == 0) ? "" : " | ";
                document.title = document.title + separator + tortureVideos[i].title;

                /* open the fancybox */
                var button = $(tortureVideos[i].DOMRef)[0];
                if (button) {
                    $(button).trigger("click");
                }
            }
        }
    } else {
        /* Can't initialize addthis anytime before a     * 
         * lightbox is shown or it breaks in IE          *
         * Handling landing without video edge case here */
        var isMSIE = /*@cc_on!@*/false;
        if (isMSIE) {
            reInitAddThis();
        }
    }
});

/* Omniture Tracking for Article Checklist Print/Share */
$(document).ready(function(){
    var buttonPrint = $(".printShare .print")[0];
    var buttonShare = $(".printShare .share")[0];
    if ((typeof omniture_pageName != "undefined") && (typeof omniture_sectionName != "undefined")) {
        var pageName = omniture_pageName;
        $(buttonPrint).click(function(){
            //console.log("button click %o",this);
            clicked = this; 
            var linkName = omniture_sectionName + " > Checklist > Print";
            doOmnitureEvent({ pageName: pageName, 
                              channel:  omniture_sectionName, 
                              linkName: linkName,
                              clicked:  clicked });
        });
        $(buttonShare).click(function(){
            //console.log("button click %o",this);
            clicked = this; 
            var linkName = omniture_sectionName + " > Checklist > Share";
            doOmnitureEvent({ pageName: pageName, 
                              channel:  omniture_sectionName, 
                              linkName: linkName,
                              clicked:  clicked });
            //om_activateShare("large");
              shareActivateInt = window.setInterval(function(){ om_activateShare("large"); },900);
        });
            $(buttonShare).mouseover(function(){
            //var waitABit = setTimeout(om_activateShare("small"),500);
            shareActivateInt = window.setInterval(function() { om_activateShare("small") },900);
        });
    }
});

var om_activateShare = function(type) {
    //console.log("om_activateShare()....");
    var shareBox = true;
    if (type === "large") {
        shareBox = $("#at20mc")[0];
    } else if (type === "small") {
        shareBox = $("#at15s")[0];
    }
    if (shareBox) {
        window.clearInterval(shareActivateInt);
        var shareLinks = $(shareBox).find(".at_item");
        $(shareLinks).unbind("click");
        $(shareLinks).click(function(){
            //console.log("button click %o",this);
            clicked = this; 
            var linkText = $(this).text();
            var linkName = omniture_sectionName + " > Checklist > Share > " + linkText;
            doOmnitureEvent({ pageName: omniture_pageName, 
                              channel:  omniture_sectionName, 
                              linkName: linkName,
                              clicked:  clicked });
        });
    }
}

/* Omniture Tracking for Product Verticals Tabbed Content */
$(document).ready(function(){
    var tabControls = $("#content #tabs ul > li a");
    var linkName = "";
    var clicked = false;
    //console.log("Omniture tracking: have tabControls %o",tabControls);
    var page = "";
    var channel = "Products";
    var vertical = $("#page")[0].className;
    //console.log("Omniture tracking: have #page className %o",vertical);
    switch(vertical) {
        case "automotive":
            page = "Products > Automotive";
            category = "Automotive";
            break;
        case "marine":
            page = "Products > Marine";
            category = "Marine";
            break;
        case "powersport":
            page = "Products > PowerSport";
            category = "PowerSport";
            break;
        case "tractor":
            page = "Products > Lawn and Tractor";
            category = "Lawn and Tractor";
            break;
        case "tools":
            page = "Products > Tools and Home";
            category = "Tools and Home";
            break;
        case "chargers":
            page = "Products > Chargers and Portable Power";
            category = "Chargers and Portable Power";
            break;
        case "gear":
            page = "Products > Gear";
            category = "Gear";
            break;
    }
    $(tabControls).click(function(){
        //console.log("tab click %o",this);
        clicked = this; 
        linkName = $(this).html().replace(/<br.*?>/," ");
        linkName = linkName.replace(/&amp;/,"and");
        doOmnitureEvent({ pageName: page, 
                          channel:  "Products", 
                          linkName: linkName,
                          clicked:  clicked, 
                          sProp39:  category,
                          sProp44:  linkName,
                          linkTrackOptionalVars: "prop39,prop44" });
    });
});

/* Footer promo: PNG alpha fix for IE6 div.promo is parent of a single <img>     *
 * which we want inline for ease of drop-in replacement, e.g. content management */
$(document).ready(function(){
  $("#footer .promo").pngFix();
});

/* Battery selector: progressive enhancement, add class to container div so *
 * CSS scope can be wider for this page without major Rails re-factoring to *
 * support a minor UI feature                                               */
$(document).ready(function(){
  $(".batterySelector").parent().addClass("batterySelectorWrap");
});

/* Battery selector content height fix */

function adjustBatterySelectorHeight() {
	var h = viewPortHeight();
    var textHeight = $("#selectorResults li span").height();
    var textOffset = textHeight - 14.5;
    var minHeightBase = 493;
    var headerFooterOffset = 80;
    var totalMinHeight = minHeightBase + headerFooterOffset + textOffset;
    //console.log("totalMinHeight %o, minHeightBase %o, headerFooterOffset %o, textOffset %o, textHeight %o",totalMinHeight,minHeightBase,headerFooterOffset,textOffset, textHeight );
	if (h > totalMinHeight) {
		var newH = h - headerFooterOffset + "px";
	} else {
		var newH = minHeightBase + textOffset + "px";
	}
    //alert("viewPortHeight() '"+h+"', newH '"+newH+"', totalMinHeight '"+totalMinHeight+"', minHeightBase '"+minHeightBase+"', headerFooterOffset '"+headerFooterOffset+"', textOffset '"+textOffset+"', textHeight '"+textHeight+"'");
	$(".batterySelector #content .stepOne").css("min-height",minHeightBase+textOffset+"px");
	//$(".batterySelector #wrapper").css("height",newH);
	$(".batterySelector #wrapper").css("min-height",newH);
}

$(document).ready(function() {
	if ($("#page").hasClass("batterySelector")) {	
		adjustBatterySelectorHeight();
	}
});
$(window).resize(function() {
	if ($("#page").hasClass("batterySelector")) {	
		adjustBatterySelectorHeight();
	}
});

/* Help Center Tabbed Drop-down */

/* Action to show Help Center for 15 seconds */
helpCenterInit = function() {
  //console.log("helpCenterInit()...");
	if ($("body").hasClass("home_root")) {
        var target = $("#helpCenterTab")
        if ($(target).hasClass("collapsed")) {
            $(target).removeClass("collapsed");
            $(target).removeClass("collapsedAndSet");
		    if (typeof ViewPortUtil === "object") {
		      ViewPortUtil.heightAdjust();
		    }
		    var t = setTimeout(function() {
                //helpCenterAnimate("closed",800);
                if (!$(target).hasClass("collapsed")) {
                    helpCenterToggle();
                }
		    }, 15000);
        }
	}
}

/* Help Center Animate */
helpCenterAnimate = function(direction,duration) {
    //console.log("helpCenterAnimate(%o,%o)...",direction,duration);
    var target = $("#helpCenterTab");
    var classRemove;
    var classAdd;
    var classTest = "collapsedAndSet";
    switch(direction) {
        case "open":
                classRemove = "collapsed";
                classAdd = "";
                extraRemove = "helpCenterClosed"
                extraAdd = "";
            break;
        case "closed":
                classRemove = "";
                classAdd = "collapsed";
                extraRemove = ""
                extraAdd = "helpCenterClosed";
            break;
    }
    var alreadyThere = $(target).hasClass(classAdd);
    //console.log("case %o... check for target already has class %o: alreadyThere %o",direction,classAdd,alreadyThere );
    if (!alreadyThere) {
        //console.log("doing anim");
        //alert("doing anim");
        if (direction === "open") {
            $("#helpCenterTab").css("background-color","#AB8817");
            $("#helpCenterTab").css("background-image","none");
		    if ($("#page").hasClass("home")) {
	            if (!(($.browser.msie) && ($.browser.version < 7))) {
                //hideFooterPromo();
                }
            }
        } else {
		    if ($("#page").hasClass("home")) {
	            if (!(($.browser.msie) && ($.browser.version < 7))) {
                //showFooterPromo();
                }
            }
        } 
	    if (($.browser.msie) && ($.browser.version < 7)) {
            $("#wrapper").css("zoom","1");
        }
        //alert('switch class: classRemove "'+classRemove+'", classAdd "'+classAdd+'", duration "'+duration+'", extraRemove "'+extraRemove+'", extraAdd "'+extraAdd+'"..');
        $(target).switchClass(classRemove,classAdd,duration);
		if ($("#page").hasClass("home")) {
		    if (($.browser.msie) && ($.browser.version < 7)) {
            var footerWait = setTimeout(function(){
                $("#footer").removeClass(extraRemove);
                $("#footer").addClass(extraAdd);
            },duration);
            } else {
            $("#footer").switchClass(extraRemove,extraAdd,duration);
            }
        }
        //$("#wrapper").switchClass(extraRemove,extraAdd,duration);
        //alert("setup anim afters");
        var waitTime = duration + 100;
        var waitABit = setTimeout(function(){
            //alert("anim afters...");
            //console.log("doing extra CSS...");
            if (direction === "open") {
                $("#helpCenterTab").css("background","#AB8817 url(../images/backgrounds/helpCenter-bgd-tile.png) 0 0 repeat-x");
                $(target).removeClass("collapsedAndSet");
                $(target).removeClass("collapsed");
                $("#footer").css("margin-top","65px");
            } else {
                $(target).addClass("collapsedAndSet");
                $(target).addClass("collapsed");
                $("#footer").css("margin-top","");
                //alert("adjusting viewport");
                //ViewPortHeightAdjust();
                //$("#wrapper").removeClass(extraAdd);
                //$("#footer").removeClass(extraAdd);
            }
		    if (($.browser.msie) && ($.browser.version < 7)) {
            //$("#wrapper").switchClass("tabStuff","",1);
                $("#wrapper").css("position","relative");
                $("#wrapper").css("zoom","");
                //alert("fixed?");
            }
        },waitTime);
    }

}

helpCenterToggle = function() {
    var target = $("#helpCenterTab");
    $(target).toggleClass("collapsed");
    $(target).toggleClass("collapsedAndSet");
    /* prefer to toggle as above instead of animate, since it performs poorly *
     * on any slow browser, not just Internet Explorer, per Casey Hess        */
	if (0 && !(($.browser.msie) && ($.browser.version < 7))) {
        if ($(target).hasClass("collapsed")) {
            helpCenterAnimate("open",800);
        } else {
            helpCenterAnimate("closed",800);
        } 
        // external function
        if (typeof ViewPortUtil === "object") {
		  ViewPortUtil.heightAdjust();
        }
    } else {
        //alert("toggle help bar ie6");
        /* IE6 AS3 External Interface bug keep us from reliably showing/hiding Flash *
         * footer promo via JS, so skipping that intended display feature for now    */
         /*
        if ($(target).hasClass("collapsed")) {
		    if ($("#page").hasClass("home")) {
                hideFooterPromo();
            }
        } else {
		    if ($("#page").hasClass("home")) {
                showFooterPromo();
            }
        } 
        */
	    /* IE6 fix */
		if (($("#page").hasClass("home"))) {
            $("#wrapper").css("zoom","1");
            $("#wrapper").css("position","relative");
            var waitThenFixWrapper = setTimeout(function(){
                $("#wrapper").css("zoom","");
                $("#wrapper").css("position","relative");
            },100);
		} else {
			if (!($("#helpCenterTab").hasClass("collapsed"))) {
				//$("#content").css("margin-top","0");	
			} else {
				//$("#content").removeAttr("style");
			}
            var carouselHeight_new = 0;
            var carousel = $("#recProducts")[0];
            if (carousel && !($(carousel).css("display") === "none")) {
                carouselHeight_new = $(carousel).height();
                if (carouselHeight_new > 0) {
                    carouselHeight_new -= 26;
                }
            }
            var helpCenter = $("#helpCenterTab")[0];
            var helpCenterOpen = !$("#helpCenterTab").hasClass("collapsed");
            var helpCenterHeight = 0;
            if (helpCenter) {
                helpCenterHeight = (helpCenterOpen) ? $("#helpCenterTab").height() : 0;
            }
            var pageIsLegacy = $("#page").hasClass("legacy");
            var pageInProducts = $("#page")[0].className.match(/automotive|marine|powersport|tractor|tools|chargers|gear/);
            var legacyHeight = (pageIsLegacy) ? 60 : 0;
            var productsHeight = (pageInProducts) ? 40 : 0;
            var pageHeight = $("#page").height() + helpCenterHeight + carouselHeight_new + legacyHeight + productsHeight;
            //alert("helpCenterToggle(): set #contain to new height "+pageHeight);
            $("#contain").css("height",pageHeight+"px");
            $("#outer").css("height",pageHeight+"px");
        }
        // external function
        if (typeof ViewPortUtil === "object") {
		      ViewPortUtil.heightAdjust();
        }
	}
}

/* Help Center Click Tab Control */
$(document).ready(function(){
    $("#helpCenterTabControl").click(function(){
        helpCenterToggle();
    });
    /* CSS support for IE6 -- alternate layout the Help Center tab, to retain    * 
     * 24-bit PNG w/ alpha across normal vs. hover and collapsed vs. open states */
    var span = $("#helpCenterTabControl > span");
    $("#helpCenterTabControl").mouseover(function(){
        $(span).css("top","-21px");
    });
    $("#helpCenterTabControl").mouseout(function(){
        $(span).css("top","0");
    });
});

/* Omniture Click Tracking Utility */
doOmnitureEvent = function(options) {
    //s.linkTrackVars='prop1,prop2,events'; 
    //s.linkTrackEvents='event1'; 
    //s.prop1='Custom Property of Link'; 
    //s.events='event1'; 
    //s.tl(this,'o','Link Name'); 
    //handle options
    this.options = {  eventType: "click",
                      clicked: false, 
                      linkTrackVars: "channel,eVar12",
                      linkTrackOptionalVars: false,
                      linkTrackEvents: "None",
                      events: false,
                      pageName: false,
                      linkName: "",
                      channel: false,
                      eVar7: false,
                      eVar12: "DieHard",
                      eVar38: false,
                      sProp39: false,
                      sProp44: false };
                     
    //console.log("doOmnitureEvent: default options %o",this.options);
    jQuery.extend(this.options,options);
    if (this.options.linkTrackOptionalVars) {
        this.options.linkTrackVars += ","+this.options.linkTrackOptionalVars;
    }
    s.linkTrackVars = this.options.linkTrackVars; 
    s.linkTrackEvents = this.options.linkTrackEvents; 
    //console.log("doOmnitureEvent: options incl. instance args %o",this.options);
    
    //copy values from options hash
    if (this.options.pageName) {
        s.pageName = this.options.pageName;
    }
    if (this.options.channel) {
        s.channel = this.options.channel;
        //console.log("added channel to %o, s.channel %o",s,s.channel);
    }
    s.eVar7 = this.options.eVar7;
    if (this.options.eVar7) {
        s.eVar7 = this.options.eVar7;
        //console.log("added eVar7 to %o, s.eVar7 %o",s,s.eVar7);
    }
    s.eVar12 = this.options.eVar12;
    if (this.options.eVar38) {
        s.eVar38 = this.options.eVar38;
        //console.log("added eVar38 to %o, s.eVar38 %o",s,s.eVar38);
    }
    if (this.options.sProp39) {
        s.prop39 = this.options.sProp39;
    }
    if (this.options.sProp44) {
        s.prop44 = this.options.sProp44;
    }
    if (this.options.events) {
        s.events = this.options.events;
    }

    if (this.eventType === "pageload") {
      s.t(); 
      //console.log("doOmnitureEvent: eventType \"pageload\"");
    } else if (this.options.clicked) {
      //console.log("doOmnitureEvent: have clicked as %o",this.options.clicked);
      //console.log("pre event %o",s);
      //console.log("s.linkTrackvars %o; s.eVar38 %o, s.eVar12 %o",s.linkTrackVars,s.eVar38,s.eVar12);
      s.tl(this.options.clicked,'o',this.options.linkName); 
      //console.log("post event %o",s);
      //console.log("s.linkTrackvars %o; s.eVar38 %o, s.eVar12 %o",s.linkTrackVars,s.eVar38,s.eVar12);
    }
}


var FitmentTest = function() {
    var self = this;
    this.params = { fitmentSteps: [ { key: "year",  value: "false" },
                                    { key: "make",  value: "false" },
                                    { key: "model", value: "false" },
                                    { key: "engine", value: "false" } 
                                  ] };
    this.init = function() {
      //this.getFitmentData({ step: 1 }); 
    }
    this.dataComplete = function(options) {
      //console.log("dataComplete() %o",options);
      switch(options.step) {
        case 1:
          this.getYearResults(options);
          break;
        case 2:
          this.getMakeResults(options);
          this.displayMakeResults(options);
          break;
        case 3:
          this.getModelResults(options);
          this.displayModelResults(options);
          break;
        case 4:
          this.getEngineResults(options);
          this.displayEngineResults(options);
          break;
        case 5:
          this.getProductResults(options);
          this.displayProductResults(options);
          break;
      }
    }
    this.getYearResults = function() {
      this.params.fitmentResults = { };
      $("#year_list").find("a").each(function(index){
          var key = $(this).text();
          self.params.fitmentResults[key] = { };
      });
      //console.log(this.params.fitmentResults);
      for (year in this.params.fitmentResults) {
        this.params.fitmentSteps[0].value = year;
        this.getFitmentData({ step: 2, year: year }); 
      }
    }
    this.getMakeResults = function(options) {
      //console.log("getMakeResults");
      $("#make_list").find("a").each(function(index){
          var year = options.year;
          var make = $(this).text();
          //console.log("year: %o, make: %o",year,make);
          self.params.fitmentResults[year][make] = { };
      });
      //console.log(this.params.fitmentResults);
    }
    this.getModelResults = function(options) {
      $("#model_list").find("a").each(function(index){
          var year = options.year;
          var make = options.make;
          var model = $(this).text().replace(/;[ ]*/g," ").replace(/ /,"_");
          //console.log("year: %o, make: %o, model: %o",year,make,model);
          self.params.fitmentResults[year][make][model] = { };
      });
      //console.log(this.params.fitmentResults);
    }
    this.getEngineResults = function(options) {
      $("#engine_list").find("a").each(function(index){
          var year = options.year;
          var make = options.make
          var model = options.model.replace(/;[ ]*/g," ").replace(/ /,"_");
          var engine = $(this).text();
          //console.log("year: %o, make: %o",year,make);
          self.params.fitmentResults[year][make][model][engine] = { };
      });
    }
    this.getProductResults = function(options) {
      console.log("getProductResults(%o)",options);
    }
    this.displayMakeResults = function(options) {
      var parentLinks = $("#year_list").find("a[rel='"+options.year+"']");
      var subListId = options.year + "_make_list";
      $(parentLinks).each(function(index){
        $(this).after('<ul id="'+subListId+'"></ul>'); 
      });
      var sublist = $("#"+subListId);
      for (make in self.params.fitmentResults[options.year]) {
        var subListItemId = options.year + "_" + make;
        $(sublist).append('<li><a href="javascript:;" id="'+subListItemId+'">'+make+'</a></li>');
        $("#"+subListItemId).click(function(makeScoped){
          return function() {
          //ev.preventDefault();
          self.getFitmentData({ step: 3, year: options.year, make: makeScoped }); 
          }
        }(make));
      }
    }
    this.displayModelResults = function(options) {
      var parentLinks =$("#"+options.year+"_"+options.make);
      var subListId = options.year + "_" + options.make + "_model_list";
      $(parentLinks).each(function(index){
        $(this).after('<ul id="'+subListId+'"></ul>'); 
      });
      var sublist = $("#"+subListId);
      for (model in self.params.fitmentResults[options.year][options.make]) {
        var subListItemId = options.year + "_" + options.make + "_" +model;
        $(sublist).append('<li><a href="javascript:;" id="'+subListItemId+'">'+model+'</a></li>');
        $("#"+subListItemId).click(function(modelScoped){
          return function() {
          console.log("clicked %o",this);
          //ev.preventDefault();
          self.getFitmentData({ step: 4, year: options.year, make: options.make, model: modelScoped }); 
          }
        }(model));
      }
    }
    this.displayEngineResults = function (options) {
      var model = options.model.replace(/;[ ]*/g,"");
      var parentLinks =$("#"+options.year+"_"+options.make+"_"+model);
      var subListId = options.year + "_" + options.make + "_" + model + "_engine_list";
      $(parentLinks).each(function(index){
        $(this).after('<ul id="'+subListId+'"></ul>'); 
      });
      var sublist = $("#"+subListId);
      for (engine in self.params.fitmentResults[options.year][options.make][model]) {
        var subListItemId = options.year + "_" + options.make + "_" + model + "_" + engine;
        $(sublist).append('<li><a href="javascript:;" id="'+subListItemId+'">'+engine+'</a></li>');
        $("#"+subListItemId).click(function(engineScoped){
          return function() {
          //ev.preventDefault();
          self.getFitmentData({ step: 5, year: options.year, make: options.make, model: options.model, engine: engineScoped }); 
          }
        }(engine));
      }
    }
    this.displayProductResults = function(options) {
      console.log("displayProductResults(%o)",options);
    }
    this.getFitmentData = function(options) {
        //console.log("getFitmentData(%o)...",options);
        var n = options.step-1;
        var authToken = window._token;
        //console.log("getFitmentData(): leading space for year? %o; make? %o; model? %o; engine? %o",this.fitmentSteps[0].resultLeadingSpace,this.fitmentSteps[1].resultLeadingSpace,this.fitmentSteps[2].resultLeadingSpace,this.fitmentSteps[3].resultLeadingSpace);

        // get fitment from options
        var year    = options.year;
        var make    = options.make;
        var model   = options.model;
        var engine  = options.engine;
        //console.log(this.params.fitmentSteps);
        //console.log("year %o, make %o, model %o, engine %o",year,make,model,engine);

        // URI encode the whole string
        year   = encodeURIComponent(year);
        make   = encodeURIComponent(make);
        model  = encodeURIComponent(model);
        engine = encodeURIComponent(engine);

        //alert('year: "'+year+'" make: "'+make+'" model: "'+model+'" engine: "'+engine+'"');
        //console.log("year / make / model / engine : %o / %o / %o / %o",year,make,model,engine);
        var params = [  { token: authToken, url: "/fitment/get_years",            data: "" },
                        { token: authToken, url: "/fitment/get_makes",            data: "year="+year },
                        { token: authToken, url: "/fitment/get_models",           data: "year="+year+"&make="+make },
                        { token: authToken, url: "/fitment/get_engines",          data: "year="+year+"&make="+make+"&model="+model  },
                        { token: authToken, url: "/fitment/get_fitment_details",  data: "year="+year+"&make="+make+"&model="+model+"&engine="+engine } ];
        jQuery.ajax({
          data: params[n].data+'&authenticity_token=' + encodeURIComponent(params[n].token),
          success: function(){ 
              self.dataComplete(options);
          },
          dataType:'script',
          type:'post',
          url: params[n].url
        });
    }
    this.init();
}

/* Fitment Questionnaire UI Utility */
function FitmentQuestionnaireUtil() {
    var self = this;
    this.init = function() {
      this.containerEl = $("#page").eq(0);
      this.stepContainerEls = false;
      this.stepProgressEls = false;
      this.progressRefs = { results:      "#progress_results",
                            fitment_menu: "#progress_fitment",
                            stepNav:      ".stepNavProgress",
                            fitmentSteps: { 1: { flyout: "#fitment_progress_flyout",
                                                 preset: "#fitment_progress_preset_1"},
                                            2: { flyout: "#fitment_progress_flyout",
                                                 preset: "#fitment_progress_preset_2"},
                                            3: { flyout: "#fitment_progress_flyout",
                                                 preset: "#fitment_progress_preset_3"},
                                            4: { flyout: "#fitment_progress_flyout",
                                                 preset: "#fitment_progress_preset_4"}}};
      this.progressSteps = [ ];
      /* continue only if fitment UI is present */
      if ($(this.containerEl).hasClass("batterySelector")) {
        this.stepContainerEls = $(this.containerEl).find("div.steps");
        this.mapEl = $("#map");
        this.pinEl = $("#pin");
        this.mapInputNorthEl = $("#fitment_map_north");
        this.mapInputMidEl = $("#fitment_map_mid");
        this.mapInputSouthEl = $("#fitment_map_south");
        this.driveFrequencyEls = $(".timesDriven input[type=radio]");
        this.deviceUsageEls = $(".accessories input[type=checkbox]");
        this.progressEl = $("#batteryControl");
        this.progressSteps = [ { domEl: $("#batteryControl > ul > li.stepOne") },
                               { domEl: $("#batteryControl > ul > li.stepTwo") },
                               { domEl: $("#batteryControl > ul > li.stepThree") },
                               { domEl: $("#batteryControl > ul > li.stepFour") } ];
        /* capture original text content from each nav step for re-output later */
        for (i=0, j=this.progressSteps.length; i<j; i++) {
          var sp = this.progressSteps[i];
          sp.origContent = $(sp.domEl).find("a").html();
        }
        this.fitmentClearEl = $("#selectorResults .clearResults a");
        this.seeCurrentResultsEls = $(".steps a.current");
        this.seeFinalResultsEl = $(".stepFour a.continue");
        this.fitmentTokenEl = $("#selectorResults input:hidden");
        this.fitmentSteps = [ { buttonEl:   $("#automobileSelector li#select_year a"),
                                lightboxEl: $("#selectYear"),
                                resultEl:   $("#selectorResults li#results_year"),
                                resultLeadingSpace: false },

                              { buttonEl:   $("#automobileSelector li#select_make a"),
                                lightboxEl: $("#selectMake"),
                                resultEl:   $("#selectorResults li#results_make"),
                                resultLeadingSpace: false },

                              { buttonEl:   $("#automobileSelector li#select_model a"),
                                lightboxEl: $("#selectModel"),
                                resultEl:   $("#selectorResults li#results_model"),
                                resultLeadingSpace: false },

                              { buttonEl:   $("#automobileSelector li#select_engine a"),
                                lightboxEl: $("#selectEngine"),
                                resultEl:   $("#selectorResults li#results_engine"),
                                resultLeadingSpace: false } ];
        this.productResultsEl  = $("#product_details");
        this.sortedResultsEl   = $("#resultsSorted");
        this.unsortedResultsEl = $("#resultsUnsorted");
        this.productResultsRef  = "#product_details";
        this.sortedResultsRef   = "#resultsSorted";
        this.unsortedResultsRef = "#resultsUnsorted";
        this.resultTotalRef = ".pagination .preamble .num";
        /* Skip this buttons */
        this.skipLinks = $("a.skip");
        this.params = { fitmentSteps:   [ { key: "year", value: "" },
                                          { key: "make", value: "" },
                                          { key: "model", value: "" },
                                          { key: "engine", value: "" } ],
                        steps:          { key: "step",    value: false },
                        seeResults:     { key: "results", value: false }, 
                        skipThis:       { key: "skip",    value: false }, 
                        region:         { key: "region",  value: false },
                        driveFrequency: { key: "freq",    value: false },
                        deviceUsage:    { key: "devices", value: false } 
        };
        this.queryStr = window.location.search.toString();
        this.queryEls = [ ];
        this.readQueryString();
        this.loadPresetData();
        this.setForm();
        if (this.params.seeResults.value || this.params.steps.value) {
            //this.goToStep(5);
        } else {
            this.goToStep(1);
            this.fitmentEnableStep(1); 
        }
        this.continueButtonEvents();
        this.seeCurrentResultsEvent();
        this.setupMapPin();
        this.mapClickEvent();
        this.activateGetModelNumber();
      }
    }
    // Skip this I already know my model number
    this.activateGetModelNumber = function() {
        $(this.skipLinks).click(function(){
           // self.disableContinue();
           autoSelector("#selectModelNumber", this);
           var collection = [];
           $(self.seeCurrentResultsEls).each(function(){ collection.push(this)});
           collection.push(self.seeFinalResultsEl);
           collection.push(self.fitmentClearEl);
           $(".steps .continue").each(function(){ collection.push(this)});
           $(self.progressSteps).each(function(){ collection.push(this.domEl)});
           
           for (var i=0, j=collection.length; i<j; i++){
                $(collection[i]).click(function() {
                       hidebox("#selectModelNumber");
                       $(collection[i]).unbind("click");
                   });
           } 
        });
    }
    this.batteryModelNumberClick = function(model) {
        //console.log("batteryModelNumberClick(%o), model el %o",model,$("#"+model));
        this.readForm();
        this.params.skipThis.value = model;
        this.params.seeResults.value = true;
        var queries = [ ];
        queries.push(this.params.seeResults);
        if (this.currentStep >= 1) {
            for (var i=0, j=this.params.fitmentSteps.length; i<j; i++) {
                queries.push(this.params.fitmentSteps[i]);
            }
        }
        queries.push(this.params.skipThis);
        if ((this.currentStep >= 2) && (this.params.region.value)) {
            //console.log("push region %o",this.params.region);
            queries.push(this.params.region);
        }
        if ((this.currentStep >= 3) && (this.params.driveFrequency.value)) {
            queries.push(this.params.driveFrequency);
        }
        if ((this.currentStep >= 4) && (this.params.deviceUsage.value)) {
            queries.push(this.params.deviceUsage);
        }
        this.addQuery(queries);
    }
    this.readForm = function() {
        //console.log('readForm()...');

        // set region North/Middle/South based on hidden radios behind Step 2 map
        var north = $(this.mapInputNorthEl).attr("checked");
        var mid = $(this.mapInputMidEl).attr("checked");
        var south = $(this.mapInputSouthEl).attr("checked");
        //console.log("readForm(): read north %o, mid %o",north,mid);
        if (north) {
            this.params.region.value = "n";
        } else if (mid) {
            this.params.region.value = "m";
        } else if (south) {
            this.params.region.value = "s";
        } else {
            this.params.region.value = false;
        }

        // set driving frequency based on radios behind Step 3 graphical buttons
        $(this.driveFrequencyEls).each(function(){
            //console.log("drive freq el %o checked",this.checked);
            if (this.checked) {
                self.params.driveFrequency.value = this.value;
            }
        });

        // set device usage based on checkboxes behind Step 4 graphical buttons
        this.params.deviceUsage.value = 0;
        $(this.deviceUsageEls).each(function(){
            //console.log("device usage el %o",this);
            var paren = $(this).parent();
            var parenChecked = $(paren).hasClass("checked");
            var checked = $(this).attr("checked");
            if (parenChecked && !checked) {
                checked = true; //IE6 fix: override unchecked radios if faux form parent is "checked"
            }
            if (checked) {
                self.params.deviceUsage.value++;
            }
        });
        //console.log("readForm(): resultant params region %o,\ndrive frequency %o,\ndevice usage %o",this.params.region,this.params.driveFrequency,this.params.deviceUsage);
    }
    this.setForm = function() {
        //console.log("setForm()...");
        var step_2_pin = decodeURIComponent(readCookie('fitment_optional_2_pin'));
        var step_2_result = decodeURIComponent(readCookie('fitment_optional_2_result'));
        var step_3 = decodeURIComponent(readCookie('fitment_optional_3'));
        var step_4 = decodeURIComponent(readCookie('fitment_optional_4'));
        if (step_2_pin) {
            //console.log("step_2_pin %o",step_2_pin);
            var coords = step_2_pin.split(",");
            //console.log("coords %o, pin el %o",coords,this.pinEl);
            if (coords && coords.length == 2) {
                $(this.pinEl).css("top",coords[0]+"px");
                $(this.pinEl).css("left",coords[1]+"px");
                this.pinDrop({ top: coords[0], left: coords[1] });
            }
        }
        if (step_3) {
            for (var i=0, j=this.driveFrequencyEls.length; i<j; i++){
                var target = this.driveFrequencyEls[i];
                //console.log("step 3 %o, el %o, i %o",step_3,target,i)
                if (i == step_3) {
                    target.checked = true;
                    $(target).parent().addClass("checked");
                } else {
                    $(target).parent().removeClass("checked");
                }
            }
        }
        if (step_4) {
            var checkStates = step_4.split("_");
            for (var i=0, j=checkStates.length; i<j; i++){
                var target = this.deviceUsageEls[i];
                //console.log("step 4 %o, el %o, checked %o, i %o",step_4,target,target.checked,i)
                if (checkStates[i] === "1") {
                    target.checked = true;
                    $(target).parent().addClass("checked");
                } else if (checkStates[i] == "0") {
                    target.checked = false;
                    $(target).parent().removeClass("checked");
                }
            }
        }
    }
    this.splitQueryString = function() {
        var split = this.queryStr.substring(1,this.queryStr.length).split("&");
        if (split != "") {
            this.queryEls = split;
        }
        //console.log("splitQueryString(): now have self.queryEls as %a",this.queryEls);
    }
    this.clearQuery = function() {
        this.queryEls = [];
    }
    // removes string 'key' from from the query string in URL
    // causes page re-load
    this.removeQuery = function(keyArray,options) {
        //console.log('removeQuery("%o")...',keyArray);
        var removeKey = "";
        for (i=0, j=keyArray.length; i<j; i++) {
            //console.log("removeQuery(): check over this.queryEls %o",this.queryEls);
            for (s=0, t=this.queryEls.length; s<t; s++) {
                var query = this.queryEls[s];
                var keyIdx = query.indexOf(keyArray[i]);
                if (keyIdx != -1) {
                    //console.log('removeQuery(): removing %o, found key at index %o in %o',keyArray[i],keyIdx,query);
                    removeKey = s;
                }
            }
            if ((removeKey === "")) {
                //console.log('see removeKey "%s" as not being numeric! not removing...',removeKey);
            } else {
                var index = removeKey;
                //console.log("splice index: %o",index);
                this.queryEls.splice(index,1);
                //this.queryEls = newEls;
                //console.log('removeQuery("%o"): updated this.queryEls %o',keyArray[i],this.queryEls);
            }
        }
        if (options && options.skipLocationRewrite) {
        } else {
            this.writeQueryString();
        }
    }
    // writes a key,val pair into the query string in URL
    // addObj: { "key":key,"value":value }, where key and value are
    //           strings representing URL query format '?key=value
    // causes page re-load
    this.addQuery = function(addObjArray) {
        //console.log("addQuery(%o)",addObjArray);
        for (var i=0, j=addObjArray.length; i<j; i++) {
            // load current query into self.QueryEls array
            //self.splitQueryString();
            var matched = false;
            var value = encodeURIComponent(addObjArray[i].value);
            if (this.queryEls.length > 0) {
                for (k=0, l=this.queryEls.length; k<l; k++) {
                    var writeIdx = this.queryEls[k].indexOf(addObjArray[i].key);
                    if (writeIdx != -1) {
                        //console.log("addQuery: match to key '%s', writing...",addObjArray[i].key);
                        this.queryEls[k] = addObjArray[i].key + "=" + value;
                        matched = true;
                    }
                }
                if (matched == false) {
                    this.queryEls.push(addObjArray[i].key + "=" + value);
                }
            } else {
                this.queryEls = Array(addObjArray[i].key + "=" + value);
            }
        }
        this.writeQueryString();
    }
    // causes page re-load
    this.writeQueryString = function() {
        //console.log("writeQueryString: using this.queryEls as %o",this.queryEls);
        var newQueryStr = "?" + this.queryEls.join("&");
        // prefer url without ? for empty query
        newQueryString = (newQueryStr === "?") ? "" : newQueryStr;
        var oldQueryStr = window.location.search.toString();
        // avoid race condition where re-load via window.location for
        // same search string
        if (newQueryStr === "?") {
            var protocol = window.location.protocol;
            var port     = (window.location.port != "") ? ":"+window.location.port : "";
            var path     = window.location.pathname;
            var hostname = window.location.hostname;
            var hash     = window.location.hash;
            var newLocation = protocol + "//" + hostname + port + path + hash;
            //alert("setting new location "+newLocation);
            //console.log("setting new location %o",newLocation);
            window.location = newLocation;
        } else if (newQueryStr != oldQueryStr) {
            //alert("setting new query"+newQueryStr);
            //console.log("setting new location query %o",newQueryStr);
            window.location.search = newQueryStr;
        }
    }
    this.readQueryString = function() {
        // load current query into self.QueryEls array
        this.splitQueryString();
        //console.log("have this.queryEls %o, length '%o'",this.queryEls,this.queryEls.length);
        for (i=0, j=this.queryEls.length; i<j; i++) {
            var query = this.queryEls[i];
            //console.log("working over this.queryEls, query: %o",query);
            // fitment queries 
            for (var n=0, p=this.params.fitmentSteps.length; n<p; n++) {
                this.pullSingleQuery(query,this.params.fitmentSteps[n]);
            }

            // overall step results query
            this.pullSingleQuery(query,this.params.steps);
            // force step results to numerical rather than string 
            this.params.steps.value = (+this.params.steps.value);

            // show results query
            this.pullSingleQuery(query,this.params.seeResults);

            // skip this have model number query
            this.pullSingleQuery(query,this.params.skipThis);

            // region north/mid/south query
            this.pullSingleQuery(query,this.params.region);

            // driving frequency query
            this.pullSingleQuery(query,this.params.driveFrequency);
            // force booleans for sane comparison later
            if (this.params.driveFrequency === "true") { 
                this.params.driveFrequency = true;
            }
            if (this.params.driveFrequency === "false") { 
                this.params.driveFrequency = false;
            }
            // device usage query
            this.pullSingleQuery(query,this.params.deviceUsage);
            this.params.deviceUsage.value = (+this.params.deviceUsage.value);
        }
    }
    this.pullSingleQuery = function(query,queryObj) {
        //console.log("pullSingleQuery(%o,%o)...",query,queryObj);
        var index = query.indexOf(queryObj.key);
        if (index != -1) {
            var rangeStart = index + queryObj.key.length + 1;
            var rangeLength = query.length;
            queryObj.value = decodeURIComponent(query.substring(rangeStart,rangeLength));
            //console.log("pullSingleQuery(): stored new value %o for query property %o",queryObj.value,queryObj);
        }
    }
    this.continueButtonEvents = function() {
      var btnContinue;
      var btnResults;
      for (var i=0, j=this.stepContainerEls.length; i<j; i++) {
        btnContinue = $(this.stepContainerEls[i]).find(".continue");
        btnResults = $(this.stepContainerEls[i]).find(".current");
        //console.log("registering click handler for continue button %o",btnContinue);
        $(btnContinue).click(function(e){ 
            //console.log("clicked %o",this);
            if (!$(this).hasClass("finalResults")) {
                self.goToNextStep(); 
            }
            e.preventDefault();
        });
        //$(btnResults).show();
      }
    }
    this.fitmentClearAllClick = function() {
        //console.log("fitmentClearAllClick()...");
        this.clearFitmentCookies();
        // causes page re-load
        this.removeQuery(["results","year","make","model","engine","region","freq","devices"]);
        //this.goToStep(1);
        //this.fitmentEnableStep(1); 
        //this.fitmentClearAllUI();
    }
    this.fitmentClearAllUI = function() {
      for (var i=0, j=this.fitmentSteps.length; i<j; i++) {
          //console.log(this.fitmentSteps[i].resultEl);
          $(this.fitmentSteps[i].resultEl).removeClass("complete");
          $(this.fitmentSteps[i].resultEl).find("span").text("");
          $(this.fitmentSteps[i].resultEl).hide();
      }
    }
    this.seeCurrentResultsEvent = function() {
      //console.log("seeCurrentResultsEvent()...");
      $(this.seeCurrentResultsEls).click(function(e){ 
          //console.log("see current results click, event: %o, DOM obj %o",e,this);
          self.resultsClick(this);
          e.preventDefault();
      });
      $(this.seeFinalResultsEl).click(function(e){ 
          //console.log("see final results click, event: %o, DOM obj %o",e,this);
          self.resultsClick(this);
          e.preventDefault();
      });
    }
    this.resultsClick = function(clicked) {
        //console.log("resultsClick(%o)... self %o, this %o",clicked,self,this);
        this.saveOptionalStep();
        this.params.seeResults.value = true;
        this.readForm();
        var fitmentQueries = [  this.params.fitmentSteps[0],
                                this.params.fitmentSteps[1],
                                this.params.fitmentSteps[2],
                                this.params.fitmentSteps[3] ];
        var closest = $(clicked).closest("div.steps");
        var buttonInStep2 = $(closest).hasClass("stepTwo");
        var buttonInStep3 = $(closest).hasClass("stepThree");
        var buttonInStep4 = $(closest).hasClass("stepFour");
        //console.log("seeCurrentResultsClick: have closest as %o",closest);
        //console.log("working with params %o",this.params);
        if (this.params.region.value && (buttonInStep2 || buttonInStep3 || buttonInStep4)) {
          fitmentQueries.push(this.params.region);
        }
        if (this.params.driveFrequency.value && (buttonInStep3 || buttonInStep4)) {
          fitmentQueries.push(this.params.driveFrequency);
        }
        if (this.params.deviceUsage.value && buttonInStep4) {
          fitmentQueries.push(this.params.deviceUsage);
        }
        fitmentQueries.push(this.params.seeResults);
        this.addQuery(fitmentQueries);
    }
    this.fitmentEnableStep = function(step) {
      //console.log("fitmentEnableStep(%o)",step);
      this.fitmentDisableAll();
      var n = +(step-1);
      if (n == 0) {
        this.fitmentDisableClearAll();
      } else {
        this.fitmentEnableClearAll();
      }
      for (i=0, j=step; i<j; i++) {
          //console.log("enable %o",i);
          var btn = $(this.fitmentSteps[i].buttonEl);
          //console.log("fitmentEnableStep(): have button %o",btn);
           $(this.fitmentSteps[i].buttonEl).click(function(iScoped){
              return function(){
                //console.log("button clicked %o, i: %o",this,iScoped);
                self.fitmentStepClick(iScoped+1);
              };
           }(i)); 
           var parentEl = $(this.fitmentSteps[i].buttonEl).parent();
           $(parentEl).removeClass("inactive");
      }
    }
    this.fitmentStepClick = function(step) {
      //console.log("fitmentStepClick(%o)..",step);
      var n = +(step-1);
      var id = $(self.fitmentSteps[n].lightboxEl).attr("id");
      // hide fitment results UI
      for (var i=0, j=self.fitmentSteps.length; i<j; i++) {
        $(self.fitmentSteps[i].resultEl).css("visibility","hidden");
        $(self.fitmentSteps[i].resultEl).find("span").css("visibility","hidden");
      }
      // disable continue to Battery Selector Step 2
      self.disableContinue(1);
      autoSelector('#'+id,this);
    }
    this.dataStart = function(options) {
      var n = +(options.step-1);
      //console.log("dataStart(%o)...",options);
      if (options.step < 5) {
          if (options.isClickAction) {
              //console.log("toggle progress step %o ON for fitment data via *click*",options.step);
              this.toggleProgress("fitment_flyout_"+options.step);
          } else {
              //console.log("toggle progress step %o ON for fitment data via preset",options.step);
              this.toggleProgress("fitment_preset_"+options.step);
          }
      }
    }
    this.dataComplete = function(options) {
      //console.log("dataComplete(%o)",options);
      var step = options.step;
      var n = +(step-1);
      // add click to links in selection overlay and then show
      if (n < 4) {
        var id = $(this.fitmentSteps[n].lightboxEl).attr("id");
        this.groupResults(step);
        this.activateFitmentLinks(n);
        this.fitmentEnableStep(step); 
        if (options.isClickAction) {
          // continue click flow, pop selection box for next fitment
          //console.log("toggle progress step %o off for fitment flyout *click* complete",options.step);
          this.toggleProgress("fitment_flyout_"+options.step);
          autoSelector('#'+id,this);
        } else {
          // contine presets flow, load the preset for the next step
          if (this.selectorStepOneComplete) {
              this.fitmentResultEqualHeights();
              this.loadPresetFitment(step+1,this.preset_data[step]);
          }
          //console.log("toggle progress step %o off for fitment via preset",options.step);
          this.toggleProgress("fitment_preset_"+options.step);
        }
      // fitment complete, close the selector box from the last step 
      // and enable continue from Fitment to Battery Selector Step 2
      // also request product details 
      } else {
        //console.log("dataComplete(): fitment complete, getting product results");
        //console.log("this.params %o, this.preset_data %o",this.params,this.preset_data);
        var idx = n-1;
        //console.log("++ idx: %o",idx);
        $(this.fitmentSteps[idx].lightboxEl).fadeOut("fast");

        this.getCurrentResults(options);
      }
    }
    this.groupResults = function(step) {
      var n = +(step-1);
      var dataContainerEl = $(this.fitmentSteps[n].lightboxEl).find("ul.dataContainer").eq(0);
      var listEls = $(dataContainerEl).find("li");
      var groupEls = $(this.fitmentSteps[n].lightboxEl).find("ul.selectGroup");
      var parentEl = $(dataContainerEl).parent();
      $(groupEls).remove();
      /* group results into 3 columns for fitment step 3 *
       * and 4 columns for steps 1, 2 and 4              */
      var cols = (step == 3) ? 3 : 4;
      var thresholdRaw = listEls.length / cols;
      var threshold = Math.floor(listEls.length / cols);
      var remainder = thresholdRaw - threshold;
      if (remainder > 0) {
        threshold += 1;
        thresholdRaw += 1;
      }
      var html = [ ];
      html.push('<ul class="first selectGroup">'); 
      for (i=0, j=listEls.length; i<j; i++) {
        //console.log("groupResults(): cols %o, count %o, thresholdRaw %o, threshold %o, i %o",cols,j,thresholdRaw,threshold,i);
        if (remainder > 0) {
          /* with an un-evenly divisible ratio of links / cols, we shift *
           * the remainder in favor of columns to the left.              */
          //console.log("shifted threshold %o and thresholdRaw %o",threshold,thresholdRaw);
          if ((i >= threshold) && (i < thresholdRaw)) {
            //console.log("++ this i %o seems to meet threshold REMAINDER",i);
            html.push('</ul>\n<ul class="selectGroup">');
          } else if ((i > thresholdRaw) && (i % (threshold) == 0)) {
            //console.log("++ this i %o seems to meet threshold REMAINDER",i);
            html.push('</ul>\n<ul class="selectGroup">');
          }
        } else {
          if ((i >= threshold) && (i % threshold == 0)) {
            //console.log("++ this i %o seems to meet threshold",i);
            html.push('</ul>\n<ul class="selectGroup">');
          }
        }
        link = $(listEls[i]).html();
        html.push("<li>" + link + "</li>");
      }
      html.push("</ul>"); 
      var joined = html.join("\n");
      $(parentEl).prepend(joined);
    }
    this.activateFitmentLinks = function(step){
      //console.log("activateFitmentLinks(%o)",step);
      var links = $(this.fitmentSteps[step].lightboxEl).find("ul.selectGroup > li > a");
      for (var i=0, j=links.length; i<j; i++) {
        $(links[i]).click(function(stepScoped,clicked){ 
          return function(e) { 
              self.fitmentSelectionClick(stepScoped,clicked); 
              e.preventDefault();
          };
        }(step,links[i]));
      }
    }
    this.fitmentSelectionClick = function(step,clicked) {
      //console.log("fitmentSelectionClick(%o), btn as %o...",step,clicked);

      // get fitment value
      var content = $(clicked).attr("rel");
      this.fitmentSteps[step].resultData = content;

      // save fitment query params
      //console.log("saving %o to %o",content,this.params.fitmentSteps[step]);
      this.params.fitmentSteps[step].value = content;

      // write the value chosen into the result element
      var resultEl = $(this.fitmentSteps[step].resultEl);
      $(resultEl).html("<span>"+content+"</span>");

      var nextStep = step+2;
      if (nextStep < 5) { 

        // this is not last step, enable the next fitment step
        this.clearFitmentCookies();
        this.fitmentEnableStep(nextStep);

      } else {

        // this was the last step, save fitment to cookies
        this.saveFitmentCookies();

        // form and dispatch Omniture event tracking call for a fitment
        this.fitmentSelectionOmEvent(step,clicked);

        // call the next step, get_fitment_details
        this.dataComplete({ step: 5, isClickAction: true })

      }
      // show or hide the result element according to fitment progress
      // also clear the result on hide
      for (var i=0, j=this.fitmentSteps.length; i<j; i++) {
        var threshold = step+1;
        if (i < threshold) {
          $(this.fitmentSteps[i].resultEl).addClass("complete");
          this.fitmentShowResult(i+1);
        } else {
          $(this.fitmentSteps[i].resultEl).removeClass("complete");
          $(this.fitmentSteps[i].resultEl).find("span").text("");
        }
      }
      // do adjust fitment result elements for equal heights, like table cells
      this.fitmentResultEqualHeights();
    }
    this.fitmentSelectionOmEvent = function(step,clicked) {
        //console.log("fitmentSelectionOmEvent()...");
        var eVarData = [];
        for (var i=0, j=this.params.fitmentSteps.length; i<j; i++) {
            var fitVal = this.params.fitmentSteps[i].value;
            if (fitVal && fitVal != "") {
                eVarData.push(fitVal);
            }
        }
        var eVarStr = eVarData.join(" ");
        //console.log("eVarStr %o",eVarStr);
        eVarStr = eVarStr.replace(/&amp;/,"and");
        eVarStr = eVarStr.replace(/&/," and ");
        //console.log("...after replace %o",eVarStr);
        doOmnitureEvent({ pageName: "Battery Selector > Vehicle", 
                          channel: "Battery Selector", 
                          linkName: this.params.fitmentSteps[step].value,
                          clicked: clicked, 
                          eVar7: eVarStr, 
                          linkTrackOptionalVars: "eVar7" });
    }
    this.addFitmentToQuery = function() {
        // also save fitment to URL query location 
        this.addQuery([ this.params.fitmentSteps[0], 
                        this.params.fitmentSteps[1],
                        this.params.fitmentSteps[2],
                        this.params.fitmentSteps[3] ]);
    }
    this.fitmentShowResult = function(step) {
      //console.log("fitmentShowResult(%o)..",step);
      var n = step-1;
      $(this.fitmentSteps[n].resultEl).css("visibility","");
      $(this.fitmentSteps[n].resultEl).find("span").css("visibility","");
      $(this.fitmentSteps[n].resultEl).show();
    }
    this.saveFitmentCookies = function() {
      for (var i=0, j=self.fitmentSteps.length; i<j; i++) {
        var content = self.fitmentSteps[i].resultData;
        //console.log("saveFitmentCookies(): for i %o, content '%o'",i,content);
        createCookie('fitment_selection_'+i, encodeURIComponent(content), '')
      }
    }
    this.clearFitmentCookies = function() {
      for (var i=0, j=self.fitmentSteps.length; i<j; i++) {
        createCookie('fitment_selection_'+i, '', '')
      }
    }
    this.loadPresetData = function() {
        this.preset_data = [];
        var data = "";
        var preferUrlParamsOverCookie = false;
        for (var i=0, j=this.params.fitmentSteps.length; i<j; i++) {
            if (this.params.fitmentSteps[i].value != "") {
              preferUrlParamsOverCookie = true;
            }
        }
        //console.log("loadPresetData(): preferUrlParamsOverCookie %o",preferUrlParamsOverCookie);
        for (var i=0, j=this.params.fitmentSteps.length; i<j; i++) {
            if (preferUrlParamsOverCookie) {
                data = this.params.fitmentSteps[i].value; 
            } else {
                data = decodeURIComponent(readCookie('fitment_selection_'+i));
            }
            // check for invalid cookie data
            if ((data === "undefined") || (data === "" )) {
                this.preset_data.push("null");
            } else {
                this.preset_data.push(data);
                var target = $(this.fitmentSteps[i].resultEl).find("span").eq(0);
                $(target).text(data);
            }
        }
        this.selectorStepOneComplete = true;
        for (var i=0, j=this.preset_data.length; i<j; i++){
            if (this.preset_data[i] === "null") {
                this.selectorStepOneComplete  = false;
            }
        }

        //this.fitmentResultEqualHeights();
        if (this.selectorStepOneComplete && this.params.seeResults.value) {
          //console.log("selector step one complete, getting results page");
            for (var i=0, j=this.preset_data.length; i<j; i++){
                this.params.fitmentSteps[i].value = this.preset_data[i];
            }
            this.goToStep(5);
            this.toggleProgress("results");
            this.loadFitmentResults();
        } else if (this.selectorStepOneComplete) {
          //console.log("selector step one complete, going to page %o",this.params.steps.value);
            if (this.params.steps.value) {
                this.goToStep(this.params.steps.value);
            } else { 
                this.goToStep(1);
            }
            this.disableContinueAll();
            for (var i=1, j=this.params.steps.value; i<j; i++) {
                this.enableContinue(i);
            }
            this.loadPresetFitment(1,this.preset_data[0]);
        } else {
          //console.log("no fitment, setup for default");
            // setup first Fitment button via get_years
            this.getFitmentData({ step: 1, isClickAction: false });
        }

    }
    this.loadFitmentResults = function() {
        this.getFitmentData({ step: 5, isClickAction: false });
    }
    this.loadPresetFitment = function(step,data) {
        //console.log("loadPresetFitment(%o,%o)",step,data);
        var n = step-1;
        if (step < 5) {
            this.params.fitmentSteps[n].value = data;
            this.fitmentShowResult(step);            
        }
        this.getFitmentData({ step: step, isClickAction: false });
        //this.fitmentEnableStep(n); 
    }
    this.fitmentEnableClearAll = function() {
        $(this.fitmentClearEl).unbind("click");
        $(this.fitmentClearEl).click(function(e){
            self.fitmentClearAllClick();
            e.preventDefault();
        });
        $(this.fitmentClearEl).show();
    }
    this.fitmentDisableClearAll = function() {
        $(this.fitmentClearEl).hide();
        $(this.fitmentClearEl).unbind("click");
    }
    this.fitmentDisableAll = function() {
      for (i=0, j=this.fitmentSteps.length; i<j; i++) {
           $(this.fitmentSteps[i].buttonEl).unbind("click"); 
           var parentEl = $(this.fitmentSteps[i].buttonEl).parent();
           $(parentEl).addClass("inactive")
           //$(this.fitmentSteps[i].resultEl).hide();
           $(this.fitmentSteps[i].lightboxEl).hide();
      }
      this.disableContinue(1);
      this.disableSkip(1);
    }
    this.getFitmentData = function(options) {
        //console.log("getFitmentData(%o)...",options);
        var n = options.step-1;
        var authToken = window._token;
        //console.log("getFitmentData(): leading space for year? %o; make? %o; model? %o; engine? %o",this.fitmentSteps[0].resultLeadingSpace,this.fitmentSteps[1].resultLeadingSpace,this.fitmentSteps[2].resultLeadingSpace,this.fitmentSteps[3].resultLeadingSpace);

        // get fitment from params
        var year   = this.params.fitmentSteps[0].value;
        var make   = this.params.fitmentSteps[1].value;
        var model  = this.params.fitmentSteps[2].value;
        var engine = this.params.fitmentSteps[3].value;
        //console.log(this.params.fitmentSteps);

        // URI encode the whole string
        year   = encodeURIComponent(year);
        make   = encodeURIComponent(make);
        model  = encodeURIComponent(model);
        engine = encodeURIComponent(engine);

        //alert('year: "'+year+'" make: "'+make+'" model: "'+model+'" engine: "'+engine+'"');
        //console.log("year / make / model / engine : %o / %o / %o / %o",year,make,model,engine);
        var params = [  { token: authToken, url: "/fitment/get_years",            data: "" },
                        { token: authToken, url: "/fitment/get_makes",            data: "year="+year },
                        { token: authToken, url: "/fitment/get_models",           data: "year="+year+"&make="+make },
                        { token: authToken, url: "/fitment/get_engines",          data: "year="+year+"&make="+make+"&model="+model  },
                        { token: authToken, url: "/fitment/get_fitment_details",  data: "year="+year+"&make="+make+"&model="+model+"&engine="+engine } ];
        //console.log("toggle progress? step %o, params.steps.value %o",step,this.params.steps.value);
        if (options.step == 5) {
            this.toggleProgress("steps_nav");
        } else {
          //console.log("toggle progress on for fitment");
        }
        this.dataStart(options);
        jQuery.ajax({
          data: params[n].data+'&authenticity_token=' + encodeURIComponent(params[n].token),
          success: function(){ 
              if (options.step < 5) { 
                self.fitmentDataComplete(options.step);
              } else {
                self.productDataComplete();
              }
          },
          dataType:'script',
          type:'post',
          url: params[n].url
        });
    }
    this.fitmentDataComplete = function(step) {
      //console.log("fitmentDataComplete(%o)",step);
      this.dataComplete({ step: step, isClickAction: false });
    }
    this.getCurrentResults = function(options){
        //console.log("getCurrentResults(%o)",options);
        //options.step = 5;
        this.getFitmentData(options);
    }
    this.productDataComplete = function() {
        //console.log("productDataComplete()...");
        if (this.params.seeResults.value) {
            this.productSort();
            this.applySkipToModel();
            this.goToStep(5);
            this.toggleProgress("results");
        } else if (this.params.steps.value) {
            this.enableContinue(this.params.steps.value);
            this.toggleProgress("steps_nav");
            //this.goToStep(this.params.steps.value);
        } else {
            this.toggleProgress("steps_nav");
        }
        // If the 
        if (!(this.productResultsCount == 0)) {
            this.enableSkip();
        }
    }
    this.applySkipToModel = function() {
        //console.log("applySkipToModel(): params.skipThis",this.params.skipThis);
        if (this.params.skipThis.value) {
            var model = this.params.skipThis.value;
            var resultEls = $(this.unsortedResultsRef).children("ul").children("li");
            var target = $("#resultsSorted > ul");

            $(target).children("li").removeClass("featured");
            $("#"+model).addClass("featured");
            $("#"+model).prependTo(target);
        }
    }
    this.productSort = function() {
        //console.log("productSort()...");
        //console.log("region %o\ndrive freq %o\ndevices used %o",this.params.region.value,this.params.driveFrequency.value,this.params.deviceUsage.value);
        // iterate over results hash to get count
        //var resultCount = 0;
        //for (var i in this.productResults) {
        //  resultCount++;
        //}
        var resultCount = this.productResults.length;

        //console.log("setting up sort, have products map %o",this.productResults);
        this.activeSortModel = false;
        this.sortModelsAll = {  step_1_default: [ "p",  "gn", "gs", "n",  "s" ],//default
                                step_2_north:   [ "p",  "gn", "n",  "gs", "s" ],//prefer platinum, then north 
                                step_2_mid:     [ "p",  "gn", "gs", "n",  "s" ],//prefer platinum, then gold 
                                step_2_south:   [ "p",  "gs", "s",  "gn", "n" ],//prefer platinum, then south

                                step_3_low_n:   [ "p",  "gn", "n",  "gs", "s" ],//prefer platinum, then north
                                step_3_low_m:   [ "p",  "gn", "gs", "n",  "s" ],//prefer platinum, then gold, then north *default*
                                step_3_low_s:   [ "p",  "gs", "s",  "gn", "n" ],//prefer platinum, then south

                                step_3_high_n:  [ "gn", "n",  "p",  "gs", "s" ],//prefer north, then gold, then platinum
                                step_3_high_m:  [ "gn", "gs", "p",  "n",  "s" ],//prefer gold, then platinum, then north
                                step_3_high_s:  [ "gs", "s",  "p",  "gn", "n" ],//prefer south, then gold, then platinum

                                step_4_low_n:   [ "p",  "gn", "n",  "gs", "s" ],//prefer platinum, then north, then gold
                                step_4_low_m:   [ "p",  "gn", "gs", "n",  "s" ],//prefer platinum, then gold, then north
                                step_4_low_s:   [ "p",  "gs", "s",  "gn", "n" ],//prefer platinum, then south, then gold

                                step_4_med_n:   [ "gn", "p",  "n",  "gs", "s" ],//prefer north, then gold, then platinum
                                step_4_med_m:   [ "gn", "gs", "p",  "n",  "s" ],//prefer gold, then platinum, then north
                                step_4_med_s:   [ "gs", "p",  "s",  "gn", "n" ],//prefer south, then gold, then platinum  

                                step_4_high_n:  [ "n",  "gn", "s",  "gs", "p" ],//prefer north, then standard, then gold, then platinum
                                step_4_high_m:  [ "n",  "s",  "gn", "gs", "p" ],//prefer standard, then gold, then platinum then north
                                step_4_high_s:  [ "s",  "gs", "n",  "gn", "p" ] //prefer south, then standard, then gold, then platinum
                            };
        this.sortModels =   { region: { n: this.sortModelsAll.step_2_north,
                                        m: this.sortModelsAll.step_2_mid,
                                        s: this.sortModelsAll.step_2_south },
                              freq:   { zero:     { n: this.sortModelsAll.step_3_low_n,
                                                    m: this.sortModelsAll.step_3_low_m,
                                                    s: this.sortModelsAll.step_3_low_s },
                                        four:     { n: this.sortModelsAll.step_3_low_n,
                                                    m: this.sortModelsAll.step_3_low_m,
                                                    s: this.sortModelsAll.step_3_low_s },
                                        seven:    { n: this.sortModelsAll.step_3_high_n,
                                                    m: this.sortModelsAll.step_3_high_m,
                                                    s: this.sortModelsAll.step_3_high_s },
                                        tenPlus:  { n: this.sortModelsAll.step_3_high_n,
                                                    m: this.sortModelsAll.step_3_high_m,
                                                    s: this.sortModelsAll.step_3_high_s }},
                              devices:{ low:  { n: this.sortModelsAll.step_4_low_n,
                                                m: this.sortModelsAll.step_4_low_m,
                                                s: this.sortModelsAll.step_4_low_s },
                                        med:  { n: this.sortModelsAll.step_4_med_n,
                                                m: this.sortModelsAll.step_4_med_m,
                                                s: this.sortModelsAll.step_4_med_s },
                                        high: { n: this.sortModelsAll.step_4_high_n,
                                                m: this.sortModelsAll.step_4_high_m,
                                                s: this.sortModelsAll.step_4_high_s }}
                            };
        this.assignSortModel();
        this.mapSortToProducts();
        this.applySort();
    }
    this.assignSortModel = function() {
        // Assign weighting to Step 3+4 inputs according to UX fitment logic
        // for combined weight for choose sort model for step 4 case
        var driveWeights = {  zero:     1,
                              four:     2,
                              seven:    2,
                              tenPlus:  3 };
        var driveKey = this.params.driveFrequency.value;
        var deviceWeight = 0;
        if (this.params.deviceUsage.value < 3) {
            deviceWeight = 1; 
        } else if (this.params.deviceUsage.value < 9) {
            deviceWeight = 2; 
        } else {
            deviceWeight = 3; 
        }
        var freqDeviceWeight = driveWeights[driveKey] - deviceWeight;
        // assign a weight "class" for lookup in this.sortModels hash
        var combinedWeight = false;
        if (freqDeviceWeight < 0) {
            combinedWeight = "low";
        } else if (freqDeviceWeight < 2) {
            combinedWeight = "med";
        } else {
            combinedWeight = "high";
        }
        //console.log("assignSortModel(): calc combined weighting as %o, based on \"freq - devices = freqDeviceWeight\" => \"%o - %o = %o\"",combinedWeight,driveWeights[driveKey],deviceWeight,freqDeviceWeight);
        //console.log("active sort model: %o",this.activeSortModel);
        // Step 1 *only* completed
        if (!this.params.region.value) {
            this.activeSortModel = this.sortModelsAll.step_1_default;
            //console.log("assignSortModel(): using input from Step 2 %o chosen model is %o",this.params.region.value,this.activeSortModel);
        // All optional steps 2-4 for sort completed
        } else if (this.params.deviceUsage.value && this.params.driveFrequency.value) {
            this.activeSortModel = this.sortModels.devices[combinedWeight][this.params.region.value];
            //console.log("assignSortModel(): using inputs from Steps 2.: %o, 3.: %o and 4.: %o chosen model is %o",this.params.region.value,this.params.driveFrequency.value,this.params.deviceUsage.value,this.activeSortModel);
        // Step 2 and 3 completed
        } else if (this.params.driveFrequency.value) {
            this.activeSortModel = this.sortModels.freq[this.params.driveFrequency.value][this.params.region.value];
            //console.log("assignSortModel(): using inputs from Steps 2 %o and 3 %o chosen model is %o",this.params.region.value,this.params.driveFrequency.value,this.activeSortModel);
        // Step 2 completed
        } else if (this.params.region.value) {
            this.activeSortModel = this.sortModels.region[this.params.region.value];
            //console.log("assignSortModel(): using input from Step 2 %o chosen model is %o",this.params.region.value,this.activeSortModel);
        }
    }
    this.mapSortToProducts = function() {
        var newSort = [ ];
        var newItems = { };
        for (var i=0, j=this.activeSortModel.length; i<j; i++) {
            switch(this.activeSortModel[i]) {
                case "p":
                    //pull any product dom map matching platinum true
                    newItems = this.getProductResultObjsByAttr("P");
                    break;
                case "gn":
                    newItems = this.getProductResultObjsByAttr("G","N");
                    break;
                case "gs":
                    newItems = this.getProductResultObjsByAttr("G","S");
                    break;
                case "n":
                    newItems = this.getProductResultObjsByAttr("N");
                    break;
                case "s":
                    newItems = this.getProductResultObjsByAttr("S");
                    break;
            }
            //console.log("have newItems %o",newItems);
            //jQuery.extend(newSort,newItems);
            newSort = newSort.concat(newItems);
        }
        this.productResultsSorted = newSort;
        //console.log("results of sort: %o",this.productResultsSorted);
    }
    this.applySort = function() {
        // to write the sort to the DOM so as to have un-matched float to the bottom 
        var target = $("#resultsSorted > ul");
        //for (var id in this.productResultsSorted) {
        for (var i=0, j=this.productResultsSorted.length; i<j; i++) {
            //var resultEl = $("#"+id);
            var resultEl = $("#"+this.productResultsSorted[i]["id"]);
            //console.log("id %o: have result %o, target %o",this.productResultsSorted[i]["id"],resultEl,target);
            $(target).append(resultEl); 
        }
        //console.log("apply sort complete.");
        var unsortedResults = $(this.unsortedResultsRef).children("ul").html();
        $(this.unsortedResultsRef).children("ul").children("li").remove();
        //console.log("unsorted cases: %o",unsortedResults);
        $(this.sortedResultsRef).children("ul").append(unsortedResults);
        var target = $(this.sortedResultsRef);
        var resultEls = $(target).children("ul").children("li");
        $(resultEls).each(function(idx){ 
            //console.log("idx %o, have child %o",idx,this);
            if ((idx == 0) && (resultEls.length > 1)) {
              $(this).addClass("featured"); 
            } else {
              $(this).removeClass("featured"); 
            }
        });

        this.filterResultsByRegion();
        $(this.sortedResultsRef).show();
    }
    this.filterResultsByRegion = function() {
        //console.log("filterResultsByRegion()...");
        var region = this.params.region.value;
        var filterKey = false;
        var filterThese = [];
        if (region === "n") {
            filterKey = "S";
        } else if (region === "s") {
            filterKey = "N";
        }
        if (filterKey) {
            //console.log("region is %o, opposite region to be filtered, key %o...",filterKey);
            for (var i=0, j=this.productResults.length; i<j; i++) {
            //for (var id in this.productResults) {
                if (this.productResults[i][filterKey]) {
                    //filterThese.push(id);
                    filterThese.push(this.productResults[i]["id"]);
                }
            }
            for (var i=0, j=filterThese.length; i<j; i++) {
                var target = $("#"+filterThese[i]);
                //console.log("hiding %o",target);
                $(target).hide();
            }
            var resultsShownCount = this.productResults.length - filterThese.length;
            this.setResultsTotal(resultsShownCount);
        }
    }
    this.setResultsTotal = function(newTotal) {
        //console.log("setResultsTotal(%o)",newTotal);
        $(this.resultTotalRef).text(newTotal);
    }
    this.getProductResultObjsByAttr = function(required,secondary) {
        //console.log("getProductResultObjsbyAttr(%o,%o)",required,secondary);
        //var resultObj = { };
        var resultObjs = [ ];
        var newObj = { };
        var idx = 0;

        //for (var id in this.productResults) {
        for (var i=0, j=this.productResults.length; i<j; i++) {
            idx++;
            newObj = { };
            //newObj[id] = this.productResults[id];
            //newObj = this.productResults[i];
            //console.log("%o: test obj %o\nrequired %o\nrequired match %o\nsecondary %o\nsecondary match %o",idx,this.productResults[i],required,this.productResults[i][required],secondary,this.productResults[i][secondary]);

            if (this.productResults[i][required] == true) {
                if ((secondary) && (this.productResults[i][secondary] == true)) {
                    //console.log("match both %o & %o, storing sort %o",required,secondary,this.productResults[i]);

                    //jQuery.extend(resultObj,newObj);
                    resultObjs.push(this.productResults[i]);

                } else if (typeof(secondary) === "undefined") {

                    if (this.productResults[i]["G"] != true) {
                        //console.log("match %o, storing sort %o",required,this.productResults[i]);

                        //jQuery.extend(resultObj,newObj);
                        resultObjs.push(this.productResults[i]);

                    }
                }
            }
        }
        return resultObjs;
    }
    this.enableContinue = function(step) {
      //console.log("enableContinue(%o)...",step);
      var n = +(step-1);
      var btnContinue = $(this.stepContainerEls[n]).find(".continue");
      var btnResults = $(this.stepContainerEls[n]).find(".current");
      $(btnContinue).show();
      $(btnResults).show();
    }
    this.disableContinue = function(step) {
      //console.log("disableContinue()...");
      var n = +(step-1);
      var btnContinue = $(this.stepContainerEls[n]).find(".continue");
      var btnResults = $(this.stepContainerEls[n]).find(".current");
      $(btnContinue).hide();
      $(btnResults).hide();
      this.disableSkip();
    }
    this.enableSkip = function(step) {
        //console.log("Ran enableSkip");
      var n = +(step-1);
      var el = $(this.stepContainerEls[n]).find(".skip");
      $(el).show();
    }
    this.disableSkip = function(step) {
        //console.log("Ran disableSkip");
      var n = +(step-1);
      var el = $(this.stepContainerEls[n]).find(".skip");
      $(el).hide();
    }
    this.goToStep = function(step) {
      step = (+step);
      //console.log("goToStep(%o)...",step);
      var n = +(step-1);
      this.hideAll();
      this.clearDataForward(step);
      if (step < 5) {
        // clear progress state and then load UI relevant to each specific step
        this.disableNavAll();
        this.enableProgress(step);
        $(this.stepContainerEls[n]).show();
        if (step == 1) {
            this.fitmentResultEqualHeights();
        }
        $(this.containerEl).removeClass("batterySelectorResults");
      } else {
        //console.log("fitment steps done, now showing results...");
        // move UI to next step
        this.enableProgress(5);
        $(this.containerEl).addClass("batterySelectorResults");
        // show the results div
        $(this.productResultsRef).show();
        // Activate Carousel
        // first check if it's already active
        if (!(jQuery('#carousel').hasClass("jcarousel-list"))) {
            $('#carousel').jcarousel({
                scroll: 1, 
                visible: 4
            });
        }
        // IE6 fix for Recommended Products layout 
        $("#recProductsControl").css("position","relative");
        var waitABit = setTimeout(function(){
            $("#recProductsControl").css("position","absolute");
        },100);
        // Activate Store Locator buttons
        $("#product_details a.find").click(function(){
            //console.log("store locator button click...");
            // show Store Locator
            showbox("#where");
            doOmnitureEvent({ eventType: "pageload", pageName: "Store Locator", channel: "Home", clicked: this });

            // add initial field focus
            $("#address_zipcode").eq(0).focus();
        });
      }
      this.currentStep = step;
    }
    this.goToNextStep = function() {
      //console.log("goToNextStep()...");
      this.saveOptionalStep();
      this.readForm();
      var totalSteps = this.stepContainerEls.length;
      //console.log("this.currentStep %o, totalSteps %o",this.currentStep,totalSteps);
      var queries = [ ];
      var stepObj = { };
      stepObj.key = "step";
      stepObj.value = this.currentStep+1;
      queries.push(stepObj);

      if (this.currentStep >= 1) {
          for (var i=0, j=this.params.fitmentSteps.length; i<j; i++) {
              queries.push(this.params.fitmentSteps[i]);
          }
      }
      if ((this.currentStep >= 2) && (this.params.region.value)) {
          //console.log("push region %o",this.params.region);
          queries.push(this.params.region);
      }
      if ((this.currentStep >= 3) && (this.params.driveFrequency.value)) {
          queries.push(this.params.driveFrequency);
      }
      if ((this.currentStep >= 4) && (this.params.deviceUsage.value)) {
          queries.push(this.params.deviceUsage);
      }
      this.addQuery(queries);
    }
    this.enableProgress = function(step) {
      var n = +(step-1);
      if (step < 5) {
        this.progressSteps[n].domEl.html('<p>'+this.progressSteps[n].origContent+'</p>');
        this.progressSteps[n].domEl.addClass("current");
        $(this.progressEl).find("ul").removeClass("fitmentComplete");
      // questionnaire complete, results "step"
      } else if (step == 5) {
        //console.log(this.progressEl);
        $(this.progressEl).find("ul").addClass("fitmentComplete");
      }
        for (i=0, j=n; i<j; i++) {
          if (i < 4) {
            this.progressSteps[i].domEl.addClass("complete");
            this.progressSteps[i].domEl.html('<a href="javascript:;">'+this.progressSteps[i].origContent+'</a>');
            var link = $(this.progressSteps[i].domEl).find("a");
            var linkStep = i+1;
            $(link).click(function(n,step){
                return function(e){
                    self.navClick(n,step);
                    e.preventDefault();
                };
            }(linkStep,step));
          }
        }
    }
    this.saveOptionalStep = function() {
        //console.log("saveOptionalStep(), this step %o",this.currentStep);
        //collect form data
        switch (this.currentStep) {
            case 2:
                var pinPos = $(this.pinEl).css("top").replace(/px/,"") + "," + $(this.pinEl).css("left").replace(/px/,"");
                var selected;
                if (this.mapInputNorthEl.checked) {
                    selected = "n";
                } else if (this.mapInputMidEl.checked) {
                    selected = "m";
                } else if (this.mapInputMidEl.checked) {
                    selected = "s";
                } else {
                    selected = false;
                }
                if (selected) {
                    //console.log("saving step 2, have pinPos %o",pinPos);
                    createCookie('fitment_optional_2_result', encodeURIComponent(selected), '');
                    createCookie('fitment_optional_2_pin', encodeURIComponent(pinPos), '');
                }
                break;
            case 3:
                //console.log("saving step 3");
                var freqStr = "";
                for (var i=0, j=this.driveFrequencyEls.length; i<j; i++) {
                    if (this.driveFrequencyEls[i].checked) {
                        freqStr = i;
                    }
                }
                //console.log("frequency string %o",freqStr);
                createCookie('fitment_optional_3', encodeURIComponent(freqStr), '');
                break;
            case 4:
                //console.log("saving step 4");
                var usageStr = "";
                for (var i=0, j=this.deviceUsageEls.length; i<j; i++) {
                    suffix = (i == (j-1)) ? "" : "_";
                    var paren = $(this.deviceUsageEls[i]).parent();
                    var parenChecked = $(paren).hasClass("checked");
                    var checked = $(this.deviceUsageEls[i]).attr("checked");
                    if (parenChecked && !checked) {
                        checked = true; //IE6 fix: override unchecked radios if faux form parent is "checked"
                    }
                    if (checked) {
                        usageStr = usageStr + 1 + suffix;
                    } else {
                        usageStr = usageStr + 0 + suffix;
                    }
                }
                //console.log("usage string %o",usageStr);
                createCookie('fitment_optional_4', encodeURIComponent(usageStr), '');
                break;
        }
        //write to cookie
    }
    this.navClick = function(n,step) {
        var removeThese = [ ];
        removeThese.push("results");
        removeThese.push("skip");
        //console.log("navClick(): building removeThese, n %o, step %o",n,step);
        if (n < 4) {
            removeThese.push("devices"); 
        }
        if (n < 3) {
            removeThese.push("freq"); 
        }
        if (n < 2) {
            removeThese.push("region"); 
        }
        //console.log("remove these queries %o",removeThese);
        //self.removeQuery(["results","region","freq","devices"], { skipLocationRewrite: true });
        self.removeQuery(removeThese, { skipLocationRewrite: true });
        var queryObj = { };
        queryObj.key = "step";
        queryObj.value = n;
        self.addQuery([ queryObj ]);
    }
    this.disableNavAll = function() {
        for (i=0, j=this.progressSteps.length; i<j; i++) {
          var sp = this.progressSteps[i];
          $(sp.domEl).html("<p>"+sp.origContent+"</p>");
          $(sp.domEl).removeClass("complete");
          $(sp.domEl).removeClass("current");
        }
    }
    this.disableContinueAll = function() {
        for (i=0, j=this.progressSteps.length; i<j; i++) {
            this.disableContinue(i+1);
        }
    }
    this.clearDataForward = function(step) {
        //where step is the new landing, clear data
        //from steps forward
        //console.log("clearDataForward(%o)",step);
        if (step) {
            var n = (+step)-1;
            for (var i=0, j=this.progressSteps.length; i<j; i++) {
                //console.log("i %o, n %o",i,n);
                if (i > n) {
                    this.clearStep(i+1);
                }
            }
        } 
    }
    this.clearStep = function(step) {
        //console.log("clearStep(%o)",step);
        if (step == 2) {
            eraseCookie("fitment_optional_2_pin");            
            eraseCookie("fitment_optional_2_result");            
            this.mapInputNorthEl.checked = false;
            this.mapInputMidEl.checked = false;
            this.mapInputSouthEl.checked = false;
            this.params.region.value = false;
        } else if (step == 3) {
            eraseCookie("fitment_optional_3");            
            for (var i=0, j=this.driveFrequencyEls.length; i<j; i++) {
                this.driveFrequencyEls[i].checked = false;
                $(this.driveFrequencyEls[i]).parent().removeClass("checked");
            }
            this.params.driveFrequency.value = false;
        } else if (step == 4) {
            eraseCookie("fitment_optional_4");            
            for (var i=0, j=this.deviceUsageEls.length; i<j; i++) {
                //console.log("uncheck %o",this.deviceUsageEls[i]);
                this.deviceUsageEls[i].checked = false;
                $(this.deviceUsageEls[i]).parent().removeClass("checked");
            }
            this.params.deviceUsage.value = false;
        }
    }
    this.fitmentResultEqualHeights = function(){ 
        //console.log("fitmentResultEqualHeights()...");
        var maxHeight = 0;
        for (var i=0, j=this.fitmentSteps.length; i<j; i++) {
            // set visibility if necessary
            //$(this.fitmentSteps[i].resultEl).find("span").css("visibility","hidden");
            // clear previous height setting
            $(this.fitmentSteps[i].resultEl).find("span").css("height","");
            var height = $(this.fitmentSteps[i].resultEl).find("span").height();
            //console.log("have height %o for %o",height,this.fitmentSteps[i].resultEl);
            maxHeight = (height > maxHeight) ? height : maxHeight;
        }
        //console.log("identified max height as %o",maxHeight);
        for (var i=0, j=this.fitmentSteps.length; i<j; i++) {
            $(this.fitmentSteps[i].resultEl).find("span").css("height",maxHeight+"px");
        }
        // adjust layout background to scale to footer, global function
        adjustBatterySelectorHeight(); 
    }
    this.mapClickEvent = function() {
        $(this.mapEl).click(function(e){
            //console.log("map clicked, event %o, self",e,self);
            var mapOffset = $(self.mapEl).offset();
            var clickOffset = { top: e.pageY, left: e.pageX };
            var pinInnerOffset = { top: 35, left: 8 }
            var pinOffset = { top: 0, left: 0 };
            pinOffset.top = clickOffset.top - mapOffset.top - pinInnerOffset.top;
            pinOffset.left = clickOffset.left - mapOffset.left - pinInnerOffset.left;
            //console.log("mapOffset %o clickOffset %o, pinOffset %o",mapOffset,clickOffset,pinOffset);
            $(self.pinEl).css("top",pinOffset.top+"px");
            $(self.pinEl).css("left",pinOffset.left+"px");
            self.pinDrop(pinOffset);
        });
    }
    this.setupMapPin = function() {
      $(this.pinEl).draggable({ addClasses: true, 
                                appendTo: this.mapEl,
                                containment: "parent",
                                cursor: "crosshair" });
      /* optional drag event handlers *
      $(this.pinEl).bind('dragstart', function(event, ui) {
        //console.log("dragstart: event %o ui %o",event,ui);
      });
      $(this.pinEl).bind('drag', function(event, ui) {
        //console.log("drag: event %o ui %o",event,ui);
      });
      */
      $(this.pinEl).bind('dragstop', function(event, ui) {
        //console.log("dragstop: event %o ui %o",event,ui);
        self.pinDrop(ui.position);
      });
      //this.resetPin();
    }
    this.resetPin = function() {
      // set pin off side of map for init state
      $(self.pinEl).css("left","-100px");
    }
    this.pinDrop = function(position) {
        /* determine if pin was dropped in "North" or "South" region *
         * and check hidden radio form elements appropriately        */
        //console.log("pin drop %o, north el %o, mid el %o south el %o",position,this.mapInputNorthEl,this.mapInputMidEl,this.mapInputSouthEl);
        // save the pin setting to cookie
        var pinPos = position.top + "," + position.left;
        createCookie('fitment_optional_2_pin', encodeURIComponent(pinPos), '');
        if (position.top < 120) {
            $(this.mapInputNorthEl).attr("checked","checked");
        } else if (position.top < 170) {
            $(this.mapInputMidEl).attr("checked","checked");
        } else {
            $(this.mapInputSouthEl).attr("checked","checked");
        }
    }
    this.hideAll = function() {
      this.stepContainerEls.hide();
      $(this.productResultsRef).hide();
    }
    this.toggleProgress = function(set) {
        /* set: label for various cases of elements to show/hide */
        //console.log("toggleProgress(%o)...",set);
        var progressEl = false;
        switch(set) {
            case "results":
                progressEl = this.progressRefs.results; 
                //var pad = 100;
                //this.setProgressHeight(progressEl,pad);
                break;
            case "steps_nav":
                progressEl = this.progressRefs.stepNav; 
                break;
            default:
                var shards = set.split("_");
                var type = shards[1];
                var fitmentStep = shards[2];
                progressEl = this.progressRefs.fitmentSteps[fitmentStep][type];
                //console.log("toggleProgress(%o): have progressEl %o",set,progressEl);
                break;
        }
        if (progressEl === "#fitment_progress_flyout") {
            this.doShowBoxToggle(progressEl);
        } else {
            matched = $(progressEl);
            if (matched) {
                for (var i=0, j=matched.length; i<j; i++) {
                    this.doSimpleToggle(matched[i]);
                }
            }
        }
    }
    this.doShowBoxToggle = function(ref) {
        var el = $(ref);
        if (el) {
            if ($(el).css("display") === "none") {
                // global utility, "lightbox" type with overlay
                $("#overlay").css("opacity","0.5");
                $("#overlay").css("filter","alpha(opacity=50)");
                showbox(ref);
            } else {
                // close 
                hidebox(ref);
                $("#overlay").css("opacity","");
                $("#overlay").css("filter","");
            }
        }
    }
    this.doSimpleToggle = function(el) {
        if ($(el).css("display") === "none") {
            $(el).show();
        } else {
            $(el).hide();
        }
    }
    this.init();
}
$(document).ready(function(){ 
  FitmentForm = new FitmentQuestionnaireUtil();
  if ($("#fitment_test").length) {
  FitmentWalkerTest = new FitmentTest();
  }
});

/* FormValidation: Client-side form validation utility *
 **
 **/
function FormValidation() {
      this.zipCodeRegExp  = RegExp(/^\d{5}$/);
      this.phoneRegExp  = RegExp(/^\d{10}$/);
      this.notBlankRegExp  = RegExp(/[^\s]$/);
      this.emailRegExp    =  RegExp(/(?:[a-zA-Z0-9_'^&amp;/+-])+(?:\.(?:[a-zA-Z0-9_'^&amp;/+-])+)*@(?:(?:\[?(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))\.){3}(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\]?)|(?:[a-zA-Z0-9-]+\.)+(?:[a-zA-Z]){2,}\.?)$/);
      var self = this;
      this.init = function() {
        //console.log("FormValidation.init()...");
        /* Store Locator DOM References */
        this.storeLocFormEl = $("#form_store_locator")[0];
        this.storeLocZipEl = $("#address_zipcode")[0];
        this.storeLocZipErrorEl = $("#address_zipcode_error")[0];
        this.storeLocCityEl = $("#address_city")[0];
        this.storeLocCityErrorEl = $("#address_city_error")[0];
        this.storeLocStateEl =  $("#address_state")[0];
        this.storeLocStateErrorEl = $("#address_state_error")[0];
        this.storeLocGenErrorEl = $("#store_locator_gen_error")[0];

        /* Contact DOM References */
        this.contactEmailSelectYear = $("#contact_email_year_list");
        this.contactEmailSelectMake = $("#contact_email_make_list");
        this.contactEmailSelectModel = $("#contact_email_model_list");
        this.contactEmailSelectEngine = $("#contact_email_engine_list");
        this.contactEmailFormEl = $("#form_contact_email");
        this.emailNameEl = $("#contact_email_name")[0];
        this.emailNameErrorEl = $("#contact_email_name_error")[0];
        this.emailEmailEl = $("#contact_email_email")[0];
        this.emailEmailErrorEl = $("#contact_email_email_error")[0];
        this.emailSubjectEl = $("#contact_email_subject")[0];
        this.emailSubjectErrorEl = $("#contact_email_subject_error")[0];
        this.emailCommentsEl = $("#contact_email_comments")[0];
        this.emailCommentsErrorEl = $("#contact_email_comments_error")[0];

        /* AJAX Progress DOM References */
        this.progressRefs = { storeLocator: "#where .lb_progress",
                              contactEmail: "#sendEmail .lb_progress" };

        /* General AJAX fail messages */
        this.emailErrorMsg = '<p class="failMsg">Sorry, your request was unsuccessful. Please try <a href="#" class="reset">resubmitting your information</a>.</p>';
        this.contactEmailValidators = {
              email_name:           {   fieldEl:    this.emailNameEl, 
                                        errorEl:    this.emailNameErrorEl,
                                        valid:      function(){ return (self.emailNameEl.value.match(self.notBlankRegExp) ? true : false) },
                                        errorMsg:   "please enter your name" },
              email_email_address:  {   fieldEl:    this.emailEmailEl, 
                                        errorEl:    this.emailEmailErrorEl,
                                        valid:      function(){ return (self.emailEmailEl.value.match(self.emailRegExp) ? true: false) },
                                        errorMsg:   "please enter a valid email" },
              email_subject:        {   fieldEl:    this.emailSubjectEl, 
                                        errorEl:    this.emailSubjectErrorEl,
                                        valid:      function(){ return (self.emailSubjectEl.value.match(self.notBlankRegExp) ? true: false) },
                                        errorMsg:   "please enter a subject" },
              email_comments:       {   fieldEl:    this.emailCommentsEl, 
                                        errorEl:    this.emailCommentsErrorEl,
                                        valid:      function(){ return (self.emailCommentsEl.value.match(self.notBlankRegExp) ? true: false) },
                                        errorMsg:   "please enter your comments" }
              };
        this.storeLocatorValidators = {
              zip:  { fieldEl: this.storeLocZipEl,
                      errorEl: this.storeLocZipErrorEl,
                      valid:      function(){ return (self.trim12(self.storeLocZipEl.value).match(self.zipCodeRegExp) ? true: false) },
                      errorMsg:   "please enter a valid zip code" },
              city:  { fieldEl: this.storeLocCityEl,
                      errorEl: this.storeLocCityErrorEl,
                      valid:      function(){ return (self.trim12(self.storeLocCityEl.value).match(self.notBlankRegExp) ? true: false) },
                      errorMsg:   "please enter a city" },
              state: { fieldEl: this.storeLocStateEl,
                      errorEl: this.storeLocStateErrorEl,
                      valid:      function(){ return ((self.storeLocStateEl.selectedIndex != 0) ? true: false) },
                      errorMsg:   "please select a state" }
        };
        this.formEvents();
      }
      this.formEvents = function() {
        this.activateStoreLocator();
        this.activateContactEmail();
        this.activateContactFitmentSelects();
        this.activateContactFitmentClearSelects();
      }

      // register onChange events for all fitment selects on the contact form
      this.activateContactFitmentSelects = function(){
            
              // EMAIL FORM:
              
              // Register onChange event for the Year dropdown
              $(this.contactEmailSelectYear).change(function(){
                  var year = $(this).val();
                  jQuery.ajax({
                        type:"GET", 
                        url:"/contact/get_makes?year=" + year + "&email_or_phone=email", 
                        dataType:"script",
                        success: self.contactEmailYearSuccess
                   });
                   $(self.contactEmailSelectModel).html("<option>Choose...</option>");
                   $(self.contactEmailSelectEngine).html("<option>Choose...</option>");
              });

              // Register onChange event for the Make dropdown for Call form
              $(this.contactEmailSelectMake).change(function(){
                    var make = $(this).val();
                    var year = $(self.contactEmailSelectYear).val();
                    jQuery.ajax({
                          type:"GET", 
                          url:"/contact/get_models?year=" + year + "&make=" + make + "&email_or_phone=email",
                          dataType:"script",
                          success: self.contactEmailMakeSuccess
                     });
                    $(self.contactEmailSelectEngine).html("<option>Choose...</option>");
                });

                /* TODO: Etool #152 - IE6 fix for truncated <option> within a <select> with CSS width
                $(this.contactEmailSelectModel).click(function(){
                    //alert("email <select> model clicked");
                    $(this).css("width","auto !important");
                    $(this).css("margin-left","5px");
                });
                $(this.contactEmailSelectModel).blur(function(){
                    $(this).css("width","");
                    $(this).css("margin-left","");
                });*/
                // Register onChange event for the Model dropdown for Call form
                $(this.contactEmailSelectModel).change(function(){
                      var model = $(this).val();
                      var make = $(self.contactEmailSelectMake).val();
                      var year = $(self.contactEmailSelectYear).val();
                      //console.log("Make: " + make + " Model: " + model + " Year: " + year);
                      jQuery.ajax({
                            type:"GET", 
                            url:"/contact/get_engines?year=" + year + "&make=" + make + "&model=" + escape(model) + "&email_or_phone=email",
                            dataType:"script",
                            success: self.contactEmailModelSuccess
                       });
                  });
      }
      
      this.contactEmailYearSuccess = function() {
          $(self.contactEmailSelectMake).attr("disabled", "");
      }
      this.contactEmailMakeSuccess = function() {
          $(self.contactEmailSelectModel).attr("disabled", "");
      }
      this.contactEmailModelSuccess = function() {
          $(self.contactEmailSelectEngine).attr("disabled", "");
      }
      
      this.contactFitmentClearSelects = function(){
          arr = [];
          arr.push($(this.contactEmailSelectYear));
          arr.push($(this.contactEmailSelectMake));
          arr.push($(this.contactEmailSelectModel));
          arr.push($(this.contactEmailSelectEngine));
          $(arr).each( function (){
              $(this).html("<option>Choose...</option>");
          });
          this.populateContactYears();
      }
      
      this.activateContactFitmentClearSelects = function(){
          $("a.clearAnswers").click(function (){self.contactFitmentClearSelects();});
      }

      this.activateContactEmail = function() {
        $(this.contactEmailFormEl).find("a.submit").click(function(){
            //console.log("clicked %o",this);
            $(self.contactEmailFormEl).submit();
        });
        $(this.contactEmailFormEl).submit(function(e){
            if (self.isContactEmailValid()) {
                //console.log("contact email form validates");
                self.contactEmailSubmit();
            } else {
                //console.log("contact email form FAIL VALIDATION");
                //e.preventDefault();
            }
            e.preventDefault();
        });
      }
      
      this.populateContactYears = function() {
          jQuery.ajax({
                  type:"GET", 
                  url:"/contact/get_years",
                  dataType:"script"
              });
      }
      
      this.activateStoreLocator = function() {
        $(this.storeLocFormEl).find("a.submit").click(function(){
            //console.log("clicked %o",this);
            $(self.storeLocFormEl).submit();
        });
        $(this.storeLocFormEl).submit(function(e){
            //console.log("store locator submit");
            if (self.isStoreLocatorValid()) {
                //console.log("store locator form validates");
                self.storeLocatorSubmit();
            } else {
                //console.log("store locator form FAIL VALIDATION");
                //e.preventDefault();
            }
            e.preventDefault();
        });
      }
      this.isContactEmailValid = function(){
        this.contactEmailValidate();
        return this.contactEmailValid;
      }
      this.isStoreLocatorValid = function(){
        this.storeLocatorValidate();
        return this.storeLocatorValid;
      }
      this.storeLocatorSubmit = function(){
          //console.log("storeLocatorSubmit()...");
          var hiddenInput = $(this.storeLocFormEl).find("input:hidden").eq(0);
          var token = $(hiddenInput).attr("value");
          this.toggleProgress("store_locator");
          jQuery.ajax({
              data: jQuery.param(jQuery(self.storeLocFormEl).serializeArray()) + '&authenticity_token=' + encodeURIComponent(token), 
              success: function(request){
                self.toggleProgress("store_locator");
                jQuery('#results').html(request);
                /* call general util for fix IE6 display */
                IE6LightboxForceRepaint();
                var submitBtn = $(this.storeLocFormEl).find("a.submit")[0];
                doOmnitureEvent({ pageName: "Store Locator > Result", 
                                  channel: "Home",
                                  linkTrackOptionalVars: "events,eVar7",
                                  linkTrackEvents: "event1",
                                  events: "event1",
                                  eVar7: "Store Locator",
                                  clicked: submitBtn });
              }, 
              type:'post', 
              url:'/store_locator/find_stores'
         }); 
      }
      this.contactEmailSubmit = function(){
          //console.log("contactEmailSubmit()...");
          var hiddenInput = $(this.contactEmailFormEl).find("input:hidden").eq(0);
          var token = $(hiddenInput).attr("value");
          this.toggleProgress("contact_email");
          jQuery.ajax({
              data: jQuery.param(jQuery(self.contactEmailFormEl).serializeArray()) + '&authenticity_token=' + encodeURIComponent(token), 
              success: self.contactEmailComplete, 
              error: self.contactEmailError, 
              type:'post', 
              url:'/home/email_me'
         }); 
      }
      this.contactEmailComplete = function(transport){
          //console.log("contact email complete. transport: \n",transport);
          self.toggleProgress("contact_email");
          self.lightboxMessage("#sendEmail",transport);
          var submitBtn = $(this.contactEmailFormEl).find("a.submit")[0];
          doOmnitureEvent({ pageName: "Contact Us > Submit", channel: "Home", clicked: submitBtn });
      }
      this.contactEmailError = function(transport){
          //console.log("contact email error %o",transport);
          self.toggleProgress("contact_email");
          self.lightboxMessage("#sendEmail",self.emailErrorMsg);
      }
      this.lightboxMessage = function(lightboxEl,message) {
          var formEl = $(lightboxEl).find(".formView").eq(0);
          var confirmEl = $(lightboxEl).find(".confirmView").eq(0);
          // write message into confirmation element
          $(confirmEl).html(message);
          // hide form, show message 
          $(formEl).hide();
          $(confirmEl).show();

          // add close with toggle view back to form
          var switchViewToForm = function(){
            hidebox(lightboxEl);
            $(confirmEl).hide();
            $(formEl).show();
          }
          // attach click to inline close link
          var closeEl = $(lightboxEl).find(".confirmationClose").eq(0);
          $(closeEl).click(function(e){ 
            switchViewToForm();
            e.preventDefault();
          });
          // attach click to inline reset link
          var resetEl = $(lightboxEl).find("a.reset").eq(0);
          $(resetEl).click(function(e){ 
            $(confirmEl).hide();
            $(formEl).show();
            // prevent href eval #, avoid bounce to screen top
            e.preventDefault();
          });

          // lightbox close button
          var closeBtn = $(lightboxEl).find("a.close").eq(0);
          // remove previous click handlers
          $(closeBtn).unbind("click");
          // attach new click  
          $(closeBtn).click(function(e){ 
            switchViewToForm();
            e.preventDefault();
          });
      }
      this.contactEmailValidate = function(){
        //console.log("contactEmailValidate()...");
        /* set valid to true, then loop over validators for this *
         * form and if any fail then set valid property to false */
        this.contactEmailValid = true; 

        //console.log("email validate requiring %o, %o, %o, %o",this.emailNameEl,this.emailEmailEl,this.emailSubjectEl,this.emailCommentsEl);
        if (this.emailNameEl && this.emailEmailEl && this.emailSubjectEl && this.emailCommentsEl) {
          //console.log("doing email validators");
          for (validator in this.contactEmailValidators) {
            v = this.contactEmailValidators[validator];
            //console.log("working email validator %o",v);
            isValid = v.valid();
            //console.log("validation run complete, email validator %o, errorEl %o",v,v.errorEl);
            if (!isValid) {
              this.contactEmailValid = false; 
              $(v.errorEl).show();
              $(v.fieldEl).addClass("inError");
            } else {
              $(v.errorEl).hide();
              $(v.fieldEl).removeClass("inError");
            }
          }
        }
      }
      this.storeLocatorValidate = function(){
        this.storeLocatorValid = true; 
        //console.log("storeLocatorValidate()..."); 
        /* zip is required to validate this form */ 
        if (this.storeLocZipEl) {
          var zipValid = this.storeLocatorValidators.zip.valid();

          var zip = this.trim12(this.storeLocatorValidators.zip.fieldEl.value);
          //console.log("input compare vals: \nzip: %o",zip);
          /* hide error field */
          $(this.storeLocatorValidators.zip.errorEl).hide();

          if (!zipValid) {
              $(this.storeLocatorValidators.zip.errorEl).show();
              this.storeLocatorValid = false; 
              //console.log("Store Locator form INVALID.");
          } else {
              //console.log("Store Locator form validates.");
          }
          
        }
      }
      /* old validation method, unused for now, while Sears API requires zip code *
       * it works on a model of valid zip OR city/state */
      this.storeLocatorValidateZipOrCityState = function(){
        this.storeLocatorValid = true; 
        //console.log("storeLocatorValidate()..."); 
        /* either zip or city+state are required to validate this form */ 
        if (this.storeLocZipEl && this.storeLocCityEl && this.storeLocStateEl) {
          var zipValid = this.storeLocatorValidators.zip.valid();
          var cityValid = this.storeLocatorValidators.city.valid();
          var stateValid = this.storeLocatorValidators.state.valid();

          var zip = this.trim12(this.storeLocatorValidators.zip.fieldEl.value);
          var city = this.trim12(this.storeLocatorValidators.city.fieldEl.value);
          var state = this.storeLocatorValidators.state.fieldEl.selectedIndex;
          //console.log("input compare vals: \nzip: %o\ncity: %o\nstate: %o",zip,city,state);
          /* hide all error fields, we show next only fields in error for this submit */
          $(this.storeLocGenErrorEl).hide();
          for (v in this.storeLocatorValidators) {
              $(this.storeLocatorValidators[v].errorEl).hide();
          }

          /* form default state, show general error */
          if ((zip === "") && (city === "") && (state == 0)) {
            //console.log("form default: don't validate and show general error message");
            $(this.storeLocGenErrorEl).show();
          /* some fields have user input, give preference to zip */
          } else if (zip != "") {
            //console.log("zip has input: validating that over city+state");
              if (!zipValid && cityValid && stateValid) {
                /* Zip isn't valid but City and State are, so we'll validate. Don't show *
                 * error for Zip invalid since we'll submit the form                     */
                //$(this.storeLocatorValidators.zip.errorEl).show();
              } else if (!zipValid) {
                $(this.storeLocatorValidators.zip.errorEl).show();
              }
          /* city+state fields have user input */
          } else if ((city != "") || (state != 0)) {
            //console.log("zip doesn't have input but city+state do");
              if (!(cityValid)) {
                $(this.storeLocatorValidators.city.errorEl).show();
              }
              if (!(stateValid)) {
                $(this.storeLocatorValidators.state.errorEl).show();
              }
          }
          if ((zipValid) || (cityValid && stateValid)) {
            //console.log("Store Locator form validates.");
            this.storeLocatorValid = true;
            //$("#form_store_locator .validationMessage").html("VALID!");
          } else {
            this.storeLocatorValid = false;
            //$("#form_store_locator .validationMessage").html("invalid.");
          }

        }
    }
    this.toggleProgress = function(set) {
        /* set: label for various cases of elements to show/hide */
        //console.log("toggleProgress(%o)...",set);
        var progressEl = false;
        switch(set) {
            case "store_locator":
                progressEl = this.progressRefs.storeLocator; 
                break;
            case "contact_email":
                progressEl = this.progressRefs.contactEmail; 
                break;
        }
        matched = $(progressEl);
        if (matched) {
            for (var i=0, j=matched.length; i<j; i++) {
                this.doSimpleToggle(matched[i]);
            }
        }
    }
    this.doSimpleToggle = function(el) {
        if ($(el).css("display") === "none") {
            $(el).show();
            var wrapper = $(el).parent();
            var parHeight = $(wrapper).height();
            //console.log("doSimpleToggle: have wrapper %o, height %o",wrapper,parHeight);
            $(el).find(".inner").css("height",parHeight+"px");
        } else {
            $(el).hide();
        }
    }
    this.trim12 = function (str) {
        var str = str.replace(/^\s\s*/, ''),
        ws = /\s/,
        i = str.length;
        while (ws.test(str.charAt(--i)));
        return str.slice(0, i + 1);
    }
    this.init();
}
$(document).ready(function(){ DH_formValidation = new FormValidation(); });

$(document).ready(function(){
  var clientIsMSIE = /*@cc_on!@*/false; 
  var clientIsMSIE6 = ( clientIsMSIE && ( /MSIE 6/i.test(navigator.userAgent) ) );
  var pageIsHome = $('#page').hasClass("home");
  if (pageIsHome && clientIsMSIE6) {
    $("#contain").scroll(function(){
        IE6_footerPositionFix();
    });
    $("#wrapper").scroll(function(){
        IE6_footerPositionFix();
    });
    $("#page").scroll(function(){
        IE6_footerPositionFix();
    });
  }
});

IE6_footerPositionFix = function(){
  $("#footer").css("position","absolute");
  var newWidth = $("#contain").width();
  $("#footer").css("width","99.999%");
  var waitABit = setTimeout(function(){
  $("#footer").css("width","100%");
  },100);
}

/* ViewPortHeightAdjust: UI support utility                                            *
 * 1. Dynamically adjusts height in a way CSS cannot express, e.g. height: 100% - N px *
 *    Used for Home layout, where Flash layout via #wrapper must be 100% of its parent *
 *    #outer, but minus the static heights of header and footer                        *
 * 2. IE6 layout fix for 100% height applied in IE6 stylesheet via expressions.        *
 *    The logic in CSS is applied except at high resize velocities, e.g. using window  *
 *    maximize control or doing a manual quick drag of a window edge with the mouse.   * 
 *    During re-size layout elements are hidden and then shown to force IE6 to re-calc *
 *    It causes a flicker effect, but it works.                                        */
function ViewPortHeightAdjust() {
  var self = this;
  this.outerEl = $("#outer")[0];  
  this.innerEl = $("#wrapper")[0];
  this.headerEl = $("#header")[0];
  this.footerEl = $("#footer")[0];
  this.init = function() {
    // require all DOM elements before continuing
    if (this.outerEl && this.innerEl && this.headerEl && this.footerEl) {
      this.staticPad = $(this.headerEl).height() + $(this.footerEl).height(); 
      this.helpCenterPad = 20;
      this.viewHeight = document.body.clientHeight;
      this.clientIsMSIE = /*@cc_on!@*/false; 
      this.clientIsMSIE6 = /MSIE 6/i.test(navigator.userAgent);
      //this.staticPad = (this.clientIsMSIE6) ? this.staticPad + 37 : this.staticPad;
    }
    this.heightAdjust();
  }
  this.heightAdjust = function() {
      //console.log("ViewPortUtil.heightAdjust()....");
      if (!(this.clientIsMSIE6)) {
        $(window).unbind("resize");
        $(window).bind("resize",function(){ 
            self.doResize();
        });
        this.doResize();
      }
      if (this.clientIsMSIE6) {
        self.showHideFix();
        $(window).unbind("resize");
        $(window).bind("resize",function(){ 
            var newHeight = document.body.clientHeight;
            if (newHeight != this.viewHeight) {
              self.showHideFix();
            }
            this.viewHeight = newHeight;
        });
      }
  }
  /* IE6 fix to make expressions are calculated and applied when viewport dimensions *
   * change. Required for 100% height with min-height layout for the Home Flash      */
  this.showHideFix = function() {
    $("#footer").hide();
    $("#home_flash").hide();
    var waitABit = setTimeout(function(){ 
      $("#footer").show(); 
      $("#home_flash").show(); 
    },1);
  }
  this.safariScrollFix = function() {
    /* for Safari CSS scroll behavior, where viewport horiz scroll is included    *
     * in the body height. Otherwise the CSS layout causes a vertical scroll      * 
     * anytime viewport has a horiz scroll (layout less than min-width). This fix *
     * restores independence to the 2 scroll dimensions                           */
    var oWidth = $(this.outerEl).width();
    if ((oWidth < 1005) && (navigator.userAgent.match(/Safari/))) {
      var horizScrollPad = 20; 
      var newOHeight = document.documentElement.scrollHeight - horizScrollPad + 4;
      $("#outer").css("height",newOHeight+"px");
    } else {
      $("#outer").css("height","100%");
    }
  }
  this.doResize = function() {
    //console.log("ViewPortUtil.doResize()....");
    if (this.innerEl && this.outerEl) {
      var oHeight = $(this.outerEl).height();
      this.safariScrollFix();
      var newHeight = oHeight - this.staticPad;
	  if (!($("#helpCenterTab").hasClass("collapsed"))) {
      	//$(this.innerEl).css("height",newHeight-100+"px");
        newHeight += this.helpCenterPad;
      	$(this.innerEl).css("height",newHeight+"px");
      	$("#footer").css("margin-top",5+"px");
	  } else {
		$(this.innerEl).css("height",newHeight+"px");
      	$("#footer").css("margin-top","");
	  }
    }
  }
  this.init();
}
$(document).ready(function(){
  if ($("#page").hasClass("home")) {
    ViewPortUtil = new ViewPortHeightAdjust(); 
    /* class is now added via Rails, but leave the     *
     * assignment here in case it the other is removed */
    $("body").addClass("home_root");
    $("html").addClass("home_root_root");
  }
});

/* lightbox functionality for Store Locator and Contact links */
$(document).ready(function(){
    $("#locator_header").click(function(){ 
        showbox('#where');
        doOmnitureEvent({ eventType: "pageload", pageName: "Store Locator", channel: "Home", clicked: this });
    });
    
    $("#contact_footer").click(function(){
        doOmnitureEvent({ eventType: "pageload", pageName: "Contact Us", channel: "Home", clicked: this });
        jQuery.ajax({
              type:"GET", 
              success: getContactFormComplete,
              url:"/contact/show",
              dataType:"script"
         });
    });
    
    $(".results a.find").click(function(){ 
        showbox("#where");
        doOmnitureEvent({ eventType: "pageload", pageName: "Store Locator", channel: "Home", clicked: this });
    });
});

getContactFormComplete = function(transport){
    //console.log("getContactFormComplete()...");
}

function viewPortWidth() { 
	return self.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;}
function viewPortHeight() {
	return self.innerHeight || document.documentElement.clientHeight || document.body.clientHeight; }
function documentHeight() { return document.documentElement.scrollHeight; };

function showbox(el) {
	// hide any lightbox that may already be displayed
	$(".lightbox").hide();

	var oHeight = documentHeight();
	
	// show overlay
	$("#overlay").css("height",oHeight);
	$("#overlay").css("left",0);
	
	// detect if user has scrolled
	if (navigator.appName == "Microsoft Internet Explorer") { 
		var sHeight = document.body.scrollTop; 
	} else {
		var sHeight = window.pageYOffset;
	}
	

	// show lightbox
	var $body = viewPortWidth();
	var $offset = ($body - 725) / 2 + "px";
	
	//$(el).fadeIn("fast"); prefer performance when integrated with CPU-heavy Flash, per Etool #23
    $(el).show();
	$(el).css("left",$offset);
	$(el).css("top",100 + sHeight + "px");
	// show overlay 
	$("#overlay").show().bgiframe();

    /* IE6 fix lightbox layout */
    IE6LightboxForceRepaint(el);
}

/* fix lightbox layouts for IE6                       *
  * apply a type of hasLayout magic which triggers IE6 *
  * to re-paint the DOM elements that would otherwise  *
  * be thoroughly mis-handled in terms of CSS layout   */
IE6LightboxForceRepaint = function(lightboxEl) {
    var clientIsMSIE6 = /MSIE 6/i.test(navigator.userAgent);
    if (clientIsMSIE6) {
      $(lightboxEl).find(".lb_body .inputs a").css("position","absolute");
        $(lightboxEl).find(".lb_body .store li").css("width","209px");

      var waitABit = setTimeout(function(){
        $(lightboxEl).css("width","");
        $(lightboxEl).find(".lb_body form li").css("border","none");
        $(lightboxEl).find(".lb_body .inputs a").css("position","relative");
        $(lightboxEl).find(".lb_body .store li").css("width","");
      },100);
    }
}

function autoSelector(el,selection) {
	// Restrict the lightbox if the parent element contains a class of "inactive"
	var parental = selection.parentNode;
	if ($(parental).hasClass("inactive")) {
		$(".lightbox").hide();
		
		return false;
	} else {
		$(".lightbox").hide();
		
		var $body = viewPortWidth();
		var $content = $(el).width();
			// constrain width of lightbox to 620px
			if ($content > 620) {
				$(el).css("width","620px");
				$content = 620;
			}
		var $offset = ($body - $content) / 2 + "px";
		
		$(el).fadeIn("fast");
		$(el).css("left",$offset);
		$(el).css("top","200px");
	}
}

function hidebox(el, overlay) {
	// hide lightbox
	$(el).hide();
	
	// hide overlay if there is one
	if (overlay == null) {
		$("#overlay").hide();
	}
}

// toggle hidden divs

function showDiv(e) {
	$(e).toggleClass("shown");
}

// legacy tabs

function legacySwap(content, tab) {
    //console.log("legacySwap(%o,%o)",content,tab);
	$(content).show();
	$(content).siblings().hide();

	$(tab).parent().siblings().children().removeClass("active");
	if ($(tab).hasClass("active")) {
		return false;
	} else {
		$(tab).toggleClass("active");
	}

    var sectionLabel = tab.className.match(/tab\w\w*/)[0].replace(/tab/,"");
    var omSectionLabel = "";
    //console.log("have sectionLabel %o",sectionLabel);
    switch(sectionLabel) {
        case "One":
            omSectionLabel = "1967-1975";
            break;
        case "Two":
            omSectionLabel = "1976-1985";
            break;
        case "Three":
            omSectionLabel = "1986-1995";
            break;
        case "Four":
            omSectionLabel = "1995-Today";
            break;
    }
    doOmnitureEvent({ pageName: "Legacy > " + omSectionLabel, 
                      channel: "Legacy", 
                      linkName: omSectionLabel,
                      clicked: tab }); 
}

createCookie = function (name,value,days) {
    //console.log("createCookie(%o,%o,%o)",name,value,days);
	if (days) {
		var date = new Date();
		date.setTime(date.getTime()+(days*24*60*60*1000));
		var expires = "; expires="+date.toGMTString();
	
	}
	else var expires = "";
	document.cookie = name+"="+value+expires+"; path=/";
};

readCookie = function (name) {
    //console.log("readCookie(%o)",name);
	var nameEQ = name + "=";
	var ca = document.cookie.split(';');
	for(var i=0;i < ca.length;i++) {
		var c = ca[i];
		while (c.charAt(0)==' ') c = c.substring(1,c.length);
		if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
	}
	return null;
};

eraseCookie = function (name) {
    //console.log("eraseCookie(%o)",name);
	createCookie(name,"",-1);
};

function initialCaps(str) {
  var index;
  var tmpStr;
  var tmpChar;
  var preString;
  var postString;
  var strlen;
  tmpStr = str.toString().toLowerCase();
  strLen = tmpStr.length;
  if (strLen > 0)  {
    for (index = 0; index < strLen; index++)  {
      if (index == 0)  {
        tmpChar = tmpStr.substring(0,1).toUpperCase();
        postString = tmpStr.substring(1,strLen);
        tmpStr = tmpChar + postString;
      } else {
          tmpChar = tmpStr.substring(index, index+1);
          if (tmpChar == " " && index < (strLen-1))  {
            tmpChar = tmpStr.substring(index+1, index+2).toUpperCase();
            preString = tmpStr.substring(0, index+1);
            postString = tmpStr.substring(index+2,strLen);
            tmpStr = preString + tmpChar + postString;
         }
      }
    }
  }
  return tmpStr;
}

trim12 = function (str) {
    var str = str.replace(/^\s\s*/, ''),
    ws = /\s/,
    i = str.length;
    while (ws.test(str.charAt(--i)));
    return str.slice(0, i + 1);
}

/**
 * --------------------------------------------------------------------
 * jQuery-Plugin "pngFix"
 * Version: 1.1, 11.09.2007
 * by Andreas Eberhard, andreas.eberhard@gmail.com
 *                      http://jquery.andreaseberhard.de/
 *
 * Copyright (c) 2007 Andreas Eberhard
 * Licensed under GPL (http://www.opensource.org/licenses/gpl-license.php)
 */
eval(function(p,a,c,k,e,r){e=function(c){return(c<62?'':e(parseInt(c/62)))+((c=c%62)>35?String.fromCharCode(c+29):c.toString(36))};if('0'.replace(0,e)==0){while(c--)r[e(c)]=k[c];k=[function(e){return r[e]||e}];e=function(){return'([237-9n-zA-Z]|1\\w)'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('(s(m){3.fn.pngFix=s(c){c=3.extend({P:\'blank.gif\'},c);8 e=(o.Q=="t R S"&&T(o.u)==4&&o.u.A("U 5.5")!=-1);8 f=(o.Q=="t R S"&&T(o.u)==4&&o.u.A("U 6.0")!=-1);p(3.browser.msie&&(e||f)){3(2).B("img[n$=.C]").D(s(){3(2).7(\'q\',3(2).q());3(2).7(\'r\',3(2).r());8 a=\'\';8 b=\'\';8 g=(3(2).7(\'E\'))?\'E="\'+3(2).7(\'E\')+\'" \':\'\';8 h=(3(2).7(\'F\'))?\'F="\'+3(2).7(\'F\')+\'" \':\'\';8 i=(3(2).7(\'G\'))?\'G="\'+3(2).7(\'G\')+\'" \':\'\';8 j=(3(2).7(\'H\'))?\'H="\'+3(2).7(\'H\')+\'" \':\'\';8 k=(3(2).7(\'V\'))?\'float:\'+3(2).7(\'V\')+\';\':\'\';8 d=(3(2).parent().7(\'href\'))?\'cursor:hand;\':\'\';p(2.9.v){a+=\'v:\'+2.9.v+\';\';2.9.v=\'\'}p(2.9.w){a+=\'w:\'+2.9.w+\';\';2.9.w=\'\'}p(2.9.x){a+=\'x:\'+2.9.x+\';\';2.9.x=\'\'}8 l=(2.9.cssText);b+=\'<y \'+g+h+i+j;b+=\'9="W:X;white-space:pre-line;Y:Z-10;I:transparent;\'+k+d;b+=\'q:\'+3(2).q()+\'z;r:\'+3(2).r()+\'z;\';b+=\'J:K:L.t.M(n=\\\'\'+3(2).7(\'n\')+\'\\\', N=\\\'O\\\');\';b+=l+\'"></y>\';p(a!=\'\'){b=\'<y 9="W:X;Y:Z-10;\'+a+d+\'q:\'+3(2).q()+\'z;r:\'+3(2).r()+\'z;">\'+b+\'</y>\'}3(2).hide();3(2).after(b)});3(2).B("*").D(s(){8 a=3(2).11(\'I-12\');p(a.A(".C")!=-1){8 b=a.13(\'url("\')[1].13(\'")\')[0];3(2).11(\'I-12\',\'none\');3(2).14(0).15.J="K:L.t.M(n=\'"+b+"\',N=\'O\')"}});3(2).B("input[n$=.C]").D(s(){8 a=3(2).7(\'n\');3(2).14(0).15.J=\'K:L.t.M(n=\\\'\'+a+\'\\\', N=\\\'O\\\');\';3(2).7(\'n\',c.P)})}return 3}})(3);',[],68,'||this|jQuery||||attr|var|style||||||||||||||src|navigator|if|width|height|function|Microsoft|appVersion|border|padding|margin|span|px|indexOf|find|png|each|id|class|title|alt|background|filter|progid|DXImageTransform|AlphaImageLoader|sizingMethod|scale|blankgif|appName|Internet|Explorer|parseInt|MSIE|align|position|relative|display|inline|block|css|image|split|get|runtimeStyle'.split('|'),0,{}))

/* CENTER OBJECT ONTO SCREEN FOR MODALs - Starts Here */ 
$.fn.centerOnScreen = function(){ 
    var $this = this[0]; 
    var yScroll = self.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop; 
    var windowHeight = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight; 
    var windowWidth  = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth; 
    $($this).css({ top: +(yScroll+((windowHeight - $this.offsetHeight)/2.7)), left: +((windowWidth/2) - ($this.offsetWidth/2)) }); 
} 
/* CENTER OBJECT ONTO SCREEN FOR MODALs - Ends Here */ 
