var global_util = new global_util();

function getCheckedBodyTypes() {
    var cmpModeInput= document.getElementById('compareMode');
    var cmpMode = ' ';
    if (cmpModeInput != null){
        cmpMode = cmpModeInput.value;
    }
    var bodyTypeDiv = document.getElementById('body-type-section');
    var btArray = new Array();
    if (bodyTypeDiv != null) {
        var btCheckboxes = bodyTypeDiv.getElementsByTagName("input");
        for (var i = 0; i < btCheckboxes.length; i++) {
            if (btCheckboxes[i].checked || (cmpMode!= "null" && cmpMode !=' ')) {
                btArray[btArray.length] = btCheckboxes[i].value;
            }
        }
    }

    return btArray;
}

function getAllBodyTypes() {
    var bodyStyles = new Array();
    var paramNames = global_util.paramNames();

    for (var i = 0; i < paramNames.length; i++) {
        if (paramNames[i].indexOf('body_style') == 0) {
            bodyStyles.push(global_util.paramValue(paramNames[i]));
        }
    }

    return bodyStyles;
}

function getCheckedMakes() {
    var mmDiv = document.getElementById('make-model-section');
    var mmInputs = mmDiv.getElementsByTagName('input');
    var makes = new Array();
    for (var i = 0; i < mmInputs.length; i++) {
        if (mmInputs[i].className == 'makes' && mmInputs[i].checked) {
            makes[makes.length] = mmInputs[i].value;
        }
    }
    return makes;
}

function getAllMakes() {
    var makes = new Array();
    var paramNames = global_util.paramNames();

    for (var i = 0; i < paramNames.length; i++) {
        if (paramNames[i].indexOf('make') == 0 && paramNames[i].indexOf('models') < 0) {
            makes.push(global_util.paramValue(paramNames[i]));
        }
    }
/*    if(makes.length == 0) {
        var mmDiv = document.getElementById('make-model-section');
        var mmInputs = mmDiv.getElementsByTagName('input');
        for (var i = 0; i < mmInputs.length; i++) {
            if (mmInputs[i].className == 'makes') {
                makes[makes.length] = mmInputs[i].value;
            }
        }
    }*/

    return makes;
}

function getCheckedModels(makes) {
    var mmTable = new Array();
    for (var i = 0; i < makes.length; i++) {
        var modelDiv = document.getElementById(makes[i] + 'models');
        var modelCheckboxes = modelDiv.getElementsByTagName('input');
        var checkedModels = new Array();
        for (var j = 0; j < modelCheckboxes.length; j++) {
            if (modelCheckboxes[j].checked) {
                checkedModels[checkedModels.length] = modelCheckboxes[j].value;
            }
        }
        if (checkedModels.length == 0) {

            checkedModels = getAllModelsByMake(makes[i]);
        }
        mmTable[mmTable.length] = checkedModels;
    }
    return mmTable;
}

function getAllModels(makes) {

    var mmTable = new Array();
    for (var i = 0; i < makes.length; i++) {
        mmTable[mmTable.length] = getAllModelsByMake(makes[i]);
    }
    return mmTable;
}

function getAllModelsByMake(make){
    var mm = make+'models';
    var rg = /\+/g;
    var newMM = mm.replace(rg, " ");
    var modelDiv = document.getElementById(newMM);
    var modelCheckboxes = modelDiv.getElementsByTagName('input');
    var checkedModels = new Array();
    for (var j = 0; j < modelCheckboxes.length; j++) {
        checkedModels[checkedModels.length] = modelCheckboxes[j].value;
    }
    return checkedModels;
}

function uncheckAllModels(make) {
    var modelDiv = document.getElementById(make + 'models');
    if(modelDiv == null)
    {
        return;
    }
    var modelCheckboxes = modelDiv.getElementsByTagName('input');
    for (var j = 0; j < modelCheckboxes.length; j++) {
        modelCheckboxes[j].checked = false;
    }
}

function getFromYear() {
    var fromDropdown = document.getElementById('start-year');
    return fromDropdown.options[fromDropdown.selectedIndex].text;
}

