/*
        Javascript file for generic engine matrix functionality

*/
// Initial variable setup
var whichFilter = '';
var useSlider = false;
var productMatrixUpdateUrl = "/ajax/getProductMatrix.htm";



// flag used to 'turn off' the submitProductMatrix method.  This will be set to false by method
// that make external modifications to the hp sliders.  This prevents the auto callbacks from
// doing submits at inappropriate times.  Any method that needs to set this to false will need
// to set it back to true and will also be responsible for manually calling the submitProductMatrix
// method
var shouldSubmit = true;

// function to submit the current values of the matrix back to the server.  however, it is
// 'smart' enough to make sure that when the slider is reset to its default values, that the
// action of resetting doesn't cause a submit.
function controlledMatrixSubmit(section) {

    shouldSubmit = false;
    if(useSlider) {
        resetSlider();
    }
    shouldSubmit = true;
    submitProductMatrix(section);

}

function setProductMatrixUpdateUrl(url) {
    productMatrixUpdateUrl = url;

}

function productMatrixUpdate(section, formData, sortby, showAll) {

    var url = productMatrixUpdateUrl + "?" + formData;
    if(sortby!=undefined) {
        url = url + "&sortBy="+sortby;
    } else {
        url = url + "&sortBy=productnumber-asc";
    }
	if(showAll==1) {
        url = url + "&showAll=1";
    }
    $.ajax({
        url: url,
        type: 'GET',
        timeout: 60000,
        error: function(e){
            alert('Error loading product results document');
        },
        success: function(html){
            $('#productmatrix-results')[0].innerHTML = html;
            eval($('#productmatrix-results script').html().replace(/\s/g,' '));
            updatePageData(section, jsonResults);
            
            setHeight();
        }
    });
}

function submitProductMatrixSort(sortBy) {

    if (shouldSubmit){
		var showAll = 1;
        var params = $("#productmatrix-filters").fastSerializeUrlStringIgnoreDisabled();
        if(useSlider) {
            params = $.param(params);

            params += serializeSlider();
        }
		$('.results-page').each(function() {
			if($(this).css("display") == "none") {
				showAll = 0;
			}
		});

        productMatrixUpdate(null, params, sortBy, showAll);
    } else {
        alert ('Skipping the submit now');
    }
}

function submitProductMatrix(section) {

    if (shouldSubmit){

        var params = $("#productmatrix-filters").fastSerializeUrlStringIgnoreDisabled();

        if(useSlider) {
            params = $.param(params);

            params += serializeSlider();
        }

        productMatrixUpdate(section, params,null);
    } else {
        alert ('Skipping the submit now');
    }
}

$.fn.fastSerializeUrlStringIgnoreDisabled = function() {
    //var a = [];
    var a = "";

    $('input,textarea,select,button', this).each(function() {
        var n = this.name;
        var t = this.type;

        if ( !n || (this.disabled && !this.checked) || t == 'reset' ||
            (t == 'checkbox' || t == 'radio') && !this.checked ||
            (t == 'submit' || t == 'image' || t == 'button') && this.form.clicked != this ||
            this.tagName.toLowerCase() == 'select' && this.selectedIndex == -1)
            return;

        if (t == 'image' && this.form.clicked_x)
            return a.push(
                {name: n+'_x', value: this.form.clicked_x},
                {name: n+'_y', value: this.form.clicked_y}
            );

        if (t == 'select-multiple') {
            $('option:selected', this).each( function() {
                a += "&" + n + "=" + encodeURI(this.value);
            });
            return;
        }

        //a.push({name: n, value: this.value});
        a += "&" + n + "=" + encodeURI(this.value);
    });

    return a;
};

// This will 'serialize' the slider and return the values for the lower and upper ranges
// as URL paramters.
function serializeSlider() {

    if(useSlider) {
        var attribName = $(".ui-slider-handle").attr('name');

        return '&filter[' + attribName + ']=' + $('#productmatrix-slider').slider("value", 0) + '&filter['
                + attribName + ']=' + $('#productmatrix-slider').slider("value", 1);
    }

}

// This will take the contents returned from the call to the server and update the left hand
// 'nav' and the products displayed on the page
function updatePageData(section, returnData){
    updateProductMatrixSelections(section, returnData.selects);

    updateProductCount(returnData.count);
    createPagination(returnData.count,1);

    updateProductCompare();
}

function updateProductCount(count){
    $("#productmatrix-count").html(count);
    $("#productmatrix-count-bottom").html(count);
    productCount = count;
}

/*
This will update the selections on the product matrix based on the user chosen values
This code assumes that the div containing the checkboxes is named "selectors-{filterCriteria.name}"
 */
