﻿
function RowFilter(attributeName, selectedValues){
    this.AttributeName = attributeName;
    this.SelectedValues = selectedValues;
}

var gridFilter = new function() {

    this.ReloadBaseUrl = window.location.pathname;

    this.JsonUrlBase = '/Json/TicketsJsonHandler.ashx';

    this.RowCssClass = "tn_results_standard_row";

    this.RowAltCssClass = "tn_results_alternate_row";

    this.CurrentRowCssClass = this.RowCssClass;

    this.DaysOfWeek = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];

    // holds ref to each row in grid as an array
    this.ResultRows = new Array();

    // each item in array is keyed to a filter type
    // each item holds an array of all possible values for the filter
    this.AttrOptions = new Array();

    // each item in array is keyed to a filter type
    // each item holds an array of booleans indicating if that filter value matches any visible rows
    this.AttrOptionsAvailable = new Array();

    // each item in array is keyed to a filter type
    // each item holds an array of HTML snippets for each checkbox of a filter
    this.AttrOptionsHtml = new Array();

    // each item in array is keyed to a filter type
    // each item holds an array of selected filter options
    // if the array for a filter type is empty, then that filter will "show all"
    this.RowFilters = new Array();

    // name value collection representing the parameters for which the current search was executed
    // these parameters are used for ajax data refreshes when a new date is selected
    this.SearchParameters = new Array();

    // each item in array is keyed to a filter type
    // each item holds an array of values used to filter each row
    this.RowAttr = new Array();

    this.AttrCount = new Array();

    this.foo = false;

    this.parseGrid = function() {

        this.ResultRows = new Array();

        this.AttrOptions = new Array();

        this.AttrOptionsHtml = new Array();

        this.RowFilters = new Array();

        this.ResultRows = this.getAllRows();

        this.resetFilter('eventName');
        this.resetFilter('location');
        this.resetFilter('dayOfWeek');
        this.resetFilter('dayPart');

        this.RowAttr['eventName'] = new Array();
        this.RowAttr['location'] = new Array();
        this.RowAttr['dayOfWeek'] = new Array();
        this.RowAttr['dayPart'] = new Array();

        for (var rowIndex = 0, len = this.ResultRows.length; rowIndex < len; rowIndex++) {

            this.parseFilterValue(rowIndex, "td.tn_results_event_text a", "eventName");

            this.parseFilterValue(rowIndex, "span.tn_results_location_text", "location");

            this.parseFilterValue(rowIndex, "span.tn_results_day_text", "dayOfWeek");

            this.parseFilterValue(rowIndex, "span.tn_results_time_text", "dayPart");

            // store the row index so that when rows are viewed in subset, we have ref to index in complete set
            $(this.ResultRows[rowIndex]).find('tr').first().attr('rowIndex', rowIndex);

        }

        this.renderAttrOptions('eventName');
        this.renderAttrOptions('location');
        this.renderAttrOptions('dayOfWeek');
        this.renderAttrOptions('dayPart');

        this.showTopThree('location');
    }


    this.getAllRows = function() {
        return $('#MainColumn table.tn_results tbody tr[class=' + this.RowCssClass + '],#MainColumn table.tn_results tbody tr[class=' + this.RowAltCssClass + ']');
    }

    this.getVisibleRows = function() {
        return $('#MainColumn table.tn_results tbody tr[class=' + this.RowCssClass + ']:visible,#MainColumn table.tn_results tbody tr[class=' + this.RowAltCssClass + ']:visible');
    }

    this.getTopThree = function(filterName) {

        var topThreeValues = ['', '', ''];
        var topThreeCounts = [0, 0, 0];

        for (filterValue in this.AttrCount[filterName]) {

            var attrCount = this.AttrCount[filterName][filterValue];

            if (attrCount > topThreeCounts[0]) {

                topThreeValues.unshift(filterValue);
                topThreeValues.pop();

                topThreeCounts.unshift(attrCount);
                topThreeCounts.pop();
            }
            else if (attrCount > topThreeCounts[1]) {
                topThreeCounts[2] = topThreeCounts[1];
                topThreeValues[2] = topThreeValues[1];

                topThreeCounts[1] = attrCount;
                topThreeValues[1] = filterValue;
            }
            else if (attrCount > topThreeCounts[2]) {
                topThreeCounts[2] = attrCount;
                topThreeValues[2] = filterValue;
            }
        }

        return topThreeValues;
    }

    this.showTopThree = function(filterName) {
        var topThree = this.getTopThree(filterName);
        for (var i = 0; i < 3; i++) {
            var filterValue = topThree[i];
            $('#filterParameter_' + filterName + ' ul li.ticketFilter_li_' + filterName + '[filterValue=' + filterValue + ']').addClass('filterParameterTopThree');
        }
    }

    this.resetFilter = function(filterName) {
        this.AttrOptions[filterName] = new Array();
        this.RowFilters[filterName] = new Array();
        this.AttrOptionsHtml[filterName] = new Array();
        this.AttrCount[filterName] = new Array();
        $('#filterParameter_' + filterName + ' ul li input.ticketFilter_checkBox_' + filterName + '_showAll:checkbox').attr('checked', true);
        $('#filterParameter_' + filterName + ' ul li.ticketFilter_li_' + filterName).remove();
    }

    this.parseFilterValue = function(rowIndex, selector, filterName) {

        var filterValue = $(this.ResultRows[rowIndex]).find(selector).first().html();

        if (filterName == 'dayPart')
            filterValue = this.getDayPart(filterValue);

        var filterIndex = $.inArray(filterValue, this.AttrOptions[filterName]);

        if (filterIndex < 0) {

            filterIndex = this.AttrOptions[filterName].length;

            this.AttrOptions[filterName][filterValue] = filterValue;

            var displayValue = this.truncateToWord(filterValue, 25);

            this.AttrOptionsHtml[filterName][filterValue] =
            '<li class="ticketFilter_li_' + filterName + '" filterValue="' + filterValue + '">' +
            '<input type="checkbox" value="' + filterValue +
            '" class="ticketFilter_checkBox_' + filterName +
            '" onclick="gridFilter.ticketFilter_checkBox_click(this, \'' + filterName + '\')" />' +
            displayValue + '</li>';

        }

        this.RowAttr[filterName][rowIndex] = filterValue.replace("\&amp;", "\&");

        if (this.AttrCount[filterName][filterValue] == null) {
            this.AttrCount[filterName][filterValue] = 0;
        }
        else {
            this.AttrCount[filterName][filterValue]++;
        }
    }

    this.getSortableFilterValue = function(filterName, filterValue) {

        if (filterName == 'dayOfWeek')
            return $.inArray(filterValue, this.DaysOfWeek) + '';

        if (filterName == 'dayPart')
            return filterValue == 'Daytime' ? '0' : '1';

        return filterValue.replace("\,", " - ").replace("\&amp;", "\&");
    }

    this.renderAttrOptions = function(filterName) {

        var sortedValues = new Array();
        var sortedKeys = new Array();

        $('#filterParameter_' + filterName).show();

        for (filterValue in this.AttrOptions[filterName]) {
            var sortableFilterValue = this.getSortableFilterValue(filterName, filterValue);
            sortedValues[sortableFilterValue] = filterValue;
            sortedKeys.push(sortableFilterValue);
        }

        if (sortedKeys.length < 2) {
            $('#filterParameter_' + filterName).hide();
            return;
        }

        sortedKeys.sort();

        for (var i = 0, len = sortedKeys.length; i < len; i++) {
            var sortedKey = sortedKeys[i];
            $('#ticketFilter_list_' + filterName).append(this.AttrOptionsHtml[filterName][sortedValues[sortedKey]]);
        }
    }


    this.ticketFilter_checkBox_click = function(checkbox, filterName) {
        this.parseFilterCheckBoxes(filterName);
        this.boldCheckedItems(filterName);
        this.toggleOptionDisplay(filterName);
    }

    this.parseFilterCheckBoxes = function(filterName) {

        var rowFilters = this.getRowFiltersFromCheckBoxes(filterName);

        // if there is no change in filter, we're done (maybe showall was clicked)
        var arrayAreTheSame = this.arraysAreSame(rowFilters, this.RowFilters[filterName])

        if (arrayAreTheSame)
            return;

        $('#filterParameter_' + filterName + ' ul li input.ticketFilter_checkBox_' + filterName + '_showAll:checkbox').attr('checked', (rowFilters.length < 1));

        this.RowFilters[filterName] = rowFilters;

        this.applyFilters(filterName);
    }

    this.getRowFiltersFromCheckBoxes = function(filterName) {
        var rowFilters = new Array();

        var selectedItems = $('#filterParameter_' + filterName + ' ul li input.ticketFilter_checkBox_' + filterName + ':checkbox:checked');

        for (var i = 0, len = selectedItems.length; i < len; i++) {
            var selectedValue = $(selectedItems[i]).val();
            if (selectedValue == '')
                continue;
            rowFilters.push(selectedValue);
        }

        return rowFilters;
    }

    this.setRowFilterCheckBoxes = function(filterName) {
        // first, uncheck the boxes
        $('#filterParameter_' + filterName + ' ul li input.ticketFilter_checkBox_' + filterName + ':checkbox').attr('checked', false);

        var rowFilter = this.RowFilters[filterName];

        if (rowFilter.length > 0) {
            $('#filterParameter_' + filterName + ' ul li.ticketFilter_li_' + filterName).show();
            $('#filterParameter_' + filterName + ' ul li input.ticketFilter_checkBox_' + filterName + '_showAll:checkbox').attr('checked', false);

            for (var i = 0, len = rowFilter.length; i < len; i++) {
                $('#filterParameter_' + filterName + ' ul li input.ticketFilter_checkBox_' + filterName + ':checkbox[value=' + rowFilter[i] + ']').attr('checked', true);
            }

            this.boldCheckedItems(filterName);
        }
        else {
            $('#filterParameter_' + filterName + ' ul li.ticketFilter_li_' + filterName).show();
            $('#filterParameter_' + filterName + ' ul li input.ticketFilter_checkBox_' + filterName + '_showAll:checkbox').attr('checked', true);
        }

    }

    this.arraysAreSame = function(array1, array2) {

        if (this.arrayIsNullOrEmpty(array1) && this.arrayIsNullOrEmpty(array2)) {
            return true;
        }

        if (this.arrayIsNullOrEmpty(array1) || this.arrayIsNullOrEmpty(array2)) {
            return false;
        }

        if (array1.length != array2.length) {
            return false;
        }

        for (var i = 0, len = array2.length; i < len; i++) {

            if (array1[i].compare && !array1[i].compare(array2[i])) {
                return false;
            }

            if (array1[i] !== array2[i]) {
                return false;
            }
        }

        return true;
    }

    this.arrayIsNullOrEmpty = function(array) {

        if (array == null || array == undefined)
            return true;

        if (array.length < 1)
            return true;

        return false;
    }

    this.applyFilters = function(filterName) {

        $('#filterNoResultsDiv').remove();

        this.CurrentRowCssClass = this.RowAltCssClass;

        this.AttrOptionsAvailable['location'] = new Array();
        this.AttrOptionsAvailable['eventName'] = new Array();
        this.AttrOptionsAvailable['dayOfWeek'] = new Array();
        this.AttrOptionsAvailable['dayPart'] = new Array();

        for (var rowIndex = 0, len = this.ResultRows.length; rowIndex < len; rowIndex++) {
            this.applyFiltersToRow(rowIndex);
        }

        var visibleRows = this.getVisibleRows();

        if ($(visibleRows).size() == 0) {
            $('#pluginResultDiv').after('<div id="filterNoResultsDiv">There are no results matching your selected filters.<br />Try choosing &quot;Show All&quot; on one or more filters until more results are shown.</div>');
        }

        // hide/show hot topic header depending on if there are any hot topic rows showing
        if ($('#HotTopics table tr:visible').size() == 0) {
            $('#HotTopicHeader').hide();
            $('#HotTopicOtherVenuesLink').hide();
            $('#HotTopicFooter').hide();
        }
        else {
            $('#HotTopicHeader').show();
            $('#HotTopicOtherVenuesLink').show();
            $('#HotTopicFooter').show();
        }

        //this.toggleAvailableOptions(filterName);
    }

    this.applyFiltersToRow = function(rowIndex) {

        var row = this.ResultRows[rowIndex];

        var rowValues = new Array();

        for (filterName in this.RowFilters) {

            var rowFilter = this.RowFilters[filterName];

            // if no values have been defined for this filter, show all
            if (rowFilter.length == 0) {
                continue;
            }

            var rowValue = this.RowAttr[filterName][rowIndex];

            // if the value of this row does not match any of the filter values, hide the row
            if ($.inArray(rowValue, rowFilter) < 0) {
                $(row).hide();
                return;
            }

            rowValues[filterName] = rowValue;
        }

        // if no filter caused the row to be hidden, show it
        $(row).attr('class', this.CurrentRowCssClass);
        $(row).show();

        // since the row is visible, flip a flag for each filter to indicate availability of these values for filtering
        for (filterName in this.RowAttr) {
            var rowValue = this.RowAttr[filterName][rowIndex];
            this.AttrOptionsAvailable[filterName][rowValue] = true;
        }

        this.CurrentRowCssClass = (this.CurrentRowCssClass == this.RowCssClass) ? this.RowAltCssClass : this.RowCssClass;
    }

    this.showAllClick = function(filterName) {
        var showAllCheckBox = $('#filterParameter_' + filterName + ' ul li input.ticketFilter_checkBox_' + filterName + '_showAll:checkbox');
        var showAll = $(showAllCheckBox).is(':checked');
        this.toggleShowAll(showAll, filterName);
        this.parseFilterCheckBoxes(filterName);
        this.boldCheckedItems(filterName);
    }

    this.toggleShowAll = function(showAll, filterName) {

        if (showAll) {
            //$('#filterParameter_' + filterName + ' ul li.ticketFilter_li_' + filterName).hide();
            $('#filterParameter_' + filterName + ' ul li input.ticketFilter_checkBox_' + filterName + '_showAll:checkbox').attr('checked', true);
            $('#filterParameter_' + filterName + ' ul li input.ticketFilter_checkBox_' + filterName + ':checkbox').attr('checked', false);
        }
        else {
            $('#filterParameter_' + filterName + ' ul li input.ticketFilter_checkBox_' + filterName + '_showAll:checkbox').attr('checked', false);
            //$('#filterParameter_' + filterName + ' ul li.ticketFilter_li_' + filterName).show();
        }


    }

    this.reloadPage = function() {
        window.location = this.ReloadBaseUrl + this.buildQueryString();
    }

    this.buildQueryString = function() {

        var queryString = '';
        var concat = '?';

        // add all the parameters for the search
        for (key in this.SearchParameters) {
            queryString = queryString + concat + key + '=' + escape(this.SearchParameters[key]);
            concat = '&';
        }

        // add all filters so that when page reloads, filters will be preselected
        for (key in this.RowFilters) {
            var rowFilter = this.RowFilters[key];
            for (var i = 0, len = rowFilter.length; i < len; i++) {
                queryString = queryString + concat + key + '=' + escape(rowFilter[i]);
                concat = '&';
            }
        }

        return queryString;
    }

    this.filterDate = function() {
        this.SearchParameters["sdate"] = $("#DateStartTextBox").val();
        this.SearchParameters["edate"] = $("#DateEndTextBox").val();
        this.reloadPage();
    }

    this.getDayPart = function(timeText) {

        var colonIndex = timeText.indexOf(':');

        if (colonIndex < 0)
            return 'Evening';

        var hour = timeText.substr(0, colonIndex);

        var amPm = '';

        if (timeText.indexOf('AM') > 0)
            amPm = 'AM';
        else if (timeText.indexOf('PM') > 0)
            amPm = 'PM';
        else
            return 'Evening';

        switch (amPm) {
            case 'AM':
                switch (hour) {
                    case '5':
                    case '6':
                    case '7':
                    case '8':
                    case '9':
                    case '10':
                    case '11':
                        return 'Daytime';
                        break;

                    default:
                        return 'Evening';

                }
                break;

            case 'PM':
                switch (hour) {
                    case '12':
                    case '1':
                    case '2':
                    case '3':
                    case '4':
                    case '5':
                        return 'Daytime';
                        break;

                    default:
                        return 'Evening';
                }
                break;
        }
    }

    this.boldCheckedItems = function(filterName) {
        $('#filterParameter_' + filterName + ' li').css('font-weight', 'normal');
        $('#filterParameter_' + filterName + ' li').each(function() {
            if ($(this).find('input:checkbox:checked').size() > 0) {
                $(this).css('font-weight', 'bold');
            }
        });
    }

    this.truncateToWord = function(fullText, maxLength) {

        if (fullText.length <= maxLength)
            return fullText;

        if (fullText.indexOf(' ') < 0)
            return fullText.subStr(0, maxLength - 1) + '&#133;';

        var wordArray = fullText.split(' ');
        var shortText = '';

        for (var i = 0; i < wordArray.length; i++) {

            var word = wordArray[i];

            if (shortText.length + word.length > maxLength)
                break;

            shortText += word + ' ';
        }

        return $.trim(shortText) + '&#133;';

    }

    this.toggleAvailableOptions = function(filterName) {

        // now check each set of filter checkboxes against available tickets
        if (filterName != 'location') {
            this.toggleAvailableOptionsForFilter('location');
        }
        if (filterName != 'eventName') {
            this.toggleAvailableOptionsForFilter('eventName');
        }
        if (filterName != 'dayOfWeek') {
            this.toggleAvailableOptionsForFilter('dayOfWeek');
        }
        if (filterName != 'dayPart') {
            this.toggleAvailableOptionsForFilter('dayPart');
        }

    }

    this.toggleAvailableOptionsForFilter = function(filterName) {

        var listItems = $('#filterParameter_' + filterName + ' ul li.ticketFilter_li_' + filterName);

        listItems.each(function(index, element) {

            var attrValue = $(element).find('input').first().val();

            if (gridFilter.AttrOptionsAvailable[filterName][attrValue] == true) {
                $(element).show();
            } else {
                $(element).hide();
            }
        });
    }



    this.toggleOptionDisplay = function(filterName) {

        $('#filterParameter_' + filterName + ' ul').slideToggle(200, null);

        var img = $('#filterParameter_' + filterName + ' a div.filterParameterToggler img');

        var imgSrc = $(img).attr('src').toLowerCase();

        var imgUpSrc = '/images/arroworange_up.gif'

        var imgDownSrc = '/images/arroworange_down.gif'

        if (imgSrc == imgUpSrc) {
            $(img).attr('src', imgDownSrc);

            if (this.RowFilters[filterName].length == 0) {
                filterSummary = 'Show All';
            } else {
                var filterSummary = this.RowFilters[filterName].join('; ') +
            '; <div style="margin: 4px 0px 0px 0px;">' +
            '<a style="text-decoration:underline;font-size:11px;" ' +
            'href="javascript:$.noop();" onclick="gridFilter.toggleOptionDisplay(\'' + filterName + '\'); return false;">Change Selection</a> &middot; ' +
            '<a style="text-decoration:underline;font-size:11px;" ' +
            'href="javascript:$.noop();" onclick="gridFilter.toggleShowAll(true, \'' + filterName + '\');gridFilter.showAllClick(\'' + filterName + '\');gridFilter.toggleOptionDisplay(\'' + filterName + '\'); return false;">Show All</a></div>';
                $('#filterSummary_' + filterName).html(filterSummary);
                $('#filterSummary_' + filterName).slideDown();
            }

        } else {
            $(img).attr('src', imgUpSrc);
            $('#filterSummary_' + filterName).slideUp();
        }

        $('.filterParameter').blur();

        return false;
    }


}