function getToYear() {
    var toDropdown = document.getElementById('end-year');
    return toDropdown.options[toDropdown.selectedIndex].text;
}

function getFromPrice() {
    var fromPrice = document.getElementById('min_price');
    return fromPrice.value;
}

function getToPrice() {
    var toPrice = document.getElementById('max_price');
    return toPrice.value;
}

function clearAll() {
    for(i=0; i<24; i++) {
        if(i != 3)
            document.getElementById("tile_"+i).innerHTML = "";
    }
}

function getSortType() {
    return document.getElementById('sort-by').value;
}

function getMinMpg() {
    var minMpg = document.getElementById('frommpg');
    return minMpg.value;
}

function getMaxMpg() {
    var maxMpg = document.getElementById('tompg');
    return maxMpg.value;
}

function getCheckedCategories() {
    return getChecked('categories-section');
}

function getCheckedTruckOptions() {
    return getChecked('truck-options-section');
}

function getChecked(divId) {
    var optionsDiv = document.getElementById(divId);
    var optionsArray = new Array();
    if (optionsDiv != null) {
        var checkboxes = optionsDiv.getElementsByTagName("input");
        for (var i = 0; i < checkboxes.length; i++) {
            if (checkboxes[i].checked) {
                optionsArray[optionsArray.length] = checkboxes[i].value;
            }
        }
    }
    return optionsArray;
}

