﻿/* FilterManager is tightly coupled with _templates/ScoreboardLanding.aspx and manages it's UI */
var FilterManager = (function() {
    // private properties/methods
    /////////////////////////////
    var _displayAdvancedFilters = true;
    var _primaryFilterSelection;
    var _advancedFiltersJSON;
    var _primaryFiltersJSON;
    var _setAdvancedFilterProperties;
    var _type;
    var _timerId = false;

    function clearTimer() {
        if (Object.isNumber(_timerId)) {
            window.clearTimeout(_timerId);
        }
        _timerId = false;
    };

    // object literal
    return {
        // Public Members
        /////////////////
        init: function() {
            _primaryFilterSelection = new FilterSelection($('filter-selection-primary'), 'filter-section-primary');

            // instantiate widgets
            // Accordions
            this.accordion = new Accordion.Controller.MultiTabAllClose({
                containerId: "accordion",
                tabSelector: "div#accordion > div.filter-section",
                triggerSelector: "div#accordion h2.accordion-trigger",
                drawerSelector: "div#accordion > div.filter-section > div.accordion-content",
                eventType: "click",
                defaultOpenTab: 0,
                animator: function(accordionToAnimate) {
                    return new Accordion.Animation({
                        accordion: accordionToAnimate, // no need to change this line
                        duration: 0.5,
                        transition: Effect.Transitions.sinoidal
                    });
                }
            });

            this.nestedAccordion = new Accordion.Controller.MultiTabAllClose({
                containerId: "nested-accordion",
                tabSelector: "div#nested-accordion div.filter-set",
                triggerSelector: "div#nested-accordion h3.accordion-trigger",
                drawerSelector: "div#nested-accordion div.nested-accordion-content",
                eventType: "click",
                defaultOpenTab: [0, 1], // setting defaults in markup, e.g. class="open"
                animator: function(accordionToAnimate) {
                    return new Accordion.Animation({
                        accordion: accordionToAnimate,
                        duration: 0.5,
                        transition: Effect.Transitions.sinoidal
                    });
                }
            });

            // default to disabling all primary filters except scoreboards
            $$('div#primary-filter-set fieldset select').each(function(sel, index) {
                if (index > 0) {
                    sel.disable();
                }
            });

            if (LocationHash.keys().length > 0) {
                var scoreboardID = '';
                var carClassID = '';
                var driveTypeID = '';
                var timeTrialID = '';
                var environmentID = '';
                var trackID = '';
				var typeID = '';

                if (LocationHash.include('Scoreboard')) {
                    scoreboardID = LocationHash.get('Scoreboard');
                    var selectedIndex = this.getSelectedIndex('selectPrimaryScoreboard', scoreboardID);
                    $('selectPrimaryScoreboard').selectedIndex = selectedIndex;
                }

                this.toggleAdvancedFilterPanels();

                if (LocationHash.include('CarClass')) { carClassID = LocationHash.get('CarClass'); }
                if (LocationHash.include('Environment')) { environmentID = LocationHash.get('Environment'); }
                if (LocationHash.include('Track')) { trackID = LocationHash.get('Track'); }
                if (LocationHash.include('TimeTrial')) { timeTrialID = LocationHash.get('TimeTrial'); }
                if (LocationHash.include('DriveType')) { driveTypeID = LocationHash.get('DriveType'); }
				if (LocationHash.include('type')) { typeID = LocationHash.get('type'); }

                new Ajax.Request('/ScoreboardService.asmx/GetFilterDataByPrimaryFilterValues',
				{
				    evalJSON: true,
				    contentType: 'application/json',
				    postBody: Object.toJSON({ 'scoreboardID': scoreboardID, 'carClassID': carClassID, 'environmentID': environmentID, 'driveTypeID': driveTypeID, 'trackID': trackID, 'timeTrialID': timeTrialID, 'type': typeID }),
				    onSuccess: function(result) {
				        var primaryFilters = result.responseJSON.d.PrimaryFilters;

						var prevFilterEnabled = true;
				        primaryFilters.each(function(filter) {
				            var listBoxID = 'selectPrimary' + filter;

				            $('filterPrimary' + filter).show();

				            var filterJSON = result.responseJSON.d[filter];

				            if (filterJSON) {
				                for (p in filterJSON) { FilterManager.addOptionToListBox(filterJSON[p], p, listBoxID); }

				                var value = 'NULL';

				                switch (filter) {
				                    case "CarClass":
				                        value = carClassID;
				                        break;
				                    case "Environment":
				                        value = environmentID;
				                        break;
				                    case "Track":
				                        value = trackID;
				                        break;
				                    case "DriveType":
				                        value = driveTypeID;
				                        break;
				                    case "TimeTrial":
				                        value = timeTrialID;
				                        break;
				                }

				                var selectedIndex = FilterManager.getSelectedIndex(listBoxID, value);

				                if (prevFilterEnabled) {
				                    $(listBoxID).enable();
									if (selectedIndex)
					                    $(listBoxID).selectedIndex = selectedIndex;
									else
										prevFilterEnabled = false;
				                } else {
									$(listBoxID).disable();
									_displayAdvancedFilters = false;
								}

								var llinks = $('leaderboardLinks');
								var sellink = llinks.select('li a')[typeID ? (typeID - 0) : 0];
								llinks.select('li a').each(function(lnk) { (lnk === sellink) ? lnk.addClassName('in') : lnk.removeClassName('in'); });
				            }
				        });

				        this.elPanelResults = $$('div[id$=panelResults]').first();
				        var panelResultsID = this.elPanelResults.identify();


				        if (_displayAdvancedFilters) {
				            FilterManager.accordion.enableTab('advancedFiltersSection');
				            $('applyFiltersButton').show();
				        }

				        $('clearFiltersButton').show();

				        _advancedFiltersJSON = result.responseJSON.d.AdvancedFilters;

				        _primaryFilterSelection.clear();
				        _primaryFilterSelection.add('Scoreboard', $('selectPrimaryScoreboard').options[$('selectPrimaryScoreboard').selectedIndex].text);

				        try {
				            result.responseJSON.d.PrimaryFilters.each(function(filter) {
				                var select = $('selectPrimary' + filter);
				                _primaryFilterSelection.add(filter, select.options[select.selectedIndex].text);
				            });
				        }
				        catch (e) { /*console.log(e); */ }

				        if (LocationHash.include('advanced')) {
				            $('spanFiltersApplied').show();
				        }

				        Page.post({ parameters: { setAdvancedFilterProperties: LocationHash.include('advanced'), spinnsterTargetId: this.elPanelResults.identify(), "type": LocationHash.get('type')} });
				    }
				});
            }

            // panel reference for spinnster.
            this.elPanelResults = $$('div[id$=panelResults]').first();
            var panelResultsID = this.elPanelResults.identify();

            // Pagination
            Event.selector('#maincol div.paginav a', 'click', function(e) {
                e.stop();

                var type = LocationHash.get('type') || "0";
                _type = type;
                var lnk = e.element();
                var pageNum = lnk.readAttribute('href').toQueryParams().page;

                Page.post(e, { parameters: { page: pageNum, spinnsterTargetId: panelResultsID, setAdvancedFilterProperties: _setAdvancedFilterProperties, "type": _type} });
            });

            // Subnav links
            Event.selector('#subnav ul#leaderboardLinks li a', 'click', function(e) {
                e.stop();
                var selectedLink = e.element();
                var linkHash = new ParamsHash(selectedLink, '&');
                linkHash.set('type', selectedLink.readAttribute('href').toQueryParams().type);
                linkHash.update(LocationHash.toObject());
                LocationHash.set('type', selectedLink.readAttribute('href').toQueryParams().type);

                selectedLink.up('ul').select('li a').each(function(lnk) { (lnk === selectedLink) ? lnk.addClassName('in') : lnk.removeClassName('in'); });

                Page.post(e, { parameters: { setAdvancedFilterProperties: LocationHash.include('advanced') && LocationHash.get('advanced') == 'true', spinnsterTargetId: panelResultsID, type: selectedLink.readAttribute('href').toQueryParams().type} });
            });

            // DatePicker
            this.startEndDates = new StartEndDates('textStartDate', 'textEndDate', {
                minDate: new Date('10/1/2009')
            });

            // attach event handlers
            $('addManufacturer').observe('click', this.__lnkAddManufacturerClick.bindAsEventListener(this));
            $('removeManufacturer').observe('click', this.__lnkRemoveManufacturerClick.bindAsEventListener(this));

            var boundPrimarySelectChanged = this.__primarySelectChanged.bindAsEventListener(this);
            $$('div#primary-filter-set fieldset select').invoke('observe', 'change', boundPrimarySelectChanged);

            $$('a[id$=linkButtonApply]').first().observe('click', this.__lnkApplyFiltersClick.bindAsEventListener(this));
            $('clearFiltersButton').observe('click', this.__clearFiltersButtonClick.bindAsEventListener(this));
            document.observe('accordion_tab:opened', this.__accordionTabOpened.bindAsEventListener(this));

            // More detail
            Event.selector('table.scoreboard td.time a.more-detail', 'click', this.__moreDetailClick.bindAsEventListener(this));
            // My placement
            Event.selector('table.scoreboard td.gamer a.lnk-my-placement', 'click', function(e) {
                e.stop();
				LocationHash.set('type', '0');
				var llinks = $('leaderboardLinks');
				var firstlink = llinks.select('li a').first();
				llinks.select('li a').each(function(lnk) { (lnk === firstlink) ? lnk.addClassName('in') : lnk.removeClassName('in'); });
                Page.post(e, { parameters: { spinnsterTargetId: panelResultsID, "type": LocationHash.get('type')} });
            });

            Event.selector('table.scoreboard-small td.gamer a.lnk-my-placement', 'click', function(e) {
                e.stop();
				LocationHash.set('type', '0');
				var llinks = $('leaderboardLinks');
				var firstlink = llinks.select('li a').first();
				llinks.select('li a').each(function(lnk) { (lnk === firstlink) ? lnk.addClassName('in') : lnk.removeClassName('in'); });
                Page.post(e, { parameters: { spinnsterTargetId: panelResultsID, "type": LocationHash.get('type')} });
            });
        },

        // event handlers
        /////////////////
        __lnkAddManufacturerClick: function(e) {
            e.stop();
            this.addSelectedManufacturers();
        },

        __lnkApplyFiltersClick: function(e) {
            e.stop();
            LocationHash.set('advanced', true);
            var excludeFilters = $w("XuidFilter FriendFilter");
            var relevantFilters = _advancedFiltersJSON.reject(function(filter) { return excludeFilters.member(filter); })
            var toggleSpanFiltersApplied = false;

            relevantFilters.each(function(filter) {
                if (filter == 'StartDate' || filter == 'EndDate') {
                    var txtDate = $('text' + filter);
                    if (txtDate.present()) {
                        toggleSpanFiltersApplied = true;
                        LocationHash.set('a' + filter, txtDate.value);
                    } else {
                        LocationHash.unset('a' + filter);
                    }
                }
                else if (filter == 'Manufacturer') {
                    var selectedManufacturers = $F('selectAdvancedManufacturerSelected');
                    if (selectedManufacturers == null) {
                        LocationHash.unset('aManufacturer');
                    } else {
                        toggleSpanFiltersApplied = true;
                        LocationHash.set('aManufacturer', $('selectAdvancedManufacturerSelected').childElements().pluck('value'));
                        $('selectAdvancedManufacturerSelected').childElements().each(function(option) { option.selected = true; });
                    }

                } else if (filter == 'Cars') {
                    var selectedCars = $F('selectAdvancedCars');
                    if (selectedCars == null) {
                        LocationHash.unset('aCars');
                    } else {
                        toggleSpanFiltersApplied = true;
                        LocationHash.set('aCars', selectedCars);
                    }

                } else {
                    var selFilter = $('selectAdvanced' + filter);
                    if (selFilter.present()) {
                        LocationHash.set('a' + filter, $F(selFilter));
                        if ($F(selFilter) != '0') {
                            toggleSpanFiltersApplied = true;
                        }
                    } else {
                        LocationHash.unset('a' + filter);
                    }
                }
            });

            _setAdvancedFilterProperties = true;

            Page.post(e, { parameters: { spinnsterTargetId: this.elPanelResults.identify(), type: LocationHash.get('type')} });

            if (toggleSpanFiltersApplied) {
                $('spanFiltersApplied').show();
            }
        },

        __lnkRemoveManufacturerClick: function(e) {
            e.stop();
            this.removeSelectedManufacturers();
        },

        // Exists solely for delaying xhr request when a primary select has changed--use case where the arrow keys are being held down.
        __primarySelectChanged: function(e) {
            clearTimer();
            var selectID = e.findElement('select').identify();
            _timerId = this.dispatchPrimarySelected.bind(this, selectID).delay(0.5);
        },

        // this shared event handler does page.post and fires after the individual event handler
        dispatchPrimarySelected: function(selectID) {
            $('spanFiltersApplied').hide();
            var elSelect = $(selectID);
            switch (selectID) {
                case 'selectPrimaryScoreboard':
                    $('selectPrimaryCarClass').selectedIndex = -1;
                    $('selectPrimaryEnvironment').selectedIndex = -1;
                    $('selectPrimaryTrack').selectedIndex = -1;
                    $('selectPrimaryDriveType').selectedIndex = -1;
                    $('selectPrimaryTimeTrial').selectedIndex = -1;

                    var type = LocationHash.get('type') || "0";

                    _type = type;

                    LocationHash.replace({ 'Scoreboard': $F(elSelect), 'type': type });

                    this.updateFiltersByScoreboardID($F(elSelect), '', '', '', '', '', selectID);

                    if (Object.isUndefined(_primaryFiltersJSON) == false) {
                        _primaryFiltersJSON.each(function(filter) {
                            $('selectPrimary' + filter).disable();
                        });
                    }
                    break;
                case 'selectPrimaryCarClass':
                    LocationHash.set('CarClass', $F(elSelect));
                    this.updateFiltersByScoreboardID($F($('selectPrimaryScoreboard')), $F(elSelect), '', '', '', '', selectID);
                    break;
                case 'selectPrimaryDriveType':
                    LocationHash.set('DriveType', $F(elSelect));
                    this.updateFiltersByScoreboardID($F($('selectPrimaryScoreboard')), '', '', $F(elSelect), '', '', selectID);
                    break;
                case 'selectPrimaryTimeTrial':
                    LocationHash.set('TimeTrial', $F(elSelect));
                    this.updateFiltersByScoreboardID($F($('selectPrimaryScoreboard')), $('selectPrimaryCarClass').visible() ? $F($('selectPrimaryCarClass')) : '', $F($('selectPrimaryEnvironment')), $('selectPrimaryDriveType').visible() ? $F($('selectPrimaryDriveType')) : '', '', $F(elSelect), selectID);
                    break;
                case 'selectPrimaryEnvironment':
                    $('selectPrimaryTrack').selectedIndex = -1;
                    this.updateFiltersByScoreboardID($F($('selectPrimaryScoreboard')), $('selectPrimaryCarClass').visible() ? $F($('selectPrimaryCarClass')) : '', $F($('selectPrimaryEnvironment')), $('selectPrimaryDriveType').visible() ? $F($('selectPrimaryDriveType')) : '', '', '', selectID);
                    LocationHash.set('Environment', $F(elSelect));
                    break;
                case 'selectPrimaryTrack':
                    this.updateFiltersByScoreboardID($F($('selectPrimaryScoreboard')), $('selectPrimaryCarClass').visible() ? $F($('selectPrimaryCarClass')) : '', $F($('selectPrimaryEnvironment')), $('selectPrimaryDriveType').visible() ? $F($('selectPrimaryDriveType')) : '', $F(elSelect), '', selectID);
                    LocationHash.set('Track', $F(elSelect));
                    break;
            }

            _type = LocationHash.get('type');

            Page.post({ target: selectID, element: elSelect, parameters: { setAdvancedFilterProperties: false, spinnsterTargetId: this.elPanelResults.identify(), type: _type} });

            $('selectAdvancedManufacturerSelected').childElements().each(function(option) {
                option.remove();
            });

            $('selectAdvancedCars').childElements().each(function(optgroup) {
                optgroup.remove();
            });
        },

        __clearFiltersButtonClick: function(e) {
            e.stop();
            LocationHash.unset('advanced');

            $$('select').each(function(select) {
                select.selectedIndex = -1;

                if (select.id != 'selectPrimaryScoreboard') {
                    select.childElements().each(function(option) { option.remove(); });
                }
            });

            $('filterPrimaryCarClass').hide();
            $('filterPrimaryEnvironment').hide();
            $('filterPrimaryTrack').hide();
            $('filterPrimaryDriveType').hide();
            $('filterPrimaryTimeTrial').hide();

            $('textStartDate').value = '';
            $('textEndDate').value = '';

            _type = LocationHash.get('type') || "0";

            LocationHash.replace({ 'type': _type });

            FilterManager.accordion.disableTab('advancedFiltersSection');
            FilterManager.accordion.closeTab('advancedFiltersSection');
            FilterManager.accordion.openTab('filter-section-primary');
            Page.post(e, { parameters: { resetLeaderboards: true, type: _type} });
            $('applyFiltersButton').hide();
            $('clearFiltersButton').hide();

            $('selectAdvancedManufacturerSelected').childElements().each(function(optgroup) {
                optgroup.remove();
            });

            $('spanFiltersApplied').hide();
        },

        __accordionTabOpened: function(ce) {
            // an accordion tab has been opened, see if this is the advanced filters, if so, make sure primary filters (index 0 ) is closed
            var filterSectionID = ce.element().identify();
            if (filterSectionID == 'advancedFiltersSection' && this.accordion.isTabOpen(0) == true) {
                this.accordion.closeTab(0);
            }
        },

        // shows/hides more car information
        __moreDetailClick: function(e) {
            e.stop();
            var lnk = e.element();
            var elDetailList = lnk.up('tr').down('ul.more-detail-list');
            if (lnk.hasClassName('open')) {
                new Effect.BlindUp(elDetailList, { duration: 0.25 });
                lnk.removeClassName('open').update("[+]");
            } else {
                lnk.addClassName('open').update("[-]");
                new Effect.BlindDown(elDetailList, { duration: 0.25 });
            }
        },

        // methods
        ///////////
        getSelectedIndex: function(selectID, value) {
            var selectedIndex;
            var select = $(selectID);

            if (select != null) {
                for (var i = 0; i < select.options.length; ++i) {
                    if (select.options[i].value == value) {
                        selectedIndex = i;

                        break;
                    }
                }
            }

            return selectedIndex;
        },

        resetSelects: function() {
            $$('select').each(function(select) { select.selectedIndex = 0; });
        },

        resetSelectedIndexByListBoxID: function(listBoxID) {
            var listBox = $(listBoxID);
            listBox.selectedIndex = 0;
        },

        addSelectedManufacturers: function() {
            $A($('selectAdvancedManufacturer').getElementsByTagName('option')).each(function(option) {
                if (option.selected) {
                    var sourceOption = $('selectAdvancedManufacturerSelected').select('option[value=' + option.value + ']');

                    if (!sourceOption || sourceOption == '') {
                        sourceOption = document.createElement('option');
                        sourceOption.text = option.text;
                        sourceOption.value = option.value;
                        sourceOption.title = option.text;
                        sourceOption.selected = true;

                        $('selectAdvancedManufacturerSelected').options.add(sourceOption);
                    }
                }
            });

            FilterManager.populateCars();
        },

        removeSelectedManufacturers: function() {
            $('selectAdvancedManufacturerSelected').childElements().each(function(option) {
                if (option.selected === true) {
                    if (option.value == 'NULL') {
                        $('selectAdvancedCars').childElements().each(function(optgroup) {
                            optgroup.remove();
                        });

                        option.remove();
                    } else {
                        $('selectAdvancedCars').select('optgroup[label=' + option.text + ']').invoke('remove');
                        option.remove();
                    }
                }
            });

            $('selectAdvancedCars').childElements().each(function(option) { option.remove(); });
        },

        toggleAdvancedFilterPanels: function() {
            var showAdvancedFilters = false;

            for (var i = 0; i < LocationHash.keys().length; ++i) {
                if (LocationHash.keys()[i].startsWith('a')) {
                    showAdvancedFilters = true;
                    break;
                }
            }

            if (showAdvancedFilters) {
                var selectedIndex = 0;

                FilterManager.accordion.enableTab('advancedFiltersSection');
                FilterManager.accordion.openTab('advancedFiltersSection');

                if (LocationHash.include('aBraking') || LocationHash.include('aStabilityTraction') || LocationHash.include('aShifting') || LocationHash.include('aSuggestedLine') || LocationHash.include('aClean')) {
                    FilterManager.nestedAccordion.openTab('filter-set-difficulty');

                    selectedIndex = this.getSelectedIndex('selectAdvancedBraking', LocationHash.get('aBraking'));
                    $('selectAdvancedBraking').selectedIndex = selectedIndex;

                    selectedIndex = this.getSelectedIndex('selectAdvancedStabilityTraction', LocationHash.get('aStabilityTraction'));
                    $('selectAdvancedStabilityTraction').selectedIndex = selectedIndex;

                    selectedIndex = this.getSelectedIndex('selectAdvancedShifting', LocationHash.get('aShifting'));
                    $('selectAdvancedShifting').selectedIndex = selectedIndex;

                    selectedIndex = this.getSelectedIndex('selectAdvancedSuggestedLine', LocationHash.get('aSuggestedLine'));
                    $('selectAdvancedSuggestedLine').selectedIndex = selectedIndex;

                    selectedIndex = this.getSelectedIndex('selectAdvancedClean', LocationHash.get('aClean'));
                    $('selectAdvancedClean').selectedIndex = selectedIndex;
                }

                if (LocationHash.include('aManufacturer') || LocationHash.include('aCars')) {
                    FilterManager.nestedAccordion.openTab('filterCars');

                    if (LocationHash.include('aManufacturer')) {
                        var manufacturerIDs = LocationHash.get('aManufacturer');

                        if (Object.isArray(manufacturerIDs)) {
                            manufacturerIDs.each(function(manufacturerID) {
                                $('selectAdvancedManufacturer').childElements().each(function(option) {

                                    if (option.value == manufacturerID) {
                                        var manufacturerOption = new Element('option', { 'value': option.value, 'title': option.text }).update(option.text);
                                        manufacturerOption.selected = true;

                                        $('selectAdvancedManufacturerSelected').options.add(manufacturerOption);
                                    }
                                });
                            });
                        }
                        else {
                            $('selectAdvancedManufacturer').childElements().each(function(option) {
                                if (option.value == manufacturerIDs) {
                                    var manufacturerOption = new Element('option', { 'value': option.value, 'title': option.text }).update(option.text);
                                    manufacturerOption.selected = true;

                                    $('selectAdvancedManufacturerSelected').options.add(manufacturerOption);
                                }
                            });
                        }
                    }

                    FilterManager.populateCars();
                }

                if (LocationHash.include('aDriveType')) {
                    FilterManager.nestedAccordion.openTab('filterDriveType');
                    selectedIndex = this.getSelectedIndex('selectAdvancedDriveType', LocationHash.get('aDriveType'));
                    $('selectAdvancedDriveType').selectedIndex = selectedIndex;
                }

                if (LocationHash.include('aCarClass')) {
                    FilterManager.nestedAccordion.openTab('filterCarClass');
                    selectedIndex = this.getSelectedIndex('selectAdvancedCarClass', LocationHash.get('aCarClass'));
                    $('selectAdvancedCarClass').selectedIndex = selectedIndex;
                }

                if ((LocationHash.include('aStartDate') || LocationHash.include('aEndDate')) && (LocationHash.get('aStartDate').length > 0 || LocationHash.get('aEndDate').length > 0)) {
                    FilterManager.nestedAccordion.openTab('filterDateRange');
                    $('textStartDate').value = LocationHash.get('aStartDate');
                    $('textEndDate').value = LocationHash.get('aEndDate');
                }
            }
        },

        populateCars: function() {
            var manufacturerIDs;

            try {
                if (LocationHash.include('aManufacturer') && $('selectAdvancedManufacturer').selectedIndex == -1) {
                    manufacturerIDs = LocationHash.get('aManufacturer');
                } else {
                    manufacturerIDs = $F($('selectAdvancedManufacturer'));
                }
            } catch (e) {
                console.log(e);
            }

            if (!manufacturerIDs || manufacturerIDs.length < 1) {
                manufacturerIDs = 'NULL';
            }

            if (!Object.isArray(manufacturerIDs)) {
                var array = new Array();
                array[0] = manufacturerIDs;

                manufacturerIDs = array;
            }

            var carClass = $F('selectPrimaryCarClass');

            if (carClass == '' || !$F('selectPrimaryCarClass')) {
                carClass = $F('selectAdvancedCarClass');
            }

            $('selectAdvancedCars').childElements().each(function(option) {
                if (option.value == 'NULL') {
                    option.remove();
                }
            });

            new Ajax.Request('/ScoreboardService.asmx/GetCarListByManufacturerID',
			{
			    evalJSON: true,
			    contentType: 'application/json',
			    postBody: Object.toJSON({ 'scoreboardID': $F($('selectPrimaryScoreboard')), 'carClass': carClass, 'manufacturerIDs': manufacturerIDs }),
			    onSuccess: function(result) {
			        var carsJSON = result.responseJSON.d.Cars;
			        var carsJSONArray = Object.keys(carsJSON);

			        var optGroupDestination;

			        if (manufacturerIDs.length > 1 || manufacturerIDs[0] == 'NULL') {
			            // check for cars in the hash
			            var selectedCarIDs = LocationHash.get('aCars') || [];
			            if (!Object.isArray(selectedCarIDs)) {
			                selectedCarIDs = [selectedCarIDs];
			            }

			            for (var i = 0; i < carsJSONArray.length; ++i) {
			                var index = parseInt(carsJSONArray[i]);

			                if (!(isNaN(index)) && index < 0) {
			                    // create a new optgroup
			                    optGroupDestination = $('selectAdvancedCars').childElements().find(function(optgroup) { return optgroup.label == carsJSON[carsJSONArray[i]]; });
			                    if (Object.isUndefined(optGroupDestination)) {
			                        optGroupDestination = new Element('optgroup', { 'label': carsJSON[carsJSONArray[i]] });
			                        $('selectAdvancedCars').insert({ bottom: optGroupDestination });
			                    }
			                }
			                else {
			                    // add option to the new optgroup
			                    try {
			                        var carOption = new Element('option', { 'value': carsJSONArray[i], 'title': carsJSON[carsJSONArray[i]] }).update(carsJSON[carsJSONArray[i]]);
			                        if (selectedCarIDs.member(carsJSONArray[i])) {
			                            carOption.selected = true;
			                        }

			                        if (Object.isUndefined(optGroupDestination && carsJSONArray[i] != 'NULL')) {
			                            optGroupDestination = new Element('optgroup', { 'label': carsJSON[carsJSONArray[i]] });
			                        }

			                        optGroupDestination.insert(carOption);
			                    }
			                    catch (e) {
			                        /*console.log(e); */
			                    }
			                }
			            }
			        }
			        else {
			            var label;

			            $('selectAdvancedManufacturer').childElements().each(function(option) {
			                if (option.value == manufacturerIDs[0]) {
			                    label = option.text;
			                }
			            });

			            optGroupDestination = new Element('optgroup', { 'label': label });

			            for (var i = 0; i < carsJSONArray.length; ++i) {
			                var carOption = new Element('option', { 'value': carsJSONArray[i], 'title': carsJSON[carsJSONArray[i]] }).update(carsJSON[carsJSONArray[i]]);

			                if (carOption.value != 'NULL') {
			                    optGroupDestination.insert(carOption);
			                }
			            }

			            $('selectAdvancedCars').insert({ top: optGroupDestination });
			        }

			        var carOption = new Element('option', { 'value': 'NULL', 'title': 'Any' }).update('Any');
			        $('selectAdvancedCars').insert({ top: carOption });
			    }
			});
        },

        updatePrimaryFilters: function(controlID, result) {
            switch (controlID) {
                case 'selectPrimaryScoreboard':
                    FilterManager.hidePrimaryFilters();
                    var primaryFilters = result.responseJSON.d.PrimaryFilters;

                    primaryFilters.each(function(filter) {
                        var listBoxID = 'selectPrimary' + filter;
                        var filterJSON = result.responseJSON.d[filter];

                        $('filterPrimary' + filter).show();

                        if (filterJSON) {
                            FilterManager.clearListBox(listBoxID);

                            for (p in filterJSON) { FilterManager.addOptionToListBox(filterJSON[p], p, listBoxID); }
                        }
                    });

                    break;

                case 'selectPrimaryEnvironment':
                    var trackJSON = result.responseJSON.d.Track;

                    FilterManager.clearListBox('selectPrimaryTrack');

                    for (p in trackJSON) { FilterManager.addOptionToListBox(trackJSON[p], p, 'selectPrimaryTrack'); }

                    $('filterPrimaryTrack').show();

                    break;
            }
        },

        updateAdvancedFilters: function(advancedFilters) {
            FilterManager.accordion.enableTab('advancedFiltersSection');
            $('spanPrimaryFiltersCollapse').show();
            FilterManager.hideAdvancedFilters();

            advancedFilters.each(function(filter) {
                var filterJSON = result.responseJSON.d[filter];
                var filterFieldSetID = 'filter' + filter;
                var listBoxID = 'selectAdvanced' + filter;

                if (filter != 'XuidFilter') {
                    try {
                        if (filter != "StartDate" && filter != "EndDate") {
                            FilterManager.clearListBox(listBoxID);

                            if (filter != 'Cars') {
                                for (p in filterJSON) { FilterManager.addOptionToListBox(filterJSON[p], p, listBoxID); }
                            }

                            FilterManager.resetSelectedIndexByListBoxID(listBoxID);
                            $(filterFieldSetID).show();
                        }
                        else {
                            $('text' + filter).value = '';
                        }
                    }
                    catch (e) {
                    }
                }
            });
        },

        toggleAdvancedFiltersByPrimaryFilterSelections: function() {
            $$('div#primary-filter-set fieldset').each(function(element) {
                if (element.visible()) {
                    $$('div#primary-filter-set fieldset#' + element.id + ' select').each(function(select) {
                        if (select.selectedIndex == -1 && _displayAdvancedFilters == true) { _displayAdvancedFilters = false; }
                    });
                }
            });
        },

        updateFiltersByScoreboardID: function(scoreboardID, carClassID, environmentID, driveTypeID, trackID, timeTrialID, controlID) {
            new Ajax.Request('/ScoreboardService.asmx/GetFilterDataByPrimaryFilterValues',
			{
			    evalJSON: true,
			    contentType: 'application/json',
			    postBody: Object.toJSON({ 'scoreboardID': scoreboardID, 'carClassID': carClassID, 'environmentID': environmentID, 'driveTypeID': driveTypeID, 'trackID': trackID, 'timeTrialID': timeTrialID }),
			    onSuccess: function(result) {
			        $('clearFiltersButton').show();
			        FilterManager.updatePrimaryFilters(controlID, result);

			        _primaryFilterSelection.clear();
			        _primaryFilterSelection.add('Scoreboard', $('selectPrimaryScoreboard').options[$('selectPrimaryScoreboard').selectedIndex].text);

			        _displayAdvancedFilters = true;
			        _primaryFiltersJSON = result.responseJSON.d.PrimaryFilters;
			        FilterManager.toggleAdvancedFiltersByPrimaryFilterSelections();

			        try {
						var prevFilterEnabled = true;
			            _primaryFiltersJSON.each(function(filter) {
			                var select = $('selectPrimary' + filter);
							if (prevFilterEnabled)
				                select.enable();
							else
								select.disable();
			                _primaryFilterSelection.add(filter, select.options[select.selectedIndex].text);
							prevFilterEnabled = prevFilterEnabled && ((filter == 'Scoreboard' && select.selectedIndex != -1) || select.selectedIndex > 0);
			            });
			        }
			        catch (e) { }

			        var advancedFilters = result.responseJSON.d.AdvancedFilters;

			        if (_displayAdvancedFilters == false || advancedFilters.length == 0) {
			            $('applyFiltersButton').hide();
			            $('spanFiltersApplied').hide();
			        }
			        else { $('applyFiltersButton').show(); }

			        if (advancedFilters.length == 0 || _displayAdvancedFilters == false) {
			            FilterManager.accordion.closeTab('advancedFiltersSection');
			            FilterManager.accordion.disableTab('advancedFiltersSection');
						$('advancedFiltersSection').hide();
			            $('spanFiltersApplied').hide();
			        }
			        else if (advancedFilters.length > 0 && _displayAdvancedFilters == true) {
			            _advancedFiltersJSON = advancedFilters;
						$('advancedFiltersSection').show();
			            FilterManager.accordion.enableTab('advancedFiltersSection');
			            $('spanPrimaryFiltersCollapse').show();
			            FilterManager.hideAdvancedFilters();
						$('filter-set-difficulty').show();

			            advancedFilters.each(function(filter) {
			                var filterJSON = result.responseJSON.d[filter];
			                var filterFieldSetID = 'filter' + filter;
			                var listBoxID = 'selectAdvanced' + filter;

			                if (filter != 'XuidFilter') {
			                    try {
			                        if (filter != "StartDate" && filter != "EndDate") {
			                            FilterManager.clearListBox(listBoxID);

			                            if (filter != 'Cars') {
			                                for (p in filterJSON) { FilterManager.addOptionToListBox(filterJSON[p], p, listBoxID); }
			                            }

			                            FilterManager.resetSelectedIndexByListBoxID(listBoxID);
			                            $(filterFieldSetID).show();
			                        }
			                        else {
			                            $('text' + filter).value = '';
			                        }
			                    }
			                    catch (e) {
			                    }
			                }
			            });
			        }
			    },
			    onFailure: this.xhrFailureCallback.bind(this)
			});
        },

        hidePrimaryFilters: function() {
            $('filterPrimaryCarClass').hide();
            $('filterPrimaryDriveType').hide();
            $('filterPrimaryEnvironment').hide();
            $('filterPrimaryTrack').hide();
            $('filterPrimaryTimeTrial').hide();
        },

        hideAdvancedFilters: function() {
            $('filterCarClass').hide();
            $('filterDriveType').hide();
            $('filterCars').hide();
            $('filterBraking').hide();
            $('filterStabilityTraction').hide();
            $('filterShifting').hide();
            $('filterClean').hide();
            $('filterSuggestedLine').hide();
			$('filterDateRange').hide();
			$('filter-set-difficulty').hide();
			$('applyFiltersButton').hide();
        },

        clearListBox: function(listBoxID) {
            var listBox = $(listBoxID);

            if (listBox != null) {
                while (listBox.length > 0) {
                    listBox.remove(0);
                }
            }
        },

        addOptionToListBox: function(text, value, controlID) {
            try {
                var option = document.createElement('option');
                option.text = text;
                option.value = value;
                option.title = text;

                var listBox = $(controlID);

                if (listBox != null) {
                    listBox.options.add(option);
                }
            }
            catch (e) { }
        },

        xhrFailureCallback: function(transport) {
            console.log('something went wrong with the xhr request.\n"' + transport.status + ':' + transport.statusText + '"\ntransport:');
            console.log(transport);
        }
    }
})();
