/*
 * The Top Picks Module requests information, populates ui with results and stores the results in Car class
 * @requires prototype 1.6.0
 * @requires control.rating_1.6.js
 * @requires effects.js
 */
var TopPicks = {
    index  : 0,  /** index of link-scroll list. (Number) @private */
    rating : null, /** rating container. (Number) @private */
    cars   : $H(), /* hash or name:value pairs. (Array) @private */
    ceil   : 0,
    inTab: false,
    contentId:0, /* server contentId. (Number) @private */
    contentTitle:0,
    consumerRating:0,
    sponsoredContentIds: $A(),
    misCodes: $H(), /* hash of MIS Codes by content-id */
/* use templates for similar data patterns found in prototpye 1.6.0 http://www.prototypejs.org/api/template */
    listTemplate:new Template("<li class=\"#{clazz}\"><div>#{index}.</div><a href=\"javascript:void(0);\" title=\"#{car}\">#{car}</a></li>"),
/**
 * construct the Top Picks module
 *
 * */
    init:function() {
        //this.clearWhiteSpace($$("#overview a","#spins a", "#exp a", "#cust a"));
        this.contentId = this.ServerParams.currentTopPickContentId;
        this.cars.set(this.contentId, $A());
        this.inTab = this.ServerParams.inTab;
        
        if( this.ServerParams.sponsoredContentIds ) {
            this.sponsoredContentIds = this.ServerParams.sponsoredContentIds;
        }
        
        if( this.ServerParams.misCodes ) {
            this.misCodes = this.ServerParams.misCodes;
        }
        
        /* this uses the control.rating_1.6.js. here we're setting up the defaults*/
        this.rating = new Control.Rating('rating_two', {max: 5, rated:false});
        this.setRating(this.ServerParams.initialRating);
        this.setupObserves();
        this.updateButtons();
        this.disableNextPrev("top-pick-previous");
        /* prototype css selector. add css class to the first item in the link-scroll list */
        $$("#link-scroll ol li:nth-child(1)").invoke('addClassName', 'big-bold');
        this.checkCustRating();
        this.getOptionLabel();
    },

    setupObserves:function() {
        $("top-pick-previous").observe("click", this.prev.bind(this));
        /* bind the next and previous functions (found below) to the html elements */
        $("top-pick-next").observe("click", this.next.bind(this));
        this.setupListBindings();
        /* check to see if there is anything in the topPicksSelect combo box. if nothing then exit. */
        if(!$("topPicksSelect")) return;
        $("topPicksSelect").observe("change", this.invokeList.bind(this));
        /* otherwise attach event "change" listner and when something changes call invokeList */
        $A($("topPicksSelect").options).each(function(option) {
            this.cars.set(option.value, $A());
            /* grab the cars hash "$H() and set the option value into an array" */
        }.bind(this));
    },

    /**
     * Updates the Sponsored Header on the New Car Page 'Top Picks' tab
     *
     * @note Static
     */
    updateSponsoredHeader:function() {
        if ((optionValue = arguments[0]) && optionValue == $('topPicksSelect').value)
            $('sponsored-heading').show();
        else
            $('sponsored-heading').hide();
    },

/**
 * iterates through a collection of list items
 * */
    setupListBindings:function() {
        $$("#link-scroll ol li").each(function(li, i) {
            li.writeAttribute("index", i).observe("click", function(e) {
                if(this.contentId == 0) return;
                Effect.Fade("fader", {duration:.3,afterFinish:function() {
                    this.invokeCar(parseInt($(Event.element(e).parentNode).readAttribute("index")));
                    this.updateButtons();
                    if ($("whathot")) $("whathot").hide();
                    //$("content-description").update(li.down().readAttribute("title"))
                    Effect.Appear('fader');
                }.bind(this)});
            }.bind(this));
        }.bind(this));
    },
/**
 * get/set the index and make sure its a number from the first item in the arguments.
 * set the remove the big-bold class from all list items and then add it to the clicked item
 * set the rating for the stars.
 * */
    invokeCar:function() {
        this.index = (!isNaN(arguments[0])) ? arguments[0] : this.index;
        this.linkStyle();
        this.setRating();
            TopPicksList.getStyle(this.contentId, this.index, this.carLoadComplete.bind(this));
        this.updateButtons();
    },
/**
 * create a new car object, get the car to load from the cars $H() then render the car
 * @parameter (String) resp Response from dwr
 * */
    carLoadComplete:function(resp) {
        var myCar = new Car(resp);


        if (this.index == "") this.index = 0;
        this.cars.get(this.contentId)[this.index] = myCar;
        myCar.render();
    },
/**
 * set contentId to the value of the selected option from the topPicksSelect combo box,
 * then ask the server for content based on the value of the combo box then load the link-scroll list
 * */
    invokeList:function() {
        if($("topPicksSelect")){
            this.contentId = $("topPicksSelect").value;
            this.getOptionLabel();
            this.contentTitle = $("topPicksSelect").options[$("topPicksSelect").selectedIndex].text;
        }else{
            this.contentId = this.contentId;
        }
        if (this.contentId == 0) {
            this.disableUI("pick-list");
            $("content-title").update("");
            $("content-description").update("");
            return
        }else{
            this.hideStatus("cover")
        };
        //this.checkCustRating();
        this.showStatus("link-scroll");
        TopPicksList.getTopPicksByContentId(this.contentId, this.listLoadComplete.bind(this));
        TopPicksList.getTopPicksListByContentId(this.contentId, this.generateCompareUrl);
    },

    /**
    * Generate the Compare Vehicles URL based on number of results in selected Top Picks list
    * **/
    generateCompareUrl:function(styleListForCompare) {
        compareThreshold = 4;
        compareStyles = styleListForCompare[0].styleIds;
        compareParam = '';
        compareTemplate = new Template("<a href=\"javascript:parentWindowRedirect(parent,'#{compareUrl}');this.close();void(0)\">Compare Vehicles</a>");
        if (compareStyles.length <= compareThreshold) {
            compareParams = compareStyles.each(function(el,i){
                compareParam = compareParam+'vehicle_number'+(i+1)+'='+el+'&';
            })
            compareUrl = '/research/compare/index.jsp?ignore_session=true&';
        }
        if (compareStyles.length > compareThreshold) {
            compareParams = compareStyles.each(function(el,i){
                compareParam = compareParam+'styleId='+el+'&';
            })
            compareParam = compareParam+'compareMode=CMPRTOP'
            compareUrl = '/research/compare/model-selection-set.jsp?';
        }
        compareParam = compareParam.replace(/\s+/g,'');
        compareUrl = compareUrl+compareParam;
        var compareValues = {
            compareUrl : compareUrl
        }
        $('top-pick-compare').update(compareTemplate.evaluate(compareValues));
    },

    /**
    * checks to see if the topPicksSelect exists, if it does then change the title and description
    * **/
    getOptionLabel:function(){
        if ($("topPicksSelect")) {
            $("topPicksSelect").observe("change", function() {
                if($(this).options[this.selectedIndex].value != 0){
                    $("content-title").update($(this).options[this.selectedIndex].text);
                    this.contentHeight = $("content-title").getHeight()
                    $("content-description").update($(this).options[this.selectedIndex].title);
                    this.descriptionHeight = $("content-description").getHeight();
                }
            });
        }
    },

    /**
     *  Creates a new link-scroll list based on server response
     * @parameter (Array) topPickInfo Array of items returned from the server
     * */
    listLoadComplete:function(topPickInfo) {
        var ols = $("link-scroll").down("ol").update("");
        $A(topPickInfo).each(function(style, i) {
            if (!style) return; // this is really a continue
            ols.insert(this.listTemplate.evaluate({clazz:(i % 2 == 0) ? "zebra-style" : "",index:[i+1], car:[topPickInfo[i]]}));
        }.bind(this));
        $$("#link-scroll ol li:nth-child(1)").invoke('addClassName', 'big-bold');
        this.setupListBindings();
        this.specialEffects(0);
        this.hideStatus("status");
        var ref = "";
        if (document.referrer != '') {
            ref = "&ref="+document.referrer.substring(document.referrer.indexOf("/",9));
        }
        var seoTitle = this.contentTitle.replace(/[&$]/g,"");
        seoTitle = seoTitle.replace(/[^a-zA-Z0-9\~_-]/g,"-")
        seoTitle = seoTitle.replace(/--/g,"-");
        $("seo-asis").update("<img src=\"/no_cache/ac/SEO_nocount.asis?page=/research/inc/top_pick_list.jsp&galleryTopPickContentId="+this.contentId+"&origuri=/research/top-cars/"+this.contentId+"/"+seoTitle+".jsp"+ref+"\" height=\"1\" width=\"1\" />");
    },
    /**
    *  check value of rating then hide/show avg-cust-rating
    * */
    checkCustRating:function(){
        if($("rating").innerHTML == 0){$("avg-cust-rating").hide()} else{$("avg-cust-rating").show()}
    },
/**
 * sets the star rating
 * @parameter (Number) rate The rating of the current car
 * */
    setRating:function(rate) {
        this.rating.setValue(rate);
    },
/**
 * adds effects and updates the detail container
 * */
    next:function() {
        if (this.topPickNext) return;
        if(this.contentId == 0) return;
        if ($("whathot")) $("whathot").hide();
        this.index++;
        this.updateButtons();
        this.specialEffects();
        $('item-num').update(this.index + 1);
    },
/**
 * adds effects and updates the detail container
 * */
    prev:function() {
        if (this.topPickPrevious) return;
        if(this.contentId == 0) return;
        if ($("whathot")) $("whathot").hide();
        this.index--;
        this.updateButtons();
        this.specialEffects();
        $('item-num').update(this.index + 1);
    },
    /**
    * adds effects and calls the invokeCar() function
    * @parameter (Number) not required
    * */
    specialEffects:function(item){
        Effect.Fade("fader", {duration:.3,afterFinish:function(e) {
            Effect.Appear('fader');
            this.invokeCar(item);
        }.bind(this)});
    },
/**
 * checks the position in the link-scroll list and enables or disables the next/previous buttons
 * */
    updateButtons:function() {
        this.olsCount = $A($$("#link-scroll ol li")).size();
        this.topPickPrevious = false;
        this.topPickNext = false;
        if (this.index == this.olsCount - 1) {
            this.disableNextPrev("top-pick-next");
            this.enableNextPrev("top-pick-previous");
            this.topPickNext = true;
            return
        };

        if (this.index == 0) {
            this.disableNextPrev("top-pick-previous");
            this.enableNextPrev("top-pick-next");
            this.topPickPrevious = true;
            return
        };

        if (this.index <= this.olsCount - 1) {
            this.enableNextPrev("top-pick-previous");
            this.enableNextPrev("top-pick-next");
        };

        if (this.index <= 0 && this.olsCount <= 1) {
            this.disableNextPrev("top-pick-next");
            this.disableNextPrev("top-pick-previous");
            return
        };
    },
/**
 * provides disabled state
 * @parameter (String) button Button css id
 * */
    disableNextPrev:function(button) {
        $(button).addClassName("disable-next-previous");
        $$("#" + button + " img").invoke("setStyle", {visibility:"hidden"});
    },
/**
 * provides enable state
 * @parameter (String) button Button css id
 * */
    enableNextPrev:function(button) {
        $(button).removeClassName("disable-next-previous");
        $$("#" + button + " img").invoke("setStyle", {visibility:"visible"});
    },
/**
 * sets the style of the selected item in the link-scroll element
 * */
    linkStyle:function() {
        $$("#link-scroll ol li").invoke('removeClassName', 'big-bold');
        $$("#link-scroll ol li:nth-child" + "(" + (this.index + 1) + ")").invoke('addClassName', 'big-bold');
    },
/**
* add div to target item that displays a status indicator until hideStatus is called.
* used for ajax calls.
* @parameter (String) target CSS id to target for status div
* */
    showStatus:function(target) {

        /*var myTarget = "#" + target;
        if($$(myTarget)[0] == undefined) return;
        var thisLeft = $$(myTarget)[0].cumulativeOffset()[0]+"px";
        var thisWidth = $$(myTarget)[0].getWidth()+"px";
        var thisHeight = $$(myTarget)[0].getHeight()+"px";
        var thisCenterTop = parseInt(thisHeight)/2 + "px";
        //todo: fix the - 50 (trying to show the center)
        var thisCenterLeft = parseInt(thisWidth)/2 - 50 +"px";
        var element = "<div id=\"status\" class=\"status\" style=\"left:"+thisLeft+";height:"+thisHeight+";width:"+thisWidth+"\" >" +
                      "<div style=\"margin:"+thisCenterTop +" 0 0 " + thisCenterLeft +";\">" +
                      "<img src=\"/img/research/ajax-loader.gif\"/>&nbsp;One moment...<div></div>"

        $(target).insert({before:element});*/


        var width = $(target).getStyle("width");
        var height = '180px';//$(target).getStyle("height");
        var nleft = $(target).offsetLeft;
        //todo: clean this mess up.
        var element = "<div id=\"status\" style=\"-moz-opacity:0.8;filter:alpha(opacity=80);background-color:#fff;" +
                      "z-index:1000;position:absolute;padding-top:70px;display:block;margin:0;left:" + nleft + ";width:" + width + ";height:" + height + ";" + "text-align:center\"><img style=\"\" src=\"/img/research/ajax-loader.gif\"/>&nbsp;One moment...</div>"

        $(target).insert({before:element}, function(){
            //todo: see if we can make this work
            $("status").cumulativeOffset({left:left});
        })
    },
/**
*
* */
    hideStatus:function(target) {
        if(!$(target)) return;
        $(target).remove()
    },

    disableUI:function(target){
        var cover = "<div id=\"cover\" style=\"-moz-opacity:0.8;filter:alpha(opacity=80);position:absolute;z-index:1000;top:52px;width:620px;height:230px;background-color:#fff\"></div>"
        $(target).insert({before:cover});
    },

    clearWhiteSpace:function(params){
        params.each(function(id){
            var x = id.href.replace(/ /g, "");
            id.writeAttribute("href", x);
        })
    }
};
/* create an object to hold all of our data */
var Car = Class.create({

    linksTemplate:new Template("<a href=\"javascript:parentWindowRedirect(#{ref},'#{href}');this.close();void(0)\">#{title}</a>"),
    initialize:function(resp) {
        /* using the response from the server save all the information */
        /* why do this? allows the browser to cache the information for later/repeated use.  */
        Object.extend(this, resp);
    },
    checkData:function(item, val){
        if(item != item || item == null){
            return val
        }else{
            return item
        }
    },
    render:function() {
        /* update the ui */
        var ref = (!TopPicks.inTab) ? "window.opener" : "parent", seperator = " ", ymm="";

        this.cleanYear = this.checkData(this.year, " ");
        this.cleanMake = this.checkData(this.make, " ");
        this.cleanModel = this.checkData(this.model, " ");
        this.cleanTrimLevel = this.checkData(this.style, " ");
        this.cleanPrice = this.checkData(this.price, " ");
        this.cleanImgUrl = this.checkData(this.imageUrl, "/img/research/shared/image_not_available.gif" );
        this.cleanConsumerCount = this.checkData(this.consumerReviewCount, " ");
        this.cleanEPAH = this.checkData(this.epaAutoHighway, "NA");
        this.cleanEPAC = this.checkData(this.epaAutoCity, "NA");
        ymm = this.cleanYear + seperator + this.cleanMake + seperator + this.cleanModel;

        $('ymm').update(ymm);
        $("trimLevel").update(this.cleanTrimLevel);
        $("price").update(this.addCommas(this.cleanPrice, "missing data"));
        //def 24436
        $("imgurl").writeAttribute({"src": this.cleanImgUrl, "title": ymm, "alt": ymm});
        $("consumerreviewcount").update(this.cleanConsumerCount);
        $("item-num").update(TopPicks.index + 1);

        if(this.cleanEPAH != "NA"){
            $('epahwy').update(this.cleanEPAH);
            $("na-mpg-h").update("MPG");
        }else{
            $('epahwy').update("");
            $("na-mpg-h").update("N/A");
        };

        if(this.cleanEPAH != "NA"){
            $('epacity').update(this.cleanEPAC);
            $("na-mpg-c").update("MPG");
        }else{
            $('epacity').update("");
            $("na-mpg-c").update("N/A");
        };

        if (this.consumerRating == null || this.consumerRating == 0) {
            this.consumerRating = 0;
            $("rating").update(0);
            $("avg-cust-rating").hide();
        }else{
            $("avg-cust-rating").show();
            $("rating").update(this.consumerRating);
            TopPicks.setRating(this.consumerRating);
        };

        if (this.overViewUrl){
            $("overview").show();
            $("overview").update(this.linksTemplate.evaluate({ref:ref,href:this.overViewUrl + '&rdpage=RCTPPOP', title:"Overview"}));
        }else{
            $("overview").hide();
        };

         if (this.expReviewUrl){
            $("exp").show();
            $("exp").update(this.linksTemplate.evaluate({ref:ref,href:this.expReviewUrl + '&rdpage=RCTPPOP', title:"Expert Reviews"}));
        }else{
            $("exp").hide();
        };

        if (this.consReviewUrl){
            $("cust").show();
            $("cust").update(this.linksTemplate.evaluate({ref:ref,href:this.consReviewUrl + '&rdpage=RCTPPOP', title:"Customer Reviews"}));
        }else{
            $("cust").hide();
        };

        if (this.spinUrl){
            $("spins").show();
            $("spins").update(this.linksTemplate.evaluate({ref:ref,href:this.spinUrl + '&rdpage=RCTPPOP', title:"360&deg; Spins"}));
        }else{
            $("spins").hide();
        };
        /*$("overview").update(this.linksTemplate.evaluate({ref:ref,href:this.overViewUrl.replace(/ /g, ""), title:"Overview"}));
        $("spins").update(this.linksTemplate.evaluate({ref:ref,href:this.spinUrl.replace(/ /g, ""), title:"360&deg; Spins"}));
        $("exp").update(this.linksTemplate.evaluate({ref:ref,href:this.expReviewUrl.replace(/ /g, ""), title:"Expert Reviews"}));
        $("cust").update(this.linksTemplate.evaluate({ref:ref,href:this.consReviewUrl.replace(/ /g, ""), title:"Customer Reviews"}));*/
    },

    addCommas: function(strValue) {
        var objRegExp = new RegExp('(-?[0-9]+)([0-9]{3})');
        while (objRegExp.test(strValue)) {
            strValue = strValue.replace(objRegExp, '$1,$2');
            strValue = "$" + strValue;
        }
        return strValue;
    }
});

/* prefered method is document.observe("dom:loaded", TopPicks.init.bind(TopPicks)); */
Event.observe(window, "load", TopPicks.init.bind(TopPicks));