function filterSearch(num) {
    var bodystyles = getCheckedBodyTypes();
    if (bodystyles.length == 0) {
        bodystyles = getAllBodyTypes();
    }

    var lifestyleCategory = document.getElementById("lifestyle").value;

    var startYear = null;
    var endYear = null;
    //only set the years if the value is 'y' to ensure proper rollup mode
    if (document.getElementById("yearsChanged").value == 'y') {
        startYear = getFromYear();
        endYear = getToYear();
    }
    var makes = getCheckedMakes();
    var models = getCheckedModels(makes);
    if (makes.length == 0) {
        makes = getAllMakes();
        models = getAllModels(makes);
    }

    var chkFrmPrice = Number(document.getElementById("min_price").value);
    var chkToPrice = Number(document.getElementById("max_price").value);
    
    if (isNaN(chkFrmPrice) || isNaN(chkToPrice) || chkFrmPrice < 0 || chkToPrice < 0) {
        alert("Please enter the price range from lowest to highest using only numerals not less than zero.");
        return false;
    }
    //form.subject.options[form.subject.selectedIndex].value;
    var fromIndex = document.getElementById("frommpg").selectedIndex;
    var toIndex = document.getElementById("tompg").selectedIndex;
    var chkFromMPG = Number(document.getElementById("frommpg").options[fromIndex].value);
    var chkToMPG = Number(document.getElementById("tompg").options[toIndex].value);

    var minPrice = null;
    var maxPrice = null;
    if (chkFrmPrice > chkToPrice && chkToPrice != "" && chkFrmPrice != "") {
        alert("The minimum price cannot be larger than the maximum price. Please check your values and try again");
        return false;
    } else {
        minPrice = getFromPrice();
        maxPrice = getToPrice();
    }

    if (chkFromMPG > chkToMPG && chkToMPG != "" && chkToMPG != "") {
        alert("The \"from \" Fuel Mileage cannot be larger than the \"to \" Fuel Mileage. Please check your values and try again");
        return false;
    }

    var keywords = null;
    if(global_util.paramValue("keywords_display") != null && global_util.paramValue("keywords_display") != ""){
        keywords = global_util.paramValue("keywords_display");
        if (keywords == 'undefined') {
            keywords = null;
        }
    }

    var hybrid = false;
    var isHybrid = "n";
    if(global_util.paramValue("hybrid") != null && global_util.paramValue("hybrid") != ""){
       hybrid = true;
       isHybrid = "y";
    }
    var sortBy = getSortType();

    var firstRecord = 1;
    var numRecords = 23;

    if(num > 0) {
        firstRecord = (num * 23) + 1;
    }

    var minMpg;
    var maxMpg;
    if (document.getElementById("mpgChanged").value == 'y') {
        minMpg = getMinMpg();
        maxMpg = getMaxMpg();
    }

    var categories = getCheckedCategories();

    var truckOptions = getCheckedTruckOptions();
    // only reset the pagination links if we have not asked for a specific page number
    var resetPagination = (num == null || num == 0);

    var callback = function(objWrapperx) {
        var x = objWrapperx.modelSearchResults;
        //update NML URL entry point on SRP with link passed in by ModelSearchUtil.updateSearch
        if(objWrapperx.badgeBean != null && objWrapperx.badgeBean.url != null) {
            var nmlUrl = objWrapperx.badgeBean.url;

            if(objWrapperx.badgeBean.link_type != 'OEM_DETAIL_PAGE') {
                var urlAddress = ATC.cs.research.ctr.url.getParameter("address");
                nmlUrl = nmlUrl + "&address=" + (urlAddress==null?"":urlAddress);//from url
            }
            if (nmlUrl != null) {
                $('misrp-nml-link').href = nmlUrl;
                $('misrp-nml').show();
                $('misrp-nml').removeClassName("hide");
            } else {
                $('misrp-nml').hide();
            }
        }

        var tiles = x.tiles;
        //alert(x.rollupType);
        //alert(tiles.length);

        if (x.rollupType == 'g' || x.rollupType == 'gymmb') {
            $("ratings-header").hide();
            $("ratings-section").hide();
        } else {
            hideGenInfoText();
            $("ratings-header").show();
//            $("ratings-section").show();
        }

        clearAll();

        for (var i = 0; i < tiles.length; i++) {
            var tile = tiles[i];
            var tileText;
            var position = i;
            if (i >= 3) {
                position++;
            }
             if(i >= 0 && i <= 2){
            rowID = 1;
            }
             if(i >= 3 && i <= 6){
            rowID = 2;
            }
             if(i >= 7 && i <= 10){
            rowID = 3;
            }
            if(i >= 11 && i <= 14){
            rowID = 4;
            }
             if(i >= 15 && i <= 18){
            rowID = 5;
            }
            if(i >= 19 && i <= 22){
            rowID =6;
            }

            if (tile.photo == null || tile.photo == 'null') tile.photo = '';

            if (x.rollupType == "ymm") {
                tileText = printNoBodySingleTile(tile.styleId, tile.year, tile.make, tile.model, position, tile.photo, tile.priceLow, tile.priceHigh, tile.hwyLow, tile.hwyHigh, tile.cityLow, tile.cityHigh, tile.modelId, tile.bodyStyle,rowID,isHybrid, tile.priceLow, tile.priceHigh,tile.AggregateRating,tile.TotalRatingCount,adBodyStyle,lifestyleCategory);
            } else if (x.rollupType == "ymmb") {
                tileText = printBodySingleTile(tile.styleId, tile.year, tile.make, tile.model, position, tile.photo, tile.priceLow, tile.priceHigh, tile.hwyLow, tile.hwyHigh, tile.cityLow, tile.cityHigh, tile.modelId, tile.bodyStyleId, tile.bodyStyle,rowID,isHybrid, tile.priceLow, tile.priceHigh,tile.AggregateRating,tile.TotalRatingCount,adBodyStyle);
            } else if (x.rollupType == "g") {
                //if (tile.minYear == tile.maxYear) {
                //    tileText = printNoBodySingleTile(tile.styleId, tile.year, tile.make, tile.model, position, tile.photo, tile.priceLow, tile.priceHigh, tile.hwyLow, tile.hwyHigh, tile.cityLow, tile.cityHigh, tile.modelId, tile.bodyStyle);
                //} else
                    tileText = printNoBodyMultipleTile(tile.styleId, tile.minYear, tile.maxYear, tile.make, tile.model, i, tile.photo, tile.priceLow, tile.priceHigh, tile.hwyLow, tile.hwyHigh, tile.cityLow, tile.cityHigh, tile.modelId, tile.genId, tile.bodyStyle,rowID,isHybrid, tile.priceLow, tile.priceHigh,tile.AggregateRating,tile.TotalRatingCount,adBodyStyle);
                //}
            } else if (x.rollupType == "gymmb") {
                //if (tile.minYear == tile.maxYear) {
                //    tileText = printBodySingleTile(tile.styleId, tile.year, tile.make, tile.model, position, tile.photo, tile.priceLow, tile.priceHigh, tile.hwyLow, tile.hwyHigh, tile.cityLow, tile.cityHigh, tile.modelId, tile.bodyStyleId, tile.bodyStyle);
                //} else {
                    tileText = printBodyMultipleTile(tile.styleId, tile.minYear, tile.maxYear, tile.make, tile.model, position, tile.photo, tile.priceLow, tile.priceHigh, tile.hwyLow, tile.hwyHigh, tile.cityLow, tile.cityHigh, tile.modelId, tile.bodyStyleGenId, tile.bodyStyle,rowID,isHybrid, tile.priceLow, tile.priceHigh,tile.AggregateRating,tile.TotalRatingCount,adBodyStyle);
                //}
            }
            document.getElementById("tile_"+position).innerHTML = tileText;
        }
        document.getElementById('result-count').innerHTML = formatNumber(x.totalCount);
        if (resetPagination) {

            paginationState = new PaginationState(x.totalCount, 7, 23);
            pagination = new Pagination(paginationState);
            pagination2 = new Pagination(paginationState);

            pagination.showPageWithoutFilter(1);
            pagination2.showPageWithoutFilter(1);

//            document.getElementById('result-count').innerHTML = formatNumber(x.totalCount);

            if(x.totalCount <= 23) {
                document.getElementById('paginationOn1').style.display = "none";
                document.getElementById('paginationOn2').style.display = "none";
            } else {
                document.getElementById('paginationOn1').style.display = "block";
                document.getElementById('paginationOn2').style.display = "block";
            }
        }
        if(document.getElementById('ajax-container-table').style.visibility == "hidden"){
            document.getElementById('ajax-container-table').style.visibility = "visible";
        }
    };
    var ratings = getRatings();
    //call wrapper function instead to get NML entrypoint URL and pass in to callback
    MIBadgeWrapper.updateSearchgetMISingleYearTilesPageBadge(bodystyles, startYear, endYear, makes, models, minPrice, maxPrice, keywords,
            hybrid, sortBy, firstRecord, numRecords, minMpg, maxMpg, truckOptions, categories, ratings, lifestyleCategory,
            callback);
    //ModelSearchUtil.updateSearch(bodystyles, startYear, endYear, makes, models, minPrice, maxPrice, keywords,
    //        hybrid, sortBy, firstRecord, numRecords, minMpg, maxMpg, truckOptions, categories, ratings, lifestyleCategory,
    //        callback);

}
function formatNumber(num){
num += '';
var splitStr = num.split('.');
var splitLeft = splitStr[0];
var splitRight = splitStr.length > 1 ? '.' + splitStr[1] : '';
var regx = /(\d+)(\d{3})/;
 while (regx.test(splitLeft)) {
   splitLeft = splitLeft.replace(regx, '$1' + ',' + '$2');
  }
return splitLeft + splitRight;
}


