var iAutoTrader = {
  checkTimer:null,
  currentWidth:0,
  hashPrefix:"#_",
    currentHash:location.hash,
    historyIndex:0,
    pageStore:[],
  defaultTab:0,
  currentTab:this.defaultTab,
  defaultAJAXArea:"content",
  manyImages:[],
  manyImagesIndex:0,
    zipCode:0,
    stillLoading:false,
    SETEndpoint:"",
    myATC:{
        token:"",
        email:"",
        goBack:false
    },
    di_cta:"",
    isIphone:false,
    thread:null,

    init:function(){
        this.pageStore = [];
        window.addEventListener("load", function(){this.onLoad()}.bind(this), false);
  },

    onLoad:function(){
        this.isIphone = navigator.userAgent.indexOf("iPhone") != -1;
        this.timeouts();
    this.addListeners();
    this.tabSwitch(this.defaultTab, true); // ensures first tab is selected
        this.pageStore[0] = {area:this.defaultAJAXArea, tab:0, content:$(this.defaultAJAXArea).innerHTML, href:"homepage.jsp"}; // store initial page
    this.actionCheck(this.defaultAJAXArea); // since server injects content we have to add event listeners manually

        var c = document.cookie.split(";"), x = "";
        for(var i=0, l=c.length; i<l; i++){
            x = c[i].split("=");
            if(this.stripWhitespace(x[0]) === "ATC_ID"){
                this.di_cta = this.stripWhitespace(x[1]);
                break;
            }
        }

        // todo: anything after is temp for testing
        //this.zipCode = 30189;
        //this.tabSwitch(1);
        //window.setTimeout(function(){this.loadPage("presearch.jsp?fromYear=2002&toYear=2009&make=BMW&makeNice=BMW&model=325I&modelNice=325i&zip=31410", this.defaultAJAXArea);}.bind(this),500);
        //window.setTimeout(function(){this.loadPage("search.jsp?fromYear=2001&toYear=2009&make=ACURA&model=3.2TL&status=both&zip=30005&distance=300&min=&max=&start=0&searchType=classic&page=1", this.defaultAJAXArea);}.bind(this),500);
        //window.setTimeout(function(){this.loadPage("vehicle.jsp?id=180113426&searchType=classic", this.defaultAJAXArea);}.bind(this),500);
        //window.setTimeout(function(){this.loadPage("dealerResults.jsp?zip=30189&distance=10&address=&keywords=", this.defaultAJAXArea);}.bind(this),500);
    },

  addListeners:function(){
    $("logo").addEventListener("click", this.tabSwitch.bind(this,0,false));
    $("col1Click").addEventListener("click", this.tabSwitch.bind(this,1,false));
    $("col2Click").addEventListener("click", this.tabSwitch.bind(this,2,false));
    $("col3Click").addEventListener("click", this.tabSwitch.bind(this,3,false));
    $("light_close").addEventListener("click", this.hideOverlay.bind(this));
    $("upperclose").addEventListener("click", this.hideOverlay.bind(this));
    $("upperclose1").addEventListener("click", this.hideOverlay.bind(this));
    $("multiImageLeft").addEventListener("click", this.previewImagesMove.bindAsEventListener(this,-1));
    $("multiImageRight").addEventListener("click", this.previewImagesMove.bindAsEventListener(this,1));
        $("zipB").addEventListener("click", this.zipClear.bind(this));
        $("login").addEventListener("click", this.logout.bind(this));
        $("aboutLink").addEventListener("click", this.loadPage.bind(this,"about.jsp","content",null,null,null,null));
        $("feedbackLink").addEventListener("click", function(){
            this.loadPage("feedback.jsp?ref=" + escape(this.pageStore[this.pageStore.length-1].href),"content",null,null,null,null);
        }.bind(this));
       //$("ncalLink").addEventListener("click", this.loadPage.bind(this,"ncal.jsp?ncal_id=905400&ct=n&car_id=76467197&dealer_id=20502995&car_year=2007&rdm=1227135481345&num_records=25&systime=&highlightFirstMakeModel=&start_year=1981&keywordsfyc=&keywordsfyc=&keywordsrep=&keywordsrep=&engine=&certified=&body_code=0&fuel=&awsp=false&search_type=both&only_special=1&distance=0&marketZipError=false&search_lang=en&showZipError=n&make=&keywords_display=&color=&page_location=findacar%3A%3Aispsearchform&min_price=&drive=&default_sort=priceDESC&seller_type=b&max_mileage=&style_flag=1&sort_type=priceDESC&address=30342&advanced=y&end_year=2009&doors=&transmission=&max_price=&cardist=831","content",null,null,null,null));
        //$("vehicleLink").addEventListener("click", this.loadPage.bind(this,"vehicle.jsp?ncal_id=905400&ct=n&car_id=76467197&dealer_id=20502995&car_year=2007&rdm=1227135481345&num_records=25&systime=&highlightFirstMakeModel=&start_year=1981&keywordsfyc=&keywordsfyc=&keywordsrep=&keywordsrep=&engine=&certified=&body_code=0&fuel=&awsp=false&search_type=both&only_special=1&distance=0&marketZipError=false&search_lang=en&showZipError=n&make=&keywords_display=&color=&page_location=findacar%3A%3Aispsearchform&min_price=&drive=&default_sort=priceDESC&seller_type=b&max_mileage=&style_flag=1&sort_type=priceDESC&address=30342&advanced=y&end_year=2009&doors=&transmission=&max_price=&cardist=831","content",null,null,null,null));
  //$("makeLink").addEventListener("click", this.loadPage.bind(this,"service_makeProvider.jsp","content",null,null,null,null));
  //$("modelLink").addEventListener("click", this.loadPage.bind(this,"service_modelProvider.jsp?make=AUDI","content",null,null,null,null));
        this.addBigButtonListeners();
  },

  addBigButtonListeners:function(){
        try{
            $("bigFYC").addEventListener("click", this.zipCodeSetup.bind(this,1,null));
            $("bigFYD").addEventListener("click", this.zipCodeSetup.bind(this,2,null));
            $("bigMyATC").addEventListener("click", this.tabSwitch.bind(this,3,false));
        }catch(e){}
    },

  timeouts:function(){
      window.setTimeout(this.checkOrientAndLocation.bind(this), 0);
      this.checkTimer = window.setInterval(this.checkOrientAndLocation.bind(this), 300);
  },

  checkOrientAndLocation:function(){
    if(window.innerWidth != this.currentWidth){
          this.currentWidth = window.innerWidth;
          var orient = this.currentWidth == 320 ? "profile" : "landscape";
          document.body.setAttribute("orient", orient);
          setTimeout(scrollTo, 100, 0, 1);
      }

      if(location.hash != this.currentHash){
          var data = this.getCurrentPageCache();
            this.currentHash = location.hash;

            $(data.area).innerHTML = data.content;
            window.setTimeout(this.tabSwitch.bind(this, data.tab, true), 100);
            window.setTimeout(this.actionCheck.bind(this, data.area), 200);
            window.setTimeout(this.restoreFormState.bind(this, data), 300);
            window.setTimeout(this.hideOverlay.bind(this), 400);
            if(data.tab == 0) this.addBigButtonListeners(); // special edge case for homepage
            if(data.href.indexOf("zip.jsp") != -1){
                // find the previous pages tab (we want to redirect after zip change)
                var key = this.getCurrentPageKey()+1;
                var prevData = this.pageStore[key];
                window.setTimeout(this.addZipListeners.bind(this,((prevData) ? prevData.tab : 0),true), 500);
            }
        }
  },

    restoreFormState:function(data){
        if(!data.formStore) return;
        var f = document.getElementsByTagName("form")[data.formIndex];
        for(var key in data.formStore){
            if(!key) continue;
            f[key].value = data.formStore[key];
        }

    },

    getCurrentPageKey:function(){
        var key = location.hash.substr(this.hashPrefix.length);
        return parseInt((!key) ? 0 : key);
    },

    getCurrentPageCache:function(){
        var data = this.pageStore[this.getCurrentPageKey()];
        return (!data) ? this.pageStore[0] : data;
    },

    loadAd:function(w,h,id){
    return; // todo: chip requested we launch beta ad-less

        this.ajaxLoad("ad.jsp?w=" + w + "&h=" + h + "&id=" + id, function(req){
      $("adspace").innerHTML = req.responseText;
    });
  },

  tabSwitch:function(pos, ignoreLoad){
    switch(pos){
      case 0:
        $("tabIndicator").style.display = "none";
        $("tabText").style.display = "none";
                $("content").className = "contentHP";
                this.currentTab = 0;
        if(!ignoreLoad) this.loadPage("homepage.jsp", this.defaultAJAXArea, null, null, null, this.addBigButtonListeners.bind(this));
        break;
      case 1:
        if(!ignoreLoad && !this.zipCheckOK(pos)) return;
        var f = function(){
                    this.activateTabspace(pos)
                    $("col1Visual").setAttribute("class", "column-1 active");
                }.bind(this);
                if(!ignoreLoad) this.loadPage("service_yearProvider.jsp?first=true&zip=" + this.zipCode, this.defaultAJAXArea, null, null, null, f);
        else f();
                break;
      case 2:
                if(!ignoreLoad && !this.zipCheckOK(pos)) return;
                var f = function(){
                    this.activateTabspace(pos)
                    $("col2Visual").setAttribute("class", "column-2 active");
                }.bind(this);
                if(!ignoreLoad) this.loadPage("dealerSearch.jsp?zip=" + this.zipCode, "content", null, null, null, f);
        else f();
                break;
      case 3:
                var f = function(){
                    this.activateTabspace(pos)
                    $("col3Visual").setAttribute("class", "column-3 active-last");
                }.bind(this);
                if(!ignoreLoad) this.loadPage("my_atc.jsp?token=" + this.myATC.token + "&email=" + this.myATC.email, "content", null, null, null, f);
        else f();
                break;
    }
  },

    activateTabspace:function(tab){
        $("col1Visual").setAttribute("class", "column-1");
        $("col2Visual").setAttribute("class", "column-2");
        $("col3Visual").setAttribute("class", "column-3");
        $("tabIndicator").style.display = "block";
        $("tabText").style.display = "block";
        $("content").className = "content";
        this.currentTab = tab;
    },

    logout:function(){
        this.myATC.token = "";
        this.myATC.email = "";
        $("login").style.display = "none";
        this.tabSwitch(3);
        this.ajaxLoad("logout.jsp");
    },

    zipCheckOK:function(tab){
        if(this.zipCode===0){
            this.activateTabspace(tab)
            this.zipCodeSetup(tab,null);
            return false;
        }
        this.zipDisplay();
        return true;
    },

    zipDisplay:function(){
        $("zipB").innerHTML = " | <span class='zipBottomDisplay'>Change my zip from: " + this.zipCode + "</span>";
    },

    zipClear:function(){
        $("zipB").innerHTML = "";
        var zip = this.zipCode;
        this.zipCode = 0;
        this.zipCodeSetup((this.currentTab === 1 || this.currentTab === 2) ? this.currentTab : 0, zip);
    },

    zipCodeSetup:function(tab, oldZip){
        if(this.zipCode !== 0) this.tabSwitch(tab);
        else{
            this.loadPage("zip.jsp", "content", null, null, null, function(){
                this.tabSwitch(tab, true);
                if(oldZip){
                    $("zip").value = oldZip;
                    $("zip").select();
                }
                window.setTimeout(this.addZipListeners.bind(this,tab,oldZip), 100);
            }.bind(this));
        }
    },

    addZipListeners:function(tab,hasZip){
        $("clearZip").addEventListener("click", function(){$("zip").value = "";});
        var keys = $("keypad").getElementsByTagName("DIV");
        for(var i=0, len = keys.length; i<len; i++){
            var key = keys[i];
            key.addEventListener("click", this.zipKeyPress.bind(this, key.innerText,hasZip));
        }
        $("zipButton").addEventListener("click", this.zipValidate.bind(this, $("zip"), function(tab){
            this.tabSwitch(tab);
        }.bind(this,tab)));
    },

    zipValidate:function(field,onSuccess){
        var zip = field.value;
        if(zip.length !== 5 || isNaN(zip)){
            this.alert("Please enter a 5 digit zipcode.");
            return;
        }
        this.ajaxLoad("zipCheck.jsp?zip=" + zip, function(resp){
            var j = JSON.parse(resp.responseText);
            if(j.error == "true"){
                this.alert("The zip code you entered (" + zip + ") is not valid.");
                return;
            }
            this.zipCode = zip;
            this.zipDisplay();
            onSuccess();
        }.bind(this));
    },

    zipKeyPress:function(key, hasZip){
        var z = $("zip");
        if(z.value.length === 5 && hasZip) z.value = "";
        if(z.value.length < 5) z.value += key;
    },

    makeDisplay:function(fromYr,toYr,zip){
      if(fromYr > toYr){
            this.alert("Please make sure that your beginning year is not later than your ending year.  However, they may be the same.");
            return;
        }
        this.loadPage("service_makeProvider.jsp?fromYear=" + fromYr + "&toYear=" + toYr + "" + "&zip=" + zip + "", "content", null, null, null, null);
      },

      modelDisplay:function(){
        this.loadPage("service_modelProvider.jsp", "content", null, null, null, null);
      },

      criteriaDisplay:function(){
        this.loadPage("presearch.jsp", "content", null, null, null, null);
      },

    showOverlay:function(){
        $("overlay").style.height = document.height + "px";
        this.setOverlayOffsets();
        $("overlay").style.display = "block";
        window.setTimeout(function(){$("overlay").style.height = document.height + "px";}, 500); // sometimes the DOM is slow to update and we wont cover enough
    },

  hideOverlay:function(){
    $("overlay").style.display = "none";
    $("singleImage").style.display = "none";
    $("multiImage").style.display = "none";
    $("alert").style.display = "none";
    $("loading").style.display = "none";
  },

  activateNcalTabs:function(whichOne) {
  if (whichOne == 0)
  {
    $("ncalListingItems").style.display = "block";
    $("ncalSpecialListingItems").style.display = "none";
  }
  else
  {
    $("ncalListingItems").style.display = "none";
    $("ncalSpecialListingItems").style.display = "block";
  }
},

    setOverlayOffsets:function(){
        $("overlay").style.paddingTop = (parseInt(window.pageYOffset) + 30) + "px";
    },

    busy:function(){
        if(!this.stillLoading) return;

        $("loading").style.display = "block";
        this.showOverlay();
  },

    notBusy:function(){
        this.stillLoading = false;
        this.hideOverlay();
    },

    alertWithEvent:function(event, msg){
        event.stopPropagation();
        this.alert(msg)
    },

    alert:function(msg){
        $("alertText").innerHTML = msg;
        $("alert").style.display = "block";
        this.showOverlay();
    },

    previewImage:function(event, pic){
    event.stopPropagation();
    $("imagePreview").src = pic;
    $("singleImage").style.display = "block";
        this.showOverlay();
  },

  previewImages:function(event, images){
    event.stopPropagation();
    window.setTimeout(scrollTo, 100, 0, 1);

    this.manyImages = images;
    this.previewImagesText(1);
    this.manyImagesIndex = 0;
    $("imagePreviewCount").style.display = "block";
    this.preloadImage(this.manyImages[0]);
        $("multiImagePreview").src = this.manyImages[0];
    $("multiImage").style.display = "block";
        this.showOverlay();

        window.setTimeout(function(){
            for(var i=0, l=this.manyImages.length; i<l; i++) this.preloadImage(this.manyImages[i]);
        }.bind(this), 500);
    },

  previewImagesMove:function(event,dir){
    event.stopPropagation();
        var i = 0;
        switch(dir){
      case -1:
        i = (this.manyImagesIndex - 1 >= 0) ? this.manyImagesIndex-1 : this.manyImages.length-1;
        break;
      case 1:
        i = (this.manyImagesIndex + 1 < this.manyImages.length) ? this.manyImagesIndex+1 : 0;
        break;
    }
        this.manyImagesIndex = i;
        $("multiImagePreview").src = this.manyImages[this.manyImagesIndex];
        this.previewImagesText(this.manyImagesIndex+1);
    },

  previewImagesText:function(count){
    $("imagePreviewCount").innerHTML = count + " of " + this.manyImages.length;
  },

  preloadImage:function(src){
    var img = new Image();
    img.src = src;
  },

  submitForm:function(form, href, destination){
        var onsubmit = form.getAttribute("onsubmit");
        if(onsubmit != ""){
            var result = eval(onsubmit);
            if(typeof result  == "function") result = result();
            if(typeof result == "boolean" && !result){
                return;
            }
        }
        var data = $A(form.getElementsByTagName("input")).concat($A(form.getElementsByTagName("select")).concat($A(form.getElementsByTagName("textarea"))));
    var args = $A();
        var cache = this.getCurrentPageCache();
        cache.formStore = {};
        var forms = document.getElementsByTagName("form");
        for(var i=0,l=forms.length; i<l; i++){
            if(forms[i] == form){
                cache.formIndex = i;
                break;
            }
        }

        var zipField = null;
        for(var i=0, len = data.length; i<len; i++){
      var tmp = data[i];
      if(tmp.name === "zip" && tmp.getAttribute("ignore_zip") == null){
                zipField = tmp;
            }
            tmp.value = tmp.value.replace(/(<([^>]+)>)/ig,""); // xss bad!
            cache.formStore[tmp.name] = tmp.value;
            args.push([tmp.name,escape(tmp.value)].join("="));
    }

        var call = this.loadPage.bind(this, href, destination, args, null, form.getAttribute("method") === "post");
        if(zipField){
            this.zipValidate(zipField, call);
        }
        else call();
    },

  ajaxLoad:function(href, onComplete, args, post){
        var req = new XMLHttpRequest();
        req.onerror = function(err){
            this.alert(err);
        }.bind(this);

        req.onreadystatechange = function(){
            if(req.readyState == 4){
        onComplete(req);
            }
    }

        args = (args || []).join("&")
        if(typeof post == "boolean" && post){
            req.open("POST", href, true);
            req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
            req.send(args);
        }
    else{
            req.open("GET", href + ((href.indexOf("?") === -1) ? "?" : "") + args, true);
            req.send(null);
        }
  },

  loadPage:function(href, destination, args, append, post, extraEvent){
        if(href.indexOf("[[inject_token]]")) href = href.replace(/\[\[inject_token\]\]/g, this.myATC.token);
        if(href.indexOf("[[inject_email]]")) href = href.replace(/\[\[inject_email\]\]/g, this.myATC.email);

        this.stillLoading = true;
        window.setTimeout(this.busy.bind(this), 1000);
        this.ajaxLoad(href, function(req){
      this.injectPage(req, destination, append, extraEvent, href);
        this.notBusy();
        }.bind(this), args, post);
  },

  loadPageNoBusy:function(href, destination, args, append, post, extraEvent){
      if(href.indexOf("[[inject_token]]")) href = href.replace(/\[\[inject_token\]\]/g, this.myATC.token);
      if(href.indexOf("[[inject_email]]")) href = href.replace(/\[\[inject_email\]\]/g, this.myATC.email);

      this.ajaxLoad(href, function(req){
    this.injectPage(req, destination, append, extraEvent, href);
      }.bind(this), args, post);
},

  injectPage: function(req, destination, append, extraEvent, href){
    if(this.evalCheck(req.responseText)) return;
        if(req.responseText == null || req.responseText == "null" || req.responseText.length == 0){
            this.alert("Cannot connect to server. Please check that you are connected to a valid WIFI network.");
            return;
        }

        window.setTimeout(scrollTo, 100, 0, 1);

        if(append) $(destination).innerHTML += req.responseText;
        else $(destination).innerHTML = req.responseText;

        this.cachePage(destination, req.responseText, href);
        window.setTimeout(this.actionCheck.bind(this, destination), 100);
        window.setTimeout(this.loadAd.bind(this, 120, 90, "topAd"), 100);
        if(extraEvent) window.setTimeout(extraEvent, 10);


    },

    scrolljectPage:function(content,afterComplete){
       var o = $("master");
       var n = o.cloneNode(true);

       n.style.position = "absolute";
       n.style.left = document.width + "px";
       n.style.width = document.width + "px";
       n.style.top = 0;

       var s = document.width;
       document.body.appendChild(n);
       var divs = n.getElementsByTagName("div");
       for(var i=0,l=divs.length; i<l; i++){
           if(divs[i].id=="content") divs[i].innerHTML = content;
       }

       this.thread = window.setInterval(this.scrollimation.bind(this,s,o,n,afterComplete), 10);
    },

    scrollimation:function(s,o,n,a){
        // todo: iphone doesnt support scrollLeft - its always zero!?
        if(document.body.scrollLeft >= s){
            window.clearInterval(this.thread);
            o.parentNode.removeChild(o);
            n.style.position = "";
            a();
        }

        window.scrollTo(document.body.scrollLeft + 6, 0);
    },

    cachePage:function(dest, rawContent, href){
        var current = this.getCurrentPageKey();
        if(current < this.historyIndex){
            this.pageStore.splice(current+1);
            this.historyIndex = current;
        }

        var key = ++this.historyIndex;
        location.hash = this.hashPrefix + key;
        this.currentHash = this.hashPrefix + key;
        this.pageStore[key] = {
            area: dest,
            tab: this.currentTab,
            content: rawContent,
            href: href
        };

    },

    reDisplayLastCachedPage:function(){
        window.setTimeout(scrollTo, 100, 0, 1);
        var page = this.getCurrentPageCache();
        this.tabSwitch(page.tab, true);
        $(page.area).innerHTML = page.content;
        window.setTimeout(this.actionCheck.bind(this, page.area), 100);
    window.setTimeout(this.loadAd.bind(this, 120, 90, "topAd"), 100);
    },

    stripWhitespace:function(s){
        return s == null ? "" : s.replace(/^\s+|\s+$/g, "");
    },

    evalCheck:function(responseText){
    responseText = this.stripWhitespace(responseText);
    var set = responseText.split("eval:");
    if(set.length === 2){
      eval(set[1]);
      return true;
    }

    return false;
  },

  actionCheck:function(_el){
        var tags = $(_el).getElementsByTagName("a");
    for(var i=0, len = tags.length; i<len; i++){
      var el = tags[i];
      var tmp = el.getAttribute("target");
      if(tmp != null){
        tmp = tmp.split("|");
        if(tmp.length !== 2) continue;
        var url = el.getAttribute("href");
        el.setAttribute("href", "javascript:void(0);");
        el.setAttribute("target", "");

        switch(tmp[0]){
          case "append":
            var func = function(){this.loadPage(url, tmp[1], null, true); el.parentNode.parentNode.removeChild(el.parentNode);}.bind(this);
                        if(!this.actionRowCheck(el, func)) el.addEventListener("click", func);
              break;
          case "replace":
                        var func = this.loadPage.bind(this, url, tmp[1], null, null, null, null);
                        if(!this.actionRowCheck(el, func)) el.addEventListener("click", func);
            break;
          case "singleImage":
                        this.preloadImage(tmp[1]);
                        el.addEventListener("click", this.previewImage.bindAsEventListener(this, tmp[1]));
            break;
          case "manyImage":
            el.addEventListener("click", this.previewImages.bindAsEventListener(this, tmp[1].split(",")));
            break;
                    case "alert":
                        var func = this.alertWithEvent.bindAsEventListener(this, tmp[1]);
                        if(!this.actionRowCheck(el, func)) el.addEventListener("click", func);
              break;
                    case "map":
                        var func = this.logMap.bind(this, url, tmp[1].split(","));
                        if(!this.actionRowCheck(el, func)) el.addEventListener("click", func);
                break;
                    case "phone":
                        var func = this.logPhone.bindAsEventListener(this, url, tmp[1].split(","));
                        if(!this.actionRowCheck(el, func)) el.addEventListener("click", func);
                break;
                }
      }
    }

        tags = $(_el).getElementsByTagName("form");
        for(var i=0, len = tags.length; i<len; i++){
      var el = tags[i];
            var tmp = el.getAttribute("target");
            if(tmp != null){
        tmp = tmp.split("|");
                if(tmp.length !== 2) continue;
        if(tmp[0] == "replace"){
                    var href = el.getAttribute("action");
                    el.setAttribute("action", "javascript:void(0);");
                    el.setAttribute("target", "");
                    el.addEventListener("submit", this.submitForm.bind(this,el,href,tmp[1]));
                }
      }
            this.injectionCheck(el);
        }
  },

  confirmDeleteSearch:function(href){
    var ret = confirm('Are you sure you want to delete this search?');
    if (ret) {
      this.loadPageNoBusy(href, "content", null, null, null, null);
      return true;
    }
    else {
      return false;
    }
  },

  confirmDeleteCar:function(href){
    var ret = confirm('Are you sure you want to delete this car?');
    if (ret) {
      this.loadPageNoBusy(href, "content", null, null, null, null);
      return true;
    }
    else {
      return false;
    }
  },

  actionRowCheck:function(el, func){
        var mum = el.parentNode;
        if(mum.tagName == "DIV" && mum.getAttribute("class") && mum.getAttribute("class").indexOf("cell") != -1){
      mum.addEventListener("click", func);
            return true;
        }
        return false;
    },

    injectionCheck:function(form){
        var tmp = form["inject_email"];
        if(tmp) tmp.value = this.myATC.email;
        tmp = form["inject_token"];
        if(tmp) tmp.value = this.myATC.token;
        tmp = form["inject_zip"];
        if(tmp) tmp.value = this.zipCode;
    },

    gotoMyAtcSearches:function(){
      this.loadPage("savedSearches.jsp?token=" + this.myATC.token + "email=" + this.myATC.email, "content", null, null, null, null);
    },

    gotoCachedPage:function(page){
        var fname = "";
        switch(page){
            case "year":
              fname = "service_yearProvider.jsp";
              break;
            case "make":
                fname = "service_makeProvider.jsp";
                break;
            case "model":
                fname = "service_modelProvider.jsp";
                break;
            case "criteria":
                fname = "presearch.jsp";
                break;
            case "srl":
                fname = "search.jsp";
                break;
            case "myatc_searches":
                fname = "savedSearches.jsp";
                break;
        }

        var currentPage = this.getCurrentPageKey();

        // edge case
        if(page === "year" && this.pageStore[currentPage].href.indexOf("service_yearProvider.jsp?year=") != -1){
            fname = "service_yearProvider.jsp?first=true";
        }

        var tmp = null;
        for(var i=this.pageStore.length-1,end=0; i>=end; i--){
            tmp = this.pageStore[i];
            if(tmp.href.indexOf(fname) != -1 && tmp.href.indexOf(fname) < 100){
              var offset = (currentPage == this.pageStore.length) ? this.pageStore.length-1 : currentPage;
                history.go(-1 * (offset-i))
                return;
            }
        }
    },

    loginNeeded:function(){
        this.myATC.goBack = true;
        this.tabSwitch(3);
    },

    myatcOK:function(token,email){
        $("login").style.display = "inline";
        this.myATC.token = token;
        this.myATC.email = email;
        if(this.myATC.goBack){
            this.myATC.goBack = false;
            history.go(-1);
            window.setTimeout(function(){this.alert("You are now logged in, please try your action again.");}.bind(this), 1500);
        }
        else this.tabSwitch(3);
    },

    myatcBAD:function(email, error){
        this.reDisplayLastCachedPage();
        window.setTimeout(function(){
            this.alert(error)
            $("email").value = email;
            if($("emailConfirm")) $("emailConfirm").value = email;
        }.bind(this),100);
    },

    logMap:function(mapURL, dataset){
        this.logEvent({ATC_ID:this.di_cta, event:"map_lookup", owner_id:dataset[0], car_id:dataset[1], status_indicator:dataset[2], page_name:dataset[3]});
        window.setTimeout(function(){document.location.href = mapURL;}, 750);
    },

    logMapNew:function(url) {
      var img = new Image();
      url += "cache_kill=" + iAutoTrader.logTimeStamp();
      img.src = url;
    },

    logPhotoView:function(url) {
      var img = new Image();
      url += "cache_kill=" + iAutoTrader.logTimeStamp();
      img.src = url;
    },

    logPhone:function(e, tnURL, dataset){
        var kidz = e.currentTarget.childNodes;
        if(kidz.length == 2 && kidz[0].id && kidz[0].id.indexOf("phone2_") != -1 && kidz[0].style.display != "none") return;
        // above lines are hacks so we can support "click to view #" and NOT fire the log event which is bound to the entire container

        this.logEvent({ATC_ID:this.di_cta, event:"phone_call", page_name:dataset[0], owner_id:dataset[1], car_id:dataset[2], status_indicator:dataset[3]});
        window.setTimeout(function(){document.location.href = tnURL;}, 750);
    },

    logPhoneNew:function(url) {
      var img = new Image();
      url += "cache_kill=" + iAutoTrader.logTimeStamp();
      img.src = url;
    },

    logEvent:function(dataset){
        dataset.timestamp = new Date();
        dataset.from = "js";
        var img = new Image();
        img.src = this.SETEndpoint + "?data=" + escape(typeof dataset == "string" ? dataset : JSON.stringify(dataset));
    },

    logTimeStamp:function(){
      var dt = new Date();
      return dt.getTime();
    },

    yft:function(el){
        this._yft(el, 255, 253, 55);
    },

    _yft:function(el, fade_r, fade_g, fade_b){
      var fade_step = 25;

        if(fade_r + fade_g + fade_b != (255 * 3)){
        $(el).style.background = "rgb(" + fade_r + "," + fade_g + "," + fade_b + ")";

            fade_r = ((fade_r >= 255) || (fade_r + fade_step > 255)) ? 255 : fade_r + fade_step;
            fade_g = ((fade_g >= 255) || (fade_g + fade_step > 255)) ? 255 : fade_g + fade_step;
            fade_b = ((fade_b >= 255) || (fade_b + fade_step > 255)) ? 255 : fade_b + fade_step;

            window.setTimeout(this._yft.bind(this, el, fade_r, fade_g, fade_b),
                    ((fade_r == 255) && (fade_g == 253) && (fade_b == 55)) ? 500 : 100);
        }
        else{
            $(el).style.background = "rgb(" + fade_r + "," + fade_g + "," + fade_b + ")";
            fade_r = 255;
            fade_g = 253;
            fade_b = 55;
        }
    }
};

