// (C) Copyright 2020 Hewlett-Packard Enterprise Company, L.P.
/**
 * @type {MasterListView}
 */
define(['hp/presenter/MasterPanePresenter',
    'hp/view/SearchBoxView',
    'hp/view/MasterErrorView',
    'hp/core/LinkTargetBuilder',
    'hp/core/Localizer',
    'hp/core/Style',
    'text!hpPages/core/no_items.html',
    'jquery'],
function (MasterPanePresenter, searchBoxView, errorView, linkTargetBuilder, localizer, style, noItemsHtml) {
"use strict";

    var MasterListView = (function () {

        // consts can go here
        var LIST = '.hp-master-list';
        var ITEM = '.hp-master-list-item';
        var TITLE = '.hp-master-header .hp-master-title';
        var COUNT = '.hp-page-item-count';
        var COLLAPSER = 'header .hp-collapser';
        var MATCH_COUNT_CLASS_NAME = 'hp-master-match-count';
        var MATCH_COUNT = '.' + MATCH_COUNT_CLASS_NAME;
        var FILTERBAR_CONTROL = '.hp-filterbar-control';
        var RESET_FILTERS = '.hp-filter-reset';
        var FILTERBAR = '.hp-master-filter';
        var FILTERBAR_RESET_FILTERS = '.hp-master-filter .hp-filter-reset';
        var SUBNAV_RESET_FILTERS = '.hp-sub-nav .hp-filter-reset';
        var FILTER = '.hp-filter[data-filter-property]';
        var SORTER = '#hp-master-sort';
        var SELECTED = 'hp-selected';
        var ACTIVE = 'hp-active';
        var EXPANDED = 'hp-expanded';
        var COLLAPSED = 'hp-collapsed'; // for IE8
        var FILTERBAR_OPEN = 'hp-filterbar-open';
        var KEY_DOWN = 40;
        var KEY_UP = 38;
        var LOADMORE = 'loadMore';
        var LOADMORE_ABOVE = 'loadMoreAbove';
        var LOADMORE_SPINNER = '<div class="hp-spinner-small"><div class="hp-spinner-image"></div></div>';
        var REFRESH  = 'refresh';
        var SELECTED_ITEM_OFFSET  = 1;

        /**
         * @constructor
         */
        function MasterListView() {

            //
            // private class instance variables
            //
            var presenter = new MasterPanePresenter();
            var page = null;
            var resource = null;
            var renderer = null;
            var addHelp = "";
            var addActionLink = "";
            var addLink = "";
            var pendingItemHeight = 0;
            var manualScrollTo = -1;
            var expandedUris = [];
            // remember how many rows is in the table before "Load more" is clicked;
            // it is used to maintain the scroll position to the previous Top
            var prevRowStart;
            var disableSelectionScroll = false;
            var noItems = $(noItemsHtml);
            
            function fireRelayout() {
                // we delay so any CSS animation can finish
                setTimeout(function () {
                    page.trigger('relayout');
                }, style.animationDelay());
            }

            function clearSelection() {
                $(ITEM, page).removeClass(SELECTED);
            }

            function setSelection(selection) {
                if (selection.uris && selection.uris.length > 0) {
                    $.each($(ITEM), function () {
                        var item = this;
                        var indexResult = $.data(item, 'hpIndexResult');

                        if ((indexResult) &&
                            ($.inArray(indexResult.uri, selection.uris) !== -1)) {
                            $(item).addClass(SELECTED);
                        }
                    });
                }
            }

            /**
             * @private
             * Scroll to the table row with padding rows above it
             * @param {Element} row The row to scroll to
             */
            function scrollAndPad(row) {
                var rowIdx = row.prevAll().length;
                var rowsToScroll;
                var firstRowToScroll;
                var scrollHeight;
                
                if (presenter.haveMoreAbove() && (SELECTED_ITEM_OFFSET >= rowIdx)) {
                    // hide the "Load more" row if it exists
                    rowsToScroll = 1 ;
                } else if (rowIdx >= SELECTED_ITEM_OFFSET) {
                    // if we have enough rows above, apply padding 
                    rowsToScroll = rowIdx - SELECTED_ITEM_OFFSET;
                } else {
                    // show everything
                    rowsToScroll = 0;
                }                
                firstRowToScroll = $(LIST).children()[rowsToScroll];
                scrollHeight = $(firstRowToScroll).position().top - $(LIST).children().first().position().top;                
                $(LIST).animate({'scrollTop' : scrollHeight}, 20);
            }
            
            function scrollToSelection() {
                var row;

                if (manualScrollTo !== -1) {
                    $(LIST).animate({'scrollTop': manualScrollTo}, 20);
                } else if (! disableSelectionScroll) {
                    row = $(ITEM + '.' + SELECTED).first();
                    if (row.length > 0) {
                        scrollAndPad(row);
                    }

                    setTimeout(function () {
                        if (manualScrollTo !== -1) {
                            // reset since we just scrolled
                            manualScrollTo = -1;
                        }
                    }, 100);
                }
            }
            
            // After an item is clicked, make sure it is not partially hidden
            // from the top or bottom.
            function alignSelectedItem() {
                var scrollTo = manualScrollTo;
                var reset = false;
                
                if (scrollTo === -1) {
                    var item = $(ITEM + '.' + SELECTED).first();
                    if (item.length > 0) {
                        if ($(item).position().top < 0) {
                            scrollTo =  $(LIST, page).scrollTop() + 
                            item.position().top;                                                
                        } else if (($(item).position().top + $(item).outerHeight()) >
                            $(LIST, page).innerHeight()) {
                            // make sure we don't scroll up so we can't see the top of the item
                            scrollTo =  Math.min(
                                $(LIST, page).scrollTop() + item.position().top,
                                $(LIST, page).scrollTop() + item.position().top -
                                $(LIST, page).innerHeight() + item.outerHeight()); 
                        }
                    }
                    reset = true;
                }
                
                if (scrollTo !== -1) {
                    $(LIST, page).scrollTop(scrollTo);
                }
            }
            
            function resetSelection(selection, keepManualScroll) {
                clearSelection();
                setSelection(selection);
                
                if (!keepManualScroll) {
                    manualScrollTo = -1;
                }
                if (selection.uris.length > 0) {
                    scrollToSelection();
                }
            }
            
            // @private
            // Preserve current scroll position when "Load more" is clicked, or when new data is added
            // to the grid. If "Load more (above)" link has been clicked, or new data is added above,
            // calculate their height and scroll down. 
            // If "Load more (bottom)" is clicked, then just use the current scrolling position maintained
            // in 'manualScrollTo' variable
            // @param {int} extraRowsAbove The number of rows added above the current table.
            function preserveScrollPosition(extraRowsAbove) {
                var topOffset,
                    topList,
                    includeControlRow = presenter.haveMoreAbove() ? 1 : 0;
                
                if (extraRowsAbove - includeControlRow > 0) { 
                    topOffset = $(LIST, page).children().first().position().top; // offset of the first grid
                    topList = $(LIST, page).children()[extraRowsAbove]; //previous row top
                    manualScrollTo = $(topList).position().top - topOffset - $(topList).outerHeight(true);
                }
                clearSelection();
                setSelection(presenter.getSelection());
                if (manualScrollTo !== -1) {
                    $(LIST).animate({'scrollTop': manualScrollTo}, 20);
                }
            }
            
            function onItemClick(event) {
                // get index result from object and call presenter
                var item = $(event.target).closest(ITEM);
                var indexResult = $(item).data('hpIndexResult');
                disableSelectionScroll = true;
                presenter.select(indexResult,
                    (event.ctrlKey || event.metaKey), event.shiftKey);
                $(LIST, page).focus();
                
                alignSelectedItem();
                disableSelectionScroll = false;
            }
            
            function isEmptyMessageAvailable() {
                return ((addHelp && addHelp.length > 0) || 
                        (addActionLink && addActionLink.length > 0) || 
                        (addLink && addLink.length > 0));
            }
            
            function setEmptyMessage(indexResults) {
                var splash = $('<li></li>').addClass('hp-master-list-splash');
                var empty = $('<div></div>').addClass('hp-master-list-empty').
                    text(presenter.getEmptyMessage(indexResults));
                splash.append(empty);
                var helpText = "";
                var actionLink = "";
                var addButton = "";
                var listEmptyMessage = "";
                if (presenter.haveContacted() && 
                        ! presenter.haveSome() && 
                        isEmptyMessageAvailable() && 
                        presenter.isEmptyOrUnfiltered(indexResults)) {
                    if (addHelp && addHelp.length > 0) {
                        helpText = $('<div></div>').addClass('hp-add-help').html(addHelp);
                    }
                    if (addActionLink && addActionLink.length > 0) {
                        actionLink = $('<div></div>').addClass('hp-add-action-link').html(addActionLink);
                    }
                    if (addLink && addLink.length > 0) {
                        addButton = $('<div></div>').addClass('hp-add-link');
                        addButton.append($(addLink).addClass('hp-button hp-primary'));
                    }
                    listEmptyMessage = $('<div></div>').addClass('hp-help');
                    listEmptyMessage.append(helpText);
                    listEmptyMessage.append(actionLink);
                    splash.append(listEmptyMessage);
                    splash.append(addButton);
                }
                $(LIST, page).append(splash);
            }
            
            function saveExpandedUris() {
                expandedUris = $(ITEM + '.' + EXPANDED, page).map(function () {
                    return $(this).data('hpIndexResult').uri;
                }).get();
            }
            
            function onCollapserClick(event) {
                $(event.currentTarget).toggleClass(ACTIVE);
                $(event.currentTarget).closest(ITEM).
                    toggleClass(EXPANDED).toggleClass(COLLAPSED);
                saveExpandedUris();
                scrollToSelection(); // in case we expanded off the bottom
            }
            
            function alignSelection(item, uri) {
                // set selection state
                if ($.inArray(uri, presenter.getSelection().uris) !== -1) {
                    item.addClass(SELECTED);
                } else {
                    item.removeClass(SELECTED);
                }
            }
            
            function alignExpansion(item, uri) {
                 if (-1 !== $.inArray(uri, expandedUris)) {
                      item.addClass(EXPANDED);
                      $(COLLAPSER, item).addClass(ACTIVE);
                  } else {
                      item.addClass(COLLAPSED);
                      $(COLLAPSER, item).removeClass(ACTIVE);
                  }
            }
            
            function createRenderedItem(result) {
                var item = renderer(result);
                item.data('hpIndexResult', result);
                // set expansion state
                alignExpansion(item, result.uri);
                // set selection state
                alignSelection(item, result.uri);
                return item;
            }
            
            function createPendingItem(result, height) {
                var item = $('<li></li>').
                    addClass("hp-pending hp-master-list-item").
                    css('height', (height ? height : pendingItemHeight)).
                    data('hpIndexResult', result);
                // set expansion state
                alignExpansion(item, result.uri);
                // set selection state
                alignSelection(item, result.uri);
                return item;
            }
            
            function replaceItem(item, result) {
                var mismatch = ($(item).data('hpIndexResult').uri !== result.uri);
                var makePending = false;
                if (($(item).position().top + $(item).outerHeight() +
                    (2 * pendingItemHeight)) < 0) {
                    // above region, empty if different
                    if (! $(item).hasClass('hp-pending') || mismatch) {
                        makePending = true;
                    }
                } else if ($(item).position().top >
                    ($(LIST, page).innerHeight() + (2 * pendingItemHeight))) {
                      // below region, empty if not
                    if (! $(item).hasClass('hp-pending') || mismatch) {
                        makePending = true;
                    } else {
                        // already empty, can quit loop
                        return false;
                    }
                } else {
                    // within scroll region, update
                    $(item).replaceWith(createRenderedItem(result));
                }
                
                if (makePending) {
                    if (! $(item).hasClass('hp-pending') || mismatch) {
                        if (mismatch) {
                            $(item).replaceWith(createPendingItem(result));
                        } else {
                            $(item).replaceWith(createPendingItem(result,
                                $(item).height()));
                        }
                    }
                }
                
                return true;
            }
            
            function loadMore(listItemElement, fromAbove) {
                listItemElement.empty().append(LOADMORE_SPINNER);
                listItemElement.attr('align', 'center');
                $('.hp-spinner-small', listItemElement).show();
                presenter.loadMore(fromAbove);
            }
            
            function onLoadMoreAboveClick(ev) {
                loadMore($(ev.target.parentElement), true);
            }
            
            function onLoadMoreClick(ev) {
                loadMore($(ev.target.parentElement), false);
            }
            
            // @private
            // Update the match count with the latest results from the index
            // @param {Object} data The results from an index request
            function updateMatchCount(indexResults) {
                if ((!indexResults.filter.data.hasOwnProperty('userQuery')) &&
                    (!indexResults.filter.data.hasOwnProperty('associationName'))) {
                    $(MATCH_COUNT, page).hide();
                    return;
                }
                      
                if ((undefined === indexResults.total) ||
                    (undefined === indexResults.unFilteredTotal)) {
                    $(MATCH_COUNT, page).hide();
                    return;
                }
                
                var matchText;
                if (indexResults.total === 1) {
                    matchText = localizer.getString('core.master.filters.matchCount',
                        [indexResults.unFilteredTotal]);
                } else {
                    matchText = localizer.getString('core.master.filters.matchesCount',
                        [indexResults.total, indexResults.unFilteredTotal]);
                }
                $(MATCH_COUNT, page).text(matchText);
                $(MATCH_COUNT, page).show();
            }
            
            /**
             * @private
             * @param {Object} data the IndexResults
             */
            function onIndexResultsChange(indexResults) {
                var oldItem, newItem, oldItems;
                var overflowed = false;
                var extraRowsAbove = prevRowStart - indexResults.start;
                if (!indexResults.filter.hasReferenceUri()) {
                    // if the results is not generated by referenceUri, then the scroll
                    // reference is always 0.
                    extraRowsAbove = 0;
                }
                if (indexResults.start !== 0) {
                    // if there are more items above, then add one more row for
                    // "Load more" link on top.
                    extraRowsAbove++;
                }
                // store indexResults start location
                prevRowStart = indexResults.start;
                
                $(LIST, page).removeClass('hp-changing');
                
                if (indexResults) {
                    $(COUNT, page).text(indexResults.total);
                    updateMatchCount(indexResults);
                }
                
                if (indexResults && renderer) {
                
                    clearSelection();
                    $(LIST + ' .hp-master-list-control', page).remove();
                    $(LIST + ' .hp-master-list-splash', page).remove();
                    oldItems = $(ITEM, page);
                    
                    $(TITLE, page).text(presenter.getHeaderTitle());
                
                    $.each(indexResults.members, function (index, result) {
                        if (index >= oldItems.length) {
                            oldItem = null;
                        } else {
                            oldItem = $(oldItems[index]);
                        }
                        if (oldItem) {
                            if (! replaceItem(oldItem, result) && ! overflowed) {
                                overflowed = true;
                            }
                        } else {
                            if (! overflowed) {
                                newItem = createRenderedItem(result);
                                $(LIST, page).append(newItem);
                                if (! pendingItemHeight) {
                                    pendingItemHeight = newItem.height();
                                } else {
                                    pendingItemHeight = Math.min(pendingItemHeight,
                                        newItem.height());
                                }
                                if (newItem.position().top >
                                    ($(LIST, page).innerHeight() +
                                        (2 * pendingItemHeight))) {
                                    overflowed = true;
                                }
                            } else {
                                newItem = createPendingItem(result);
                                $(LIST, page).append(newItem);
                            }
                        }
                    });
                    
                    // remove anything beyond the results we have
                    $(ITEM, page).slice(indexResults.count).remove();
                    
                    if (presenter.haveMoreAbove()) {
                        $(LIST, page).prepend(
                                '<li class="hp-master-list-control">' +
                                '<a id="hp-master-load-more-above">' +
                                localizer.getString('core.master.showMore') +
                                '</a></li>');
                            $('#hp-master-load-more-above', page).click(onLoadMoreAboveClick);
                    }
                    
                    if (presenter.haveMore()) {
                        $(LIST, page).append(
                            '<li class="hp-master-list-control">' + 
                            '<a id="hp-master-load-more">' +
                            localizer.getString('core.master.showMore') +
                            '</a></li>');
                        $('#hp-master-load-more', page).click(onLoadMoreClick);
                    } else if (indexResults.total === 0) {
                        setEmptyMessage(indexResults);
                    }
                    
                    if (indexResults.members.length > 0) {
                        if ((indexResults.__generatedBy === LOADMORE_ABOVE) ||
                            (indexResults.__generatedBy === REFRESH)) {
                            preserveScrollPosition(extraRowsAbove);
                        } else if (indexResults.__generatedBy === LOADMORE) {
                            preserveScrollPosition(-1);
                        } else { 
                            // indexResults.__generatedBy === RELOAD
                            resetSelection(presenter.getSelection());
                        }
                    }
                }
            }
            
            function onIndexResultsChanging() {
                $(LIST, page).addClass('hp-changing');
            }

            function onIndexResultsError(errorInfo) {
                if (page) {
                    $(ITEM, page).remove();
                    $(LIST + ' #hp-no-items', page).remove();
                    $(LIST, page).append(noItems);
                }
            }
            
            // align selection classes with uris
            function onSelectionChange(selectionArg) {
                resetSelection(selectionArg);
            }

            // Invalidate current selection
            function onInvalidSelection(selection) {
                $(LIST, page).removeClass('hp-changing');
                clearSelection();
            }
            
            function closeFilterbar() {
                $('.hp-sub-nav .hp-page-label', page).after(
                        $(FILTERBAR + ' .hp-filter', page).removeClass('hp-active hp-pinned'));
                $('.hp-sub-nav .hp-page-label', page).after(
                        $(FILTERBAR + ' .hp-master-referrer', page));
                $(FILTERBAR, page).css('width', '');
                $(FILTERBAR, page).next().css('left', '');
                $(SUBNAV_RESET_FILTERS).show();
                
                $(page).removeClass(FILTERBAR_OPEN);
                fireRelayout();
            }

            function openFilterbar() {
                $(page).addClass(FILTERBAR_OPEN);
                $(SUBNAV_RESET_FILTERS).hide();
                $(FILTERBAR, page).append($('.hp-sub-nav .hp-master-referrer', page));
                $(FILTERBAR, page).append(
                    $('.hp-sub-nav .hp-filter', page).addClass('hp-active hp-pinned'));
                fireRelayout();
            }
            
            function toggleFilterbar() {
                if ($(FILTERBAR, page).length > 0 &&
                    ! $(page).hasClass(FILTERBAR_OPEN)) {
                    openFilterbar();
                } else {
                    closeFilterbar();
                }
            }
            
            function resetFilters() {
                presenter.resetFilters();
            }
            
            function onPropertyFilterChange(event, value) {
                var name = $(event.currentTarget).attr('data-filter-property');
                if (name) {
                    presenter.setFilterValue(name, value);
                }
            }
            
            function onReferrerChange(resource) {
                $('.hp-master-referrer', page).remove();
                if (resource) {
                    var elem = $('<div></div>').addClass('hp-master-referrer');
                    
                    $('<label></label>')
                        .text(localizer.getString('core.master.filters.referrerLabel'))
                        .appendTo(elem);
                    
                    var link = linkTargetBuilder.makeLink(resource.name, resource.uri);
                    // is it really a link? 
                    if (link.indexOf("<a") === -1) {
                        elem.text(link);
                    }
                    else {
                        elem.append($(link));
                    }

                    elem.append($('<a></a>').addClass('hp-close').
                        attr('href', '#' + presenter.getReferrerClearLocation()));
                    if (resource.name.length > 20) {
                        $('a:first-child', elem).hpEllipsis();
                    }
                    
                    if ($(FILTERBAR, page).length > 0 &&
                        $(page).hasClass(FILTERBAR_OPEN)) {
                        $(FILTERBAR + ' header', page).after(elem);
                    } else {
                        $('.hp-sub-nav .hp-page-label', page).after(elem);
                    }
                }
            }
            
            function onSortChange(event, sort) {
                presenter.setSort(sort.id, sort.direction);
            }
            
            function onFilterChange(filter) {
                var sort = presenter.getSort();
                $(FILTER, page).each(function (index, elem) {
                    var name = $(elem).attr('data-filter-property');
                    var value = presenter.getFilterValue(name);
                    $(elem).hpSelect('set', value);
                });
                if (sort) {
                    $(SORTER, page).hpSelect('set',
                        {ids: [sort.name], direction: sort.direction});
                }
                searchBoxView.setLocalSearchText(presenter.getSearchText());
            }
            
            function onScroll() {
                var result;
                
                // stop auto scrolling if the user scrolls
                manualScrollTo = $(LIST, page).scrollTop();
                
                $(ITEM, page).each(function (index, item) {
                    result = $(item).data('hpIndexResult');
                    return replaceItem(item, result);
                });
            }
            
            function onKeyDown(event) {
                if ($(LIST, page).is(":focus")) {
                    var keyCode = (event.which ? event.which : event.keyCode);
                    if (keyCode === KEY_DOWN) {
                        manualScrollTo = -1;
                        $('.hp-master-list-item.hp-selected').next().trigger('click');
                        event.stopPropagation();
                        return false;
                    } else if (keyCode === KEY_UP) {
                        manualScrollTo = -1;
                        $('.hp-master-list-item.hp-selected').prev().trigger('click');
                        event.stopPropagation();
                        return false;
                    }
                }
            }
            
            /**
             * @public
             * Stop the timer polling of the index service.
             */
            this.pause = function () {
                presenter.pause();
                presenter.off("indexResultsChanging", onIndexResultsChanging);
                presenter.off("indexResultsChange", onIndexResultsChange);
                presenter.off("indexResultsError", onIndexResultsError);
                presenter.off("selectionChange", onSelectionChange);
                presenter.off("invalidSelection", onInvalidSelection);
                presenter.off("referrerChange", onReferrerChange);
                presenter.off("filterChange", onFilterChange);
                errorView.pause();
                $(COUNT, page).text('');
                $(MATCH_COUNT, page).hide();
            };

            /**
             * @public
             * Resume the timer polling of the index service.
             */
            this.resume = function () {
                resetSelection(presenter.getSelection(), true);
                manualScrollTo = -1;
                presenter.on("indexResultsChanging", onIndexResultsChanging);
                presenter.on("indexResultsChange", onIndexResultsChange);
                presenter.on("indexResultsError", onIndexResultsError);
                presenter.on("selectionChange", onSelectionChange);
                presenter.on("invalidSelection", onInvalidSelection);
                presenter.on("referrerChange", onReferrerChange);
                presenter.on("filterChange", onFilterChange);
                presenter.resume();
                errorView.resume();
            };
            
            /**
             * @public
             * Intialize the view.
             */
            this.init = function (args) {
                resource = args.resource;
                page = args.page;
                renderer = args.listItemRenderer;
                addHelp = args.addHelp;
                addActionLink = args.addActionLink;
                addLink = args.addLink;
                
                localizer.localizeDom(noItems);
                presenter.init(args);
                errorView.init(presenter);
                                    
                if ($('.hp-sub-nav', page).length > 0 &&
                    $('.hp-sub-nav ' + MATCH_COUNT, page).length === 0) {
                    var matchedCount = $('<div></div>')
                        .addClass(MATCH_COUNT_CLASS_NAME)
                        .hide();
                    if ($('.hp-sub-nav .hp-sidebar-control', page).length > 0) {
                        $('.hp-sub-nav .hp-sidebar-control', page).before(matchedCount);
                    } else {
                        $('.hp-sub-nav', page).append(matchedCount);
                    }
                }
                
                $('.hp-sub-nav .hp-select', page).hpSelect();
                $('.hp-master-filter .hp-select', page).hpSelect();
                
                if ($(FILTERBAR, page).length > 0) {
                    if($(page).hasClass(FILTERBAR_OPEN)) {
                        openFilterbar();
                    } else {
                        closeFilterbar();
                    }
                }
                
                $(FILTERBAR_CONTROL, page).on('click', toggleFilterbar);
                $(RESET_FILTERS, page).on('click', resetFilters);
                $(FILTER, page).change(onPropertyFilterChange);
                $(SORTER, page).hpSelect({sorting: true});
                $(SORTER, page).change(onSortChange);
                $(LIST, page).scroll(onScroll);
                $(LIST, page).on('click', COLLAPSER, onCollapserClick);
                $(LIST, page).on('click', ITEM, onItemClick);
                $(page).on('focus', LIST, function (event) {
                    if (event.target === $(LIST, page)[0]) {
                        $(document).off('keydown', onKeyDown);  
                        $(document).on('keydown', onKeyDown);
                    }
                });
                $(page).on('blur', LIST, function (event) {
                    if (event.target === $(LIST, page)[0]) {
                        $(document).off('keydown', onKeyDown);  
                    }
                });
                
                var id = $('#hp-master-sort li:not([data-sort-direction]):not(.hp-sub-options).hp-selected').data('id');
                var direction = $('#hp-master-sort li[data-sort-direction].hp-selected').data('sort-direction');
                if (id) {
                    if (!direction) {
                        direction = 'asc';
                    }
                    presenter.setSort(id, direction);
                }
                
                this.resume();
            };
        }

        return MasterListView;

    }());

    return MasterListView;
});