function applyFilterSearchWithParameters() {
    filterSearch();
}

function updateSortBy()
{
    var eSortBy = $("sort-by");
    var len = eSortBy.options.length;
    if(len > 4)
    {
        return;
    }
    var x = 0;
    var y = sortIDs.length;
    for(x=0; x<y; x++)
    {
        var id = sortIDs[x];
        var name = sortNames[x];
        var eOption = document.createElement("option");
        eOption.setAttribute("id", id);
        eOption.setAttribute("value", id);
        var t = document.createTextNode(name);
        eOption.appendChild(t);
        eSortBy.appendChild(eOption);
    }
}

function fromYearFilter() {
    document.getElementById("yearsChanged").value = 'y';
    fromYearChangedMI();
    updateSortBy();
    applyFilterSearchWithParameters();
    //TODO handle year range changes
}

function toYearFilter() {
    document.getElementById("yearsChanged").value = 'y';
    toYearChangedMI();
    updateSortBy();
    applyFilterSearchWithParameters();
    //TODO handle year range changes
}

function mpgFilter() {
    document.getElementById("mpgChanged").value = 'y';
    applyFilterSearchWithParameters();
}

function bodyTypeChecked(evt) {
    updateCategories();
    applyFilterSearchWithParameters();
}

function makeChecked(evt) {
    evt = (evt) ? evt : ((window.event) ? window.event : "")
    var elem = (evt.target) ? evt.target : evt.srcElement
    var makeString = elem.id;
    if (!elem.checked) {
        uncheckAllModels(makeString);
    }
    applyFilterSearchWithParameters();
}

