﻿var HubDirectories = {
    hasLiveHandlers: false,
    directories: null,
    lastHashApplied: null,
    pageSize: 10,
    travelItemTemplate: null,
    init: function() {
        this.directories = jQuery("div.main div.twDirectory");
        if (this.directories.length) {
            if (!this.hasLiveHandlers) {
                jQuery.address.change(HubDirectories.onAddressChanged);

                jQuery("tr.travelItemHeaderRow .name a").live("click", HubDirectories.onTravelItemHeaderClick);
                jQuery(".directorySection h3 a").live("click", HubDirectories.onDirectorySectionHeaderClick);

                this.hasLiveHandlers = true;
            }

            this.run();
        }
    },
    reinitialize: function() {
        this.init();
        HubDirectories.applyHashState();
    },
    applyDirectoryState: function(directoryID, newOpenSectionID, newSortColumnName, newSortDirection, newItemCount, newOpenItems) {
        var sortReset = false;
        var directory = jQuery(".twDirectory[data-id='" + directoryID + "']");
        var allSections = directory.children(".directorySection");
        
        // if any section not specified by the hash is open, close it.
        allSections.filter(".on").each(function() {
            if (jQuery(this).attr("data-id") != newOpenSectionID) {
                HubDirectories.closeDirectorySection(jQuery(this));
            }
        });

        var openSection = allSections.filter(".directorySection[data-id='" + newOpenSectionID + "']");
        
        // if sort condition doesn't match hash, update sort column/direction and set sortReset flag
        var allSortColumnHeaders = openSection.find("th.sortable");
        var oldSortColumn = openSection.find(".sort");
        var oldSortColumnName = "";
        var oldSortDirection = "";
        if (oldSortColumn != null) {
            if (oldSortColumn.hasClass("desc")) {
                oldSortDirection = "desc";
            } else {
                oldSortDirection = "asc";
            }
            oldSortColumnName = oldSortColumn.attr("data-sort");
        }
        if (oldSortColumnName != newSortColumnName) {
            sortReset = true;

            if (oldSortColumn != null) {                    
                oldSortColumn.removeClass("sort desc");
                oldSortColumn.find(".sortIndicator").removeClass("primary1_bg");
            }

            var selectedSortColumnHeader = allSortColumnHeaders.filter("th[data-sort='" + newSortColumnName + "']");
            selectedSortColumnHeader.addClass("sort");
            selectedSortColumnHeader.children(".sortIndicator").addClass("primary1_bg");

            if (newSortDirection == "desc") {
                selectedSortColumnHeader.addClass("desc");
            }
        }
        else {
            if (oldSortDirection != newSortDirection) {
                sortReset = true;

                var selectedSortColumnHeader = allSortColumnHeaders.filter("th[data-sort='" + newSortColumnName + "']");
                if (newSortDirection == "desc") {
                    selectedSortColumnHeader.addClass("desc");
                } else {
                    selectedSortColumnHeader.removeClass("desc");
                }
            }
        }

        var tbody = openSection.find("tbody");
        if (sortReset) { // if sort has changed, clear old stuff
            tbody.html("");
        }

        HubDirectories.expandDirectorySection(openSection);

        var oldItemCount = parseInt(tbody.find(".travelItemHeaderRow").size());
        if (newItemCount == null || newItemCount == "all") {
            HubDirectories.fetchResults(
                tbody,
                HubDirectories.getParameters(openSection),
                oldItemCount
            );
        } else {
            newItemCount = parseInt(newItemCount);
            if (newItemCount > oldItemCount) {
                HubDirectories.fetchResults(
                    tbody,
                    HubDirectories.getParameters(openSection),
                    oldItemCount,
                    newItemCount - oldItemCount
                );
            } else if (newItemCount < oldItemCount) {
                tbody.find("tr").slice(newItemCount*2).remove(); //kill extraneous rows
                var tableFooter = tbody.parent().find("tfoot");
                var totalCount = tableFooter.find(".count").html();
                var currentCount = tbody.find(".travelItemHeaderRow").size();
                if (currentCount == totalCount) {
                    tableFooter.hide();
                } else {
                    tableFooter.show();
                }
            }
        }

        openSection.attr("data-open-items", newOpenItems);
        HubDirectories.refreshOpenTravelItems(openSection);
    },
    applyHashState: function() {
        var dirState = WDOT.Address.stateParam("dir");
        
        if (dirState != null) {
            var directoryStates = dirState.split(",");
            for (var i=0;i<directoryStates.length; i++) {
                var directoryState = directoryStates[i].split("|");
                HubDirectories.applyDirectoryState(directoryState[0], directoryState[1], directoryState[2], directoryState[3], directoryState[4], directoryState[5]);
            }
        } else {
            var directories = HubDirectories.directories;
            for(var i=0;i<directories.length;i++){
                var directory = directories.eq(i);
                var firstSection = directory.find(".directorySection:first");
                HubDirectories.applyDirectoryState(
                    directory.attr("data-id"),
                    firstSection.attr("data-id"),
                    "city",
                    "asc",
                    "10",
                    ""
                );
            }
        }
        
        HubDirectories.lastHashApplied = dirState;
    },
    closeDirectorySection: function(section) {
        if (section != null && section.hasClass("on")) {
            section.removeClass("on");
            section.find(".tableWrapper").slideUp("fast");
        }
    },
    closeTravelItem: function(headerRow) {
        if (headerRow != null && headerRow.hasClass("on")) {
            headerRow.next().find(".detailWrapper").slideUp("fast", function(e) {
                headerRow.removeClass("on");
            });
        }
    },
    expandDirectorySection: function(section) {
        if (!section.hasClass("on")) {
            section.addClass("on");
            section.find(".tableWrapper:first").slideDown("fast");
        }
    },
    fetchCount: function(section) {
        var countPlaceholders = section.find(".count");
        var params = HubDirectories.getParameters(section);
        var paramCollection = new Array();

        if (params != null) {
            if (params.selectedCategoryIDs != null) {
                paramCollection.push("selectedCategoryIDs=" + params.selectedCategoryIDs);
            }
            if (params.selectedCityIDs != null) {
                paramCollection.push("selectedCityIDs=" + params.selectedCityIDs);
            }
            if (params.selectedFilterIDs != null) {
                paramCollection.push("selectedFilterIDs=" + params.selectedFilterIDs);
            }
            if (params.proximity != null) {
                paramCollection.push("proximity=" + params.proximity);
            }
        }

	    jQuery.ajax({
	        type: "GET",
	        url: "/wisconsin/services/Directory/CountResults",
	        data: paramCollection.join("&"),
	        success: function (data) {
	            countPlaceholders.html(data.resultCount);
	        }
        });
    },
    fetchResults: function(tbody, params, skipCount, pageSize) {
        var paramCollection = new Array();
        
        if (skipCount != null) {
            paramCollection.push("skipCount=" + skipCount);
        }
        
        if (pageSize != null) {
            paramCollection.push("pageSize=" + pageSize);
        }
        
        if (params != null) {
            if (params.selectedCategoryIDs != null) {
                paramCollection.push("selectedCategoryIDs=" + params.selectedCategoryIDs);
            }
            if (params.selectedCityIDs != null) {
                paramCollection.push("selectedCityIDs=" + params.selectedCityIDs); 
            }
            if (params.selectedFilterIDs != null) {
                paramCollection.push("selectedFilterIDs=" + params.selectedFilterIDs);
            }
            if (params.proximity != null) {
                paramCollection.push("proximity=" + params.proximity);
            }
            if (params.sortColumn) {
                paramCollection.push("sortColumn=" + params.sortColumn);
            }
            if (params.sortDirection) {
                paramCollection.push("sortDirection=" + params.sortDirection);
            }
        }
    
	    jQuery.ajax({
	        type: "GET",
	        url: "/wisconsin/services/Directory/GetSectionTravelItems",
	        data: paramCollection.join("&"),
	        success: function (data) {
	            //preprocess data to include some directory-scoped variables before template is applied
                var hasGreenScoreColumn = (tbody.prev().find("th.greenScore").length>0);
                var hasAddtoTravelListColumn = (tbody.prev().find("th.addToTravelList").length>0);
                var hideViewDetailsLink = tbody.closest(".twDirectory").attr("data-hide-details-link") == "true";
	            for(var i=0;i<data.length;i++) {
	                data[i].IncludeGreenScore = hasGreenScoreColumn;
	                data[i].IncludeAddToTravelList = hasAddtoTravelListColumn;
	                data[i].IncludeViewDetailsLink = !hideViewDetailsLink;
	            }
	        
                var newRows = jQuery.tmpl(HubDirectories.travelItemTemplate, data);
                newRows.appendTo(tbody);
                
                newRows.each(function() {
                    var kids = jQuery(this).find(".detailWrapper p:first").children();
                    for (var i = 0; i < (kids.length - 1); i++) { // put pipe between kids
                        jQuery("<span> |</span>").insertAfter(kids.eq(i));
                    }
                });
                
                var tableFooter = tbody.parent().find("tfoot");
                var totalCount = tableFooter.find(".count").html();
                var currentCount = tbody.find(".travelItemHeaderRow").size();
                
                if (currentCount == totalCount) {
                    tableFooter.hide();
                } else {
                    tableFooter.show();
                }
                
                HubDirectories.refreshOpenTravelItems(tbody.closest(".directorySection"));
	        }
        });
    },
    getParameters: function(section) {
        var parameters = jQuery.parseJSON(section.attr("data-query-params"));
        if (parameters != null) {
            var sortColumn = section.find("th.sort");
            if (sortColumn.length) {
                parameters.sortColumn = sortColumn.attr("data-sort");
                if (sortColumn.hasClass("desc")) {
                    parameters.sortDirection = "desc";
                } else {
                    parameters.sortDirection = "asc";
                }
            } else {
                parameters.sortColumn = "city";
                parameters.sortDirection = "desc";
            }
        }
        return parameters;
    },
    onAddressChanged: function() {
        if (HubDirectories.lastHashApplied == null || HubDirectories.lastHashApplied != WDOT.Address.stateParam("dir")) { // keeping track of last hash applied because in some cases the hash params are decoded and it's treated as two hash updates. the asynchronicity of that causes a double-update bug. :/
            HubDirectories.applyHashState();
        }
    },
    onDirectorySectionHeaderClick: function(e) {
        var thisDirectorySection = jQuery(this).closest(".directorySection");
        var thisDirectory = thisDirectorySection.closest(".twDirectory");
        thisDirectory.attr("data-open-section", thisDirectorySection.attr("data-id"));
        HubDirectories.updateHashState();
        return false;
    },
    onSortableColumnClick: function(e) {
        var columnHeader = jQuery(this).parent();
        var directorySection = jQuery(this).closest(".directorySection");
        if (directorySection.attr("data-sort-col") != columnHeader.attr("data-sort")) {
            directorySection.attr("data-sort-col", columnHeader.attr("data-sort"));
            directorySection.attr("data-sort-dir", "asc");
        } else {
            if (directorySection.attr("data-sort-dir") == "asc") {
                directorySection.attr("data-sort-dir", "desc");
            } else {
                directorySection.attr("data-sort-dir", "asc");
            }
        }
        HubDirectories.updateHashState();
        return false;
    },
    onTravelItemHeaderClick: function(e) {
        var headerRow = jQuery(this).closest(".travelItemHeaderRow");
        var itemID = headerRow.attr("data-id");
        var directorySection = headerRow.closest(".directorySection");
        var currentOpenItemString = directorySection.attr("data-open-items");
        var currentOpenItemList = null;
        if (currentOpenItemString != null && currentOpenItemString.length > 0) {
            currentOpenItemList = currentOpenItemString.split("+");
        } else {
            currentOpenItemList = new Array();
        }
        if (jQuery.inArray(itemID, currentOpenItemList) != -1) {
            currentOpenItemList = jQuery.grep(currentOpenItemList, function(value) { return value != itemID; });
        } else {
            currentOpenItemList.push(itemID);
        }
        directorySection.attr("data-open-items", currentOpenItemList.join("+"));
        HubDirectories.updateHashState();
        return false;
    },
    onViewAllClick: function(e) {
        var directorySection = jQuery(this).closest(".directorySection");
        directorySection.attr("data-count", "all");
        HubDirectories.updateHashState();
        return false;
    },
    onViewMoreClick: function(e) {
        var directorySection = jQuery(this).closest(".directorySection");
        var oldCount = directorySection.attr("data-count");
        if (directorySection != null) {
            oldCount = parseInt(oldCount);
            directorySection.attr("data-count", oldCount + 10);
            HubDirectories.updateHashState();
        }
        return false;
    },
    openTravelItem: function(headerRow) {
        if (!headerRow.hasClass("on")) {
            headerRow.addClass("on");
            headerRow.next().find(".detailWrapper").slideDown("fast");
        }
    },
    refreshOpenTravelItems: function(directorySection) {
        if (directorySection != null) {
            var openIDs = directorySection.attr("data-open-items");
            if (openIDs != null && openIDs.length > 0) {
                openIDs = openIDs.split("+");
            } else {
                openIDs = new Array();
            }
            directorySection.find(".travelItemHeaderRow").each(function() {
                if (jQuery.inArray(jQuery(this).attr("data-id"), openIDs) >= 0) {
                    HubDirectories.openTravelItem(jQuery(this));
                } else {
                    HubDirectories.closeTravelItem(jQuery(this));
                }
            });
        }
    },
    updateHashState: function() {
        var directoryStates = new Array();
    
        for (var i=0; i < this.directories.length; i++) {
            var thisDirectory = this.directories.eq(i);
            var id = thisDirectory.attr("data-id");
            var openSectionID = thisDirectory.attr("data-open-section");
            var openSection = thisDirectory.find(".directorySection[data-id='" + openSectionID + "']");
            var sortColumn = "";
            var sortDirection = "";
            var itemCount = "";
            var openItemIDs = "";

            openSectionID = openSection.attr("data-id");

            if (openSection.length) {
                itemCount = openSection.attr("data-count");
                sortColumn = openSection.attr("data-sort-col");
                sortDirection = openSection.attr("data-sort-dir");
                openItemIDs = openSection.attr("data-open-items");
            }
            
            directoryStates.push([ id, openSectionID, sortColumn, sortDirection, itemCount, openItemIDs ].join("|"));
        }

        WDOT.Address.stateParam("dir", directoryStates.join(","));
    },
    run: function() {
        // hide any directories in the sidebar (and any hr tags after them)
        jQuery("div.sidebar div.twDirectory").hide();
        jQuery("div.sidebar div.twDirectory+hr").hide();
    
        jQuery.get("/js/directories_TravelItemTemplate.htm", function(template) {
            HubDirectories.travelItemTemplate = template;
        
            HubDirectories.directories.each(function() { //initialize directories
                var thisDirectory = jQuery(this);

                thisDirectory.find("a.viewAll").bind("click", HubDirectories.onViewAllClick);
                thisDirectory.find("a.viewMore").bind("click", HubDirectories.onViewMoreClick);
                thisDirectory.find("th.sortable a").bind("click", HubDirectories.onSortableColumnClick);

                var sections = thisDirectory.children(".directorySection");
                sections.each(function() { //initialize section counts
                    var thisSection = jQuery(this);
                    HubDirectories.fetchCount(thisSection);
                });
            });
        });
    }
};

jQuery(function() {
    HubDirectories.init();
});
