(function (paw, mainMenuScanner) {
    function MobileMenuComponent($bar, touchScrollSortList, onMenuItemsSorted) {
        var self = this;
        this.touchScrollSortList = touchScrollSortList;
        this.onMenuItemsSorted = onMenuItemsSorted;

        this.menuBar = new paw.com.mobileMenu.MobileMenuBarComponent($bar, this);
        this.$elt = null;
        this.$list = null;

        this.onMenuItemSelected = function (e) {
            var $li = $(this).parent();
            if ($li.hasClass('menu-item-issorting')) {
                e.preventDefault();
                return;
            }
            var item = mainMenuScanner.getItem($li.attr('data-list-item-id'));

            self.switchMenuState($li, item);
        };
    }

    MobileMenuComponent.prototype.init = function () {
        this.menuBar.init();
    };

    MobileMenuComponent.prototype.destroy = function () {
        this.menuBar.destroy();
    };

    MobileMenuComponent.prototype.openMenu = function (item) {
        var navItems = mainMenuScanner.scanNavigationItems(paw.utils.value.notSet(item) ? null : item);
        this.composeMenu(navItems, item);
        this.$elt = $('#paw-mobile-menu');
        this.$list = this.$elt.find('> .paw-mobile-menu ul.paw-mobile-menu-items');
        
        this.handleSortable();

        $('#paw-mobile-menu .paw-mobile-menu').css({
            bottom: $('#paw-mobile-menu .paw-mobile-menu').outerHeight() * -1,
        });

        $('#paw-mobile-menu').css({
            opacity: 0
        }).animate({
            opacity: 1
        }, 200);
        $('#paw-mobile-menu .paw-mobile-menu').animate({
            bottom: 0
        }, 200);
    };

    MobileMenuComponent.prototype.closeMenu = function () {
        var self = this;
        $('button#paw-mobile-menu-close').off('click');
        $('#paw-mobile-menu ul.paw-mobile-menu-items').animate({
            height: 0,
            'min-height': 0
        }, 200, function () {
            $('#paw-mobile-menu .paw-mobile-menu').animate({
                bottom: $('#paw-mobile-menu .paw-mobile-menu').outerHeight() * -1,
            }, 200, function () {
                $('#paw-mobile-menu').animate({
                    opacity: 0
                }, 200, function () {
                    self.deregisterSortable();
                    self.$elt.remove();

                    self.$elt = null;
                    self.$list = null;
                });
            });
        });

        
    };

    MobileMenuComponent.prototype.switchMenuState = function ($li, item) {
        var hasParent = paw.utils.value.isSet(item);
        var navItems = mainMenuScanner.scanNavigationItems(hasParent ? item : null);

        this.deregisterSortable();

        $('#paw-mobile-menu ul.paw-mobile-menu-items > li > a[data-paw-mobile-menu="sub-menu"]').off('click');

        $('#paw-mobile-menu ul.paw-mobile-menu-items').empty().append(this.composeMenuItems(navItems, item));
        var $header = $('#paw-mobile-menu .paw-mobile-menu-header');
        $header.find('button#paw-mobile-menu-back').off('click');
        $header.remove();

        $('#paw-mobile-menu .paw-mobile-menu').addClass('paw-mobile-menu-top-level')
        $('#paw-mobile-menu ul.paw-mobile-menu-items').addClass('sortable-menu');

        if (hasParent) {
            $('#paw-mobile-menu > .paw-mobile-menu').removeClass('paw-mobile-menu-top-level').prepend(this.composeMenuHeader(item));
            $('#paw-mobile-menu ul.paw-mobile-menu-items').removeClass('sortable-menu');
        }
        else {
            this.handleSortable();
        }
        this.handleItemsVisibility();
        this.setMenuHeight(navItems.length);
    };

    MobileMenuComponent.prototype.composeMenu = function (items, parent) {
        var self = this;
        var hasParent = paw.utils.value.isSet(parent);
        var markup = [];
        markup.push('<div id="paw-mobile-menu" class="paw-mobile-menu-container">');
        markup.push('   <div class="paw-mobile-menu paw-area-v paw-nooverflow paw-holder ' + (hasParent ? '' : 'paw-mobile-menu-top-level') + '">');
        markup.push('      <div class="paw-col-d paw-scrollable">');
        markup.push('         <ul class="paw-mobile-menu-items' + (hasParent ? '' : ' sortable-menu') + '"></ul>');
        markup.push('      </div>');
        markup.push('      <div class="paw-mobile-menu-footer paw-col">');
        markup.push('         <button id="paw-mobile-menu-close" type="button"><i class="fa fa-close fa-2x"></i></button>');
        markup.push('      </div>');
        markup.push('   </div>');
        markup.push('</div>');

        $('body').append(markup.join('\n'));

        var $menu = $('#paw-mobile-menu');
        var $menuItems = $menu.find('ul.paw-mobile-menu-items');
        $menuItems.append(this.composeMenuItems(items, parent));
        if (hasParent) {
            $menu.children('.paw-mobile-menu').prepend(this.composeMenuHeader(parent));
        }

        this.handleItemsVisibility();
        this.setMenuHeight(items.length);

        $('button#paw-mobile-menu-close').on('click', function () {
            self.closeMenu();
        });

        $('li > a[data-paw-mobile-menu="sub-menu"]').on('click', this.onMenuItemSelected);
    };

    MobileMenuComponent.prototype.composeMenuItems = function (items, parent) {
        var self = this;
        var markup = [];
        paw.utils.iterable.iterate(items, function (item, i) {
            markup.push('<li class="paw-mobile-menu-item' + (item.isActive ? ' active' : '') + '" data-list-item-id="' + item.listItemId + '">');
            markup.push('   <a class="paw-area-h paw-items-middle" ' + (item.isDropdown ? 'data-paw-mobile-menu="sub-menu"' : 'href="' + item.link + '"') + '>');
            if (paw.utils.value.isSet(item.icon)) {
                markup.push('      <div class="paw-col">');
                markup.push('         <i class="' + item.icon + ' paw-mobile-menu-item-icon"></i>');
                markup.push('      </div>');
            }
            markup.push('      <div class="paw-col-d">');
            markup.push('         <span>' + item.label + '</span>');
            markup.push('      </div>');
            if (item.isDropdown) {
                markup.push('      <div class="paw-col">');
                markup.push('         <i class="fa fa-angle-right"></i>');
                markup.push('      </div>');
            }
            markup.push('   </a>');
            markup.push('</li>');
        });
        $items = $(markup.join('\n'));
        $items.find('> a[data-paw-mobile-menu="sub-menu"]').on('click', this.onMenuItemSelected);
        return $items;
    };

    MobileMenuComponent.prototype.composeMenuHeader = function (item) {
        var self = this;
        var markup = [];
        markup.push('<div class="paw-col paw-area-h paw-items-middle paw-mobile-menu-header">');
        markup.push('   <div class="paw-col">');
        markup.push('      <button id="paw-mobile-menu-back" class="paw-btn-mobile-menu-back" type="button"><i class="fa fa-angle-left fa-2x"></i></button>');
        markup.push('   </div>');
        markup.push('   <div class="paw-col-d">');
        markup.push('      <span>' + item.label + '</span>');
        markup.push('   </div>');
        markup.push('</div>');

        var $header = $(markup.join('\n'));
        $header.find('button#paw-mobile-menu-back').on('click', function () {
            self.switchMenuState(null, item.parent);
        });

        return $header;
    }

    MobileMenuComponent.prototype.setMenuHeight = function (navItemsLength) {
        var $mobileMenu = $('#paw-mobile-menu .paw-mobile-menu');
        $mobileMenu.removeClass('paw-holder');

        var $header = $('#paw-mobile-menu .paw-mobile-menu-header');
        var $items = $('#paw-mobile-menu ul.paw-mobile-menu-items');
        var itemsHeight = $items.children('li:not(.hidden-column)').outerHeight() * navItemsLength;
        var headerHeight = $header.length > 0? $header.outerHeight() : 0;

        var footerHeight = $('#paw-mobile-menu .paw-mobile-menu-footer').outerHeight();
        var bodyHeight = $('#paw-mobile-menu').innerHeight() - headerHeight - footerHeight;
        
        
        if (itemsHeight < bodyHeight) {
            $items.animate({
                'min-height': itemsHeight,
                'height': itemsHeight,
                'max-height': itemsHeight
            }, 200);
        }
        else {
            $items.animate({
                'min-height': bodyHeight,
                'height': bodyHeight,
                'max-height': bodyHeight
            }, 200);
            
        }
    };

    MobileMenuComponent.prototype.handleItemsVisibility = function () {
        $('#paw-mobile-menu .paw-mobile-menu ul.paw-mobile-menu-items > li').each(function () {
            var $li = $(this);
            var item = mainMenuScanner.getItem($li.attr('data-list-item-id'));
            if (item.isHidden) {
                $li.addClass('hidden-column');
            }
            else {
                $li.removeClass('hidden-column');
            }
        });
    };

    MobileMenuComponent.prototype.handleSortable = function () {
        var self = this;
        if (this.$list.hasClass("ui-sortable")) return;
        this.touchScrollSortList(this.$list.parent(), this.$list);
        
        this.$list.sortable({
            cursor: "move",
            placeholder: "ui-state-highlight",
            opacity: 0.7,
            helper: "clone",
            items: "li:not([data-sortable])",
            start: function (e, ui) {
                ui.item.addClass('menu-item-issorting');
                ui.helper.addClass('menu-sort-item-clone');
            },
            stop: function (e, ui) {
                setTimeout(function () {
                    ui.item.removeClass('menu-item-issorting');
                }, 100);
                if (wasMenuScrolled) {
                    wasMenuScrolled = false;
                    return false;
                }
                else {
                    self.onMenuItemsSorted(self.$list);
                }
            }
        }).disableSelection();
    };

    MobileMenuComponent.prototype.deregisterSortable = function () {
        if (this.$list.hasClass('ui-sortable')) {
            this.$list.sortable('destroy');
            this.$list.off('touchstart').off('touchnmove').off('touchend');
            this.$list.removeClass('ui-sortable');
        }
    };

    MobileMenuComponent.prototype.reorder = function () {
        this.menuBar.reorder();
    };

    paw.com.mobileMenu.MobileMenuComponent = MobileMenuComponent;
})(paw, paw.helper.mainMenuScanner);