function modelChecked(evt) {
    evt = (evt) ? evt : ((window.event) ? window.event : "")
    var elem = (evt.target) ? evt.target : evt.srcElement
    var makeString = elem.parentNode.parentNode.parentNode.id.replace('makes', '');
    var makeBox = elem.parentNode.parentNode.parentNode.getElementsByTagName('input')[0];
    if(makeBox == null)
    {
        return;
    }
    // even if they are unchecking the box we don't want to uncheck the make for them, so no if is necessary here
    makeBox.checked = true;
    applyFilterSearchWithParameters();
}

function categoryChecked(evt) {
    applyFilterSearchWithParameters();
}

function hideGenInfoText() {
    if (document.getElementById) {
        document.getElementById('geninfotext').style.visibility = 'hidden';
        document.getElementById('geninfotext').style.display = 'none';
    } else if (document.layers) {
        document.geninfotext.style.visibility = 'hidden';
        document.geninfotext.style.display = 'none';
    } else {
        document.all.geninfotext.style.visibility = 'hidden';
        document.all.geninfotext.style.display = 'none';
    }
}

function showGenInfoText() {
    if (document.getElementById) {
        document.getElementById('geninfotext').style.display = 'block';
        document.getElementById('geninfotext').style.visibility = 'visible';
    } else if (document.layers) {
        document.geninfotext.style.display = 'block';
        document.geninfotext.style.visibility = 'visible';
    } else {
        document.all.geninfotext.style.display = 'block';
        document.all.geninfotext.style.visibility = 'visible';
    }
}



function updateCategories() {

    var callback = function(categoryList) {
        var catContainer = document.getElementById('categories-section');
        var catList = catContainer.getElementsByTagName('ul')[0];
        // remove all categories
        while( catList.firstChild != null ) {
            catList.removeChild( catList.firstChild );
        }
        var myDiv, myP, myLabel, myInput, category;
        for( var i = 0; i < categoryList.length; i++ ) {
            category = categoryList[i];
            var cat = category;
            if((cat != null) && (cat.startsWith("Cargo")))
            {
                cat = "Cargo";
            }
            myInput = document.createElement('input');
            myInput.setAttribute('type','checkbox');
            myInput.className = 'makes';
            myInput.setAttribute('id',cat);
            myInput.setAttribute('name',cat);
            myInput.setAttribute('value',cat);
            myInput.setAttribute('category',category);
            if( document.addEventListener ) {
                myInput.addEventListener('click',categoryChecked, false );
            } else {
                myInput.attachEvent('onclick',categoryChecked );
            }
            myLabel = document.createElement('label');
            myLabel.setAttribute("for", cat);
            myLabel.appendChild(document.createTextNode(category));
            myLi = document.createElement('li');
            myLi.setAttribute('id',category);
            myLi.className = 'category-list-item';
            myLi.appendChild(myInput);
            myLi.appendChild(myLabel);
            catList.appendChild(myLi);
        }
    }
    var bodyTypes = getCheckedBodyTypes();
    if( bodyTypes.length == 0 ) {
        bodyTypes[0] = "All";
    }
    ResearchUtil.getCategories( bodyTypes, callback );
}

/**
 * Gets ratings criteria.
 * @return an array of integers indicating which ratings checkboxes are checked.
 */