function updateProductMatrixSelections(section, filterCriteria) {

    for (var i = 0; i < filterCriteria.length; i++) {
        // get the div containing the selections for this particular filtercriteria
        $("#selectors-" + filterCriteria[i].name).find("input:checkbox").each(

            // we are forced to loop through each option that is sent back.  If we find the
            // option returned to us, then we stop searching and break.  If we do not find
            // the option returned to us, then we set that particular checkbox to a disabled
            // state, as its absence indicates that it is not a 'legal' value for the user
            // to choose from.
            function() {

                var found = false;
                for (var x = 0; x < filterCriteria[i].options.length; x++){
                    if (this.value == filterCriteria[i].options[x].value){
                        $(this).attr('disabled', false);
                        $(this).next("span").css("color","black");
                        found = true;
                        break;
                    }
                }

                // If we are on the same section, do not disable the others, so we can allow
                // multiple selections
                if (section != filterCriteria[i].name) {
                    if (! found){
                        $(this).attr('disabled', true);
                        $(this).next("span").css("color","gray");
                    }
                }
            }
        );
    }

}

// function will will reset the slider back to the original values
function resetSlider() {

    // just reset the values that have been specified as the min and max on the page that holds
    // the slider data
    setCurrentSliderPositions(sliderMin, sliderMax);
}

function setCurrentSliderPositions(currentPositionLow, currentPositionHight){
    $('#productmatrix-slider').slider("moveTo", currentPositionLow, 0 );
    $('#productmatrix-slider').slider("moveTo", currentPositionHight, 1 );
}

// Gets a list of products in the compare from the server and updates the view.
function updateProductCompare(updatedSelections, callback) {
    $(updatedSelections).attr("disabled", "disabled");
    var checked = [];
    var unchecked = [];
    for (var i in $(updatedSelections).get()) {
        var input = $(updatedSelections)[i];
        if ($(input).is(":checked")) {
            checked.push($(input).val());
        } else {
            unchecked.push($(input).val());
        }
    }

    var addToCompareCheckboxes = $(".productResults-addToCompare input");
    if (addToCompareCheckboxes.size() == 0) {
        return;
    }

    addRemoveProductsFromCompare(checked, unchecked, function(data) {
        addToCompareCheckboxes.attr("disabled", "");
        // put into map for easy lookup
        var compareProducts = {};
        for (var i in data) {
            compareProducts[data[i]] = "1";
        }
        addToCompareCheckboxes.each(function() {
            var productNumber = $(this).val();
            if (compareProducts[productNumber] != null && compareProducts[productNumber] == "1") {
                //$(this).siblings("label").text("Remove from compare");
                $(this).attr("checked", true);
            } else {
                $(this).attr("checked", false);
                //$(this).siblings("label").text("Add to compare");
            }
        });
        if ($.isFunction(callback)) {
            callback();
        }
    });

}

function addRemoveProductsFromCompare(productsToAdd, productsToRemove, callback) {
    var productSection = "";
    if (window.PRODUCT_SECTION) {
        productSection = window.PRODUCT_SECTION;
    }
    
    $.ajax({
        type : "GET",
        dataType : "json",
        url : "/ajax/compare.htm",
        data : { add:productsToAdd, remove:productsToRemove, section:productSection },
        complete : function() {
        },
        success : function(data, textStatus) {
            if ($.isFunction(callback)) {
                callback(data);
            }
        }
    });
}