(function(){
    /**! binds and $A() borrowed from Prototype framework (prototype.conio.net) */
    Function.prototype.bind = function(){
    var __method = this, args = $A(arguments), object = args.shift();
    return function(){
      return __method.apply(object, args.concat($A(arguments)));
    }
  }

    Function.prototype.bindAsEventListener = function(){
        var __method = this, args = $A(arguments), object = args.shift();
        return function(event) {
            return __method.apply(object, [event || window.event].concat(args));
        }
    }

    $A = function(it){
    if(!it) return [];
    if(it.toArray) return it.toArray();
    else{
      var results = [];
      for(var i=0, len = it.length; i<len; i++) results.push(it[i]);
      return results;
    }
  }

  $ = function(id){
    return document.getElementById(id);
  }

    /**! json borrowed from http://www.json.org/json2.js */
    if(!this.JSON){JSON=function(){function f(n){return n<10?'0'+n:n;}Date.prototype.toJSON=function(key){return this.getUTCFullYear()+'-'+f(this.getUTCMonth()+1)+'-'+f(this.getUTCDate())+'T'+f(this.getUTCHours())+':'+f(this.getUTCMinutes())+':'+f(this.getUTCSeconds())+'Z';};var cx=/[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,escapeable=/[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,gap,indent,breaker,meta={'\b':'\\b','\t':'\\t','\n':'\\n','\f':'\\f','\r':'\\r','"':'\\"','\\':'\\\\'},rep;function quote(string){return escapeable.test(string)?'"'+string.replace(escapeable,function(a){var c=meta[a];if(typeof c==='string'){return c;}return'\\u'+('0000'+(+(a.charCodeAt(0))).toString(16)).slice(-4);})+'"':'"'+string+'"';}function str(key,holder){var i,k,v,length,mind=gap,partial,value=holder[key];if(value&&typeof value==='object'&&typeof value.toJSON==='function'){value=value.toJSON(key);}if(typeof rep==='function'){value=rep.call(holder,key,value);}switch(typeof value){case'string':return quote(value);case'number':return isFinite(value)?String(value):'null';case'boolean':case'null':return String(value);case'object':if(!value){return'null';}gap+=indent;partial=[];if(typeof value.length==='number'&&!(value.propertyIsEnumerable('length'))){length=value.length;for(i=0;i<length;i+=1){partial[i]=str(i,value)||'null';}v=partial.length===0?'[]':gap?'['+breaker+gap+partial.join(','+breaker+gap)+breaker+mind+']':'['+partial.join(',')+']';gap=mind;return v;}if(rep&&typeof rep==='object'){length=rep.length;for(i=0;i<length;i+=1){k=rep[i];if(typeof k==='string'){v=str(k,value,rep);if(v){partial.push(quote(k)+(gap?': ':':')+v);}}}}else{for(k in value){if(Object.hasOwnProperty.call(value,k)){v=str(k,value,rep);if(v){partial.push(quote(k)+(gap?': ':':')+v);}}}}v=partial.length===0?'{}':gap?'{'+breaker+gap+partial.join(','+breaker+gap)+breaker+mind+'}':'{'+partial.join(',')+'}';gap=mind;return v;}}return{stringify:function(value,replacer,space,linebreak){var i;gap='';indent='';if(space){if(typeof space==='number'){for(i=0;i<space;i+=1){indent+=' ';}}else if(typeof space==='string'){indent=space;}breaker=typeof linebreak!=='string'?'\n':linebreak;}rep=replacer;if(replacer&&typeof replacer!=='function'&&(typeof replacer!=='object'||typeof replacer.length!=='number')){throw new Error('JSON.stringify');}return str('',{'':value});},parse:function(text,reviver){var j;function walk(holder,key){var k,v,value=holder[key];if(value&&typeof value==='object'){for(k in value){if(Object.hasOwnProperty.call(value,k)){v=walk(value,k);if(v!==undefined){value[k]=v;}else{delete value[k];}}}}return reviver.call(holder,key,value);}if(cx.test(text)){text=text.replace(cx,function(a){return'\\u'+('0000'+(+(a.charCodeAt(0))).toString(16)).slice(-4);});}if(/^[\],:{}\s]*$/.test(text.replace(/\\["\\\/bfnrtu]/g,'@').replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,']').replace(/(?:^|:|,)(?:\s*\[)+/g,''))){j=eval('('+text+')');return typeof reviver==='function'?walk({'':j},''):j;}throw new SyntaxError('JSON.parse');}};}();}

    iAutoTrader.init();
})();