function getRatings()
{
    var a = new Array();
    var b = ["1", "2", "3", "4", "5"];
    var rating1 = $("rating1");
    var rating2 = $("rating2");
    var rating3 = $("rating3");
    var rating4 = $("rating4");
    var rating5 = $("rating5");
    if(rating1 == null)
    {
        return b;
    }
    var r1 = rating1.checked;
    var r2 = rating2.checked;
    var r3 = rating3.checked;
    var r4 = rating4.checked;
    var r5 = rating5.checked;
    var y = 0;
    if(r1 == true)
    {
        a[y++] = "1";
    }
    if(r2 == true)
    {
        a[y++] = "2";
    }
    if(r3 == true)
    {
        a[y++] = "3";
    }
    if(r4 == true)
    {
        a[y++] = "4";
    }
    if(r5 == true)
    {
        a[y++] = "5";
    }
    return a;
}

/**
 * Resets all search result filters to the values they had when the page first loaded.
 */
function resetSearchResultFilters()
{
    // Get request parameters.
    var request = new Request();
    // Reset filters.
    setCheckboxes("truck-options-section", false);
    setCheckboxes("ratings-section", true);
    resetFuelMileageFilters();
    resetPriceRangeFilters(request);
    setCheckboxes("categories-section", false);
    setCheckboxes("make-model-section", false);
    setCheckboxes("body-type-section", false);
    resetRangeFilter("start-year", "start_year", true, request);
    resetRangeFilter("end-year", "end_year", false, request);
    // Apply changes.
    applyFilterSearchWithParameters();
}

/**
 * Checks or unchecks all checkboxes within a given container.
 * @param pID the ID of a container.
 * @param pCheck true to check or false to uncheck.
 */
function setCheckboxes(pID, pCheck)
{
    // Verify parameters.
    if(pID == null)
    {
        return;
    }
    if(pCheck == null)
    {
        return;
    }
    if(typeof(pCheck) != "boolean")
    {
        return;
    }
    // Normalize container (may be an ID or may be an element).
    var container = $(pID);
    if(container == null)
    {
        return;
    }
    // Loop through all child nodes.
    var nl = container.childNodes;
    var x = 0;
    var y = nl.length;
    for(x=0; x<y; x++)
    {
        // Get a node.
        var n = nl.item(x);
        // Skip if not an element.
        var nt = n.nodeType;
        if(nt != 1)
        {
            continue;
        }
        var e = n;
        // Skip if not an input element.
        var tn = e.tagName.toLowerCase();
        if(tn != "input")
        {
            setCheckboxes(e, pCheck);
            continue;
        }
        // Skip if not a checkbox.
        var type = e.getAttribute("type");
        if(type != "checkbox")
        {
            continue;
        }
        // Skip if already set.
        if(e.checked == pCheck)
        {
            continue;
        }
        // Toggle check state to fire related event handlers.
        e.click();
    }
}

/**
 * Resets the year range filters.
 * @param request the request parameters.
 */
function resetPriceRangeFilters(request)
{
    // Get original values.
    var min_price = request.getParameter("min_price");
    var max_price = request.getParameter("max_price");
    // Find fields.
    var min_price_field = $("min_price");
    var max_price_field = $("max_price");
    // Reset values.
    min_price_field.value = (min_price == null) ? "" : min_price;
    max_price_field.value = (max_price == null) ? "" : max_price;
}

/**
 * Resets a range filter.
 * @param id the id of the filter to reset.
 * @param name the name of the filter to reset.
 * @param first true to set to the first option or false to set to the last option.
 * @param request the request parameters.
 */
function resetRangeFilter(id, name, first, request)
{
    // Verify parameters.
    if(id == null)
    {
        return;
    }
    if(name == null)
    {
        return;
    }
    if(first == null)
    {
        return;
    }
    if(request == null)
    {
        return;
    }
    if(typeof(first) != "boolean")
    {
        return;
    }
    var field = $(id);
    if(field == null)
    {
        return;
    }
    // Get original values.
    var value = request.getParameter(name);
    if(value == null)
    {
        // A value was not specified, so set to default value.
        // Get number of options.
        var y = field.options.length;
        if(y < 1)
        {
            return;
        }
        // Determine new index.
        var index = (first == true) ? 0 : y - 1;
        // Reset value.
        field.selectedIndex = index;
    }
    else
    {
        // A value was specified, so select the option with the specified value.
        selectOneOptionByValue(id, value);
    }
}