// This will do the initial binding of functions to events within the page.
$(function() {

    // this will create the slider on the page.  It makes some assumptions about the page.  First,
    // the page that has the productmatrix-slider on it has to set a min and max value into
    // javascript
//    $('#productmatrix-slider').slider({ min: sliderMin, max:sliderMax, range: true, change: function(e,ui) { submitProductMatrix('MAXIMUM_POWER_HP') } });

    // This will fire when the user clicks the All HP link
    // it depends on the 'Select All' link  being in a CSS class called 'filters-selectall'.
    // This assumes that there is a parent div wrapping the link (with the class 'productmatrix-filtername',
    // and that that parent has a sibling div with the class 'productmatrix-selectors'.
    // This will find the checkboxes that exist inside that div and check them all
    $(".filters-hp-selectall").click( function() {
        controlledMatrixSubmit('MAXIMUM_POWER_HP');
        return false;
    });

    // This will fire when the user clicks the equivalent of the 'select all'
    // it depends on the 'Select All' link  being in a CSS class called 'filters-selectall'.
    // This assumes that there is a parent div wrapping the link (with the class 'productmatrix-filtername',
    // and that that parent has a sibling div with the class 'productmatrix-selectors'.
    // This will find the checkboxes that exist inside that div and check them all and then it will
    // also 'enable' the checkbox so that the new selected value can be sent back to the server.
    $(".filters-selectall").click( function() {
        $(this).parents(".productmatrix-filtername").next(".productmatrix-selectors").find(":checkbox").each(
                function() {
                    $(this).attr('disabled', false);
                    this.checked = true;
                }

        )

        // just get the name of one of the checkboxes and pass that on to the 'submit' method.  This is
        // needed so that we can track which one of the attributes the user just clicked
        submitProductMatrix($(this).attr('section'));
        return false;
    });

    $(".productmatrix-selectors").find(":checkbox").click( function() {
        submitProductMatrix($(this).attr('section'));
    });

    $(".filters-resetall").click( function() {
        $(this).parents("#productmatrix-filters").children(".productmatrix-selectors").find(":checkbox").each(
                function() {
                     this.checked = false;
                }

        )

        controlledMatrixSubmit('');
        return false;
    });

    // Engines Matrix Scripts
    $('a.filters-contract').click(
        function() {
            whichFilter = $(this).attr('id');
            if ( $('#selectors-' + whichFilter).is(':visible') ) {
                $('#collapsearrow-' + whichFilter).attr("src", $('#collapsearrow-' + whichFilter).attr("src").replace("-whitedown","-whiteright"));
            } else {
                $('#collapsearrow-' + whichFilter).attr("src", $('#collapsearrow-' + whichFilter).attr("src").replace("-whiteright","-whitedown"));
            }
            $('#selectors-' + whichFilter).toggle();
            return false;
        }
    )
	
	// Scripts to uncheck all
	$('a.clearallfilters').click( function() {
		$("#productmatrix-filters INPUT[type='checkbox']").attr('checked', false);
		submitProductMatrix($(this).attr('section'));
        return false;
    });
	
	// Script to uncheck all of a specific filters checkboxes
	$('a.clear').click( function() {
		var filtersid = $(this).attr("id");
		var clearwhat = filtersid.substring(filtersid.indexOf("-") + 1, filtersid.length);
		$("#mira-resultsFilterGroup-" + clearwhat + " INPUT[type='checkbox']").attr('checked', false);
		submitProductMatrix($(this).attr('section'));
        return false;
    });


    // Product Comparison functionality
    $(".mira-productResults-compareNow a").live("click", function() {
        var anchor = this;
        addRemoveProductsFromCompare(null, null, function(data) {
            if (data.length == 0) {
                $("#lightbox-scrollableArea-productCompare-noProductsError").showLightbox();
            } else {
                window.location.href = $(anchor).attr("href");
            }
        });
        return false;
    });
    $(".mira-productResults-compareNow a").hover(
            function() {
                $(this).text("max. 4 products");
            }, function() {
                $(this).text("Compare now");
            }
    );

    $(".productResults-addToCompare input").live("click", function() {
        var input = this;
        var status = $(input).attr("checked");
        updateProductCompare(input, function() {
            if (status && !$(input).attr("checked")) {
                $("#lightbox-scrollableArea-productCompare-maxNumProdsError").showLightbox();
            }
        });
    });

    $(".productCompare-removeFromCompare").live("click", function() {
        var checked = $("input.productCompare-removeFromCompare:checked").get();
        var removeProds = [];
        for (var i in checked) {
            removeProds.push($(checked[i]).val());
        }
        addRemoveProductsFromCompare([], removeProds, function(data) {
            $(checked).each(function() {
                $(this).parents(".productResult:first").remove();
            });
            if ($(".productResult").size() == 0) {
                $("#productCompare-noProducts").css("display", "block");
                //window.close();
            }
        });
    });

    // Initial product compare state
    updateProductCompare();

    // Align the comparison table the hacky way.
    function alignCompare(compareItemElements) {
        var compareItems = compareItemElements.get();

        // First find the number of columns
        var numColumns = 0;
        var xOffset = 0;
        for (var i in compareItems) {
            var left = $(compareItems[i]).offset().left;
            if (left <= xOffset) {
                break;
            }
            xOffset = left;
            numColumns = numColumns + 1;
        }

        var cells = [];
        var maxListItemHeights = [];
        for (var i in compareItems) {
            var compareItem = compareItems[i];
            var listItems = $(compareItem).find("li.productCompare-listItem").get();
            cells[i] = [];
            for (var j in listItems) {
                cells[i][j] = listItems[j];
            }
        }
        for (var i in cells) {
            for (var j in cells[i]) {
                var maxHeight = maxListItemHeights[j];
                if (maxHeight == null) {
                    maxHeight = 0;
                }
                maxHeight = Math.max(maxHeight, $(cells[i][j]).height());
                maxListItemHeights[j] = maxHeight;
            }
            if (i % numColumns == numColumns - 1 || i == cells.length - 1) {
                for (var z = 0; z <= i % numColumns; z++) {
                    for (var j in cells[i]) {
                        $(cells[i - z][j]).height(maxListItemHeights[j]);
                    }
                }
                maxListItemHeights = [];
            }
        }
    }

    alignCompare($("#prodResults-content.productCompare .productResult"));
});