/**
 * Resets the Fuel Mileage filters.
 */
function resetFuelMileageFilters()
{
    // Find fields.
    var from_mpg = $("frommpg");
    var to_mpg = $("tompg");
    if(from_mpg == null)
    {
        return;
    }
    if(to_mpg == null)
    {
        return;
    }
    // Get number of options.
    var yFrom = from_mpg.options.length;
    var yTo = to_mpg.options.length;
    // Set From to the first option.
    if(yFrom > 0)
    {
        from_mpg.selectedIndex = 0;
    }
    // Set To to the last option.
    if(yTo > 0)
    {
        to_mpg.selectedIndex = yTo - 1;
    }
}

/**
 * Switches the MI SRP from generation view to single-year view.
 */
function switchToSingleYearView()
{
    // Get request parameters.
    var request = new Request();
    var parameters = request.getParameters();
    // Assemble a new URL.
    var a = [];
    var z = 0;
    a[z++] = window.location.protocol;
    a[z++] = "//";
    a[z++] = window.location.host;
    a[z++] = window.location.pathname;
    var url = a.join("");
    // Create a form.
    var f = document.createElement("form");
    f.setAttribute("id", "generations");
    f.setAttribute("name", "generations");
    f.setAttribute("method", "get");
    f.setAttribute("action", url);
    // Add all existing parameters except for yearsChanged.
    var x = 0;
    var y = parameters.length;
    for(x=0; x<y; x++)
    {
        var nvp = parameters[x];
        var name = nvp[0];
        var value = nvp[1];
        var v = escape(value);
        if(name == "yearsChanged")
        {
            continue;
        }
        var i = document.createElement("input");
        i.setAttribute("name", name);
        i.setAttribute("type", "hidden");
        i.setAttribute("value", v);
        f.appendChild(i);
    }
    // Add year range filters if they are missing.
    // They will be missing if we got here from the RCLP.
    var start_year = request.getParameter("start_year");
    if(start_year == null)
    {
        var eStartYear = $("start-year");
        var nlStartYear = eStartYear.getElementsByTagName("option");
        var yStartYear = eStartYear.options.length;
        if(yStartYear > 0)
        {
            var xStartYear = 0;
            var oStartYear = nlStartYear.item(xStartYear);
            var vStartYear = oStartYear.getAttribute("value");
            var iStartYear = document.createElement("input");
            iStartYear.setAttribute("name", "start_year");
            iStartYear.setAttribute("type", "hidden");
            iStartYear.setAttribute("value", vStartYear);
            f.appendChild(iStartYear);
        }
    }
    var end_year = request.getParameter("end_year");
    if(end_year == null)
    {
        var eEndYear = $("end-year");
        var nlEndYear = eEndYear.getElementsByTagName("option");
        var yEndYear = eEndYear.options.length;
        if(yEndYear > 0)
        {
            var xEndYear = yEndYear - 1;
            var oEndYear = nlEndYear.item(xEndYear);
            var vEndYear = oEndYear.getAttribute("value");
            var iEndYear = document.createElement("input");
            iEndYear.setAttribute("name", "end_year");
            iEndYear.setAttribute("type", "hidden");
            iEndYear.setAttribute("value", vEndYear);
            f.appendChild(iEndYear);
        }
    }
    // Now add yearsChanged and set it to "y".
    var yc = document.createElement("input");
    yc.setAttribute("name", "yearsChanged");
    yc.setAttribute("type", "hidden");
    yc.setAttribute("value", "y");
    f.appendChild(yc);
    // Add the form to the document.
    var nl = document.getElementsByTagName("body");
    var b = nl.item(0);
    b.appendChild(f);
    // Submit the form.
    f.submit();
}
