// (C) Copyright 2020 Hewlett-Packard Enterprise Company, L.P.
/**
 * @type {Sidebar}
 */
define(['hp/core/EventDispatcher', 'hp/core/Style', 'jquery'],
function (EventDispatcher, style) { "use strict";
  
    var BODY = '#hp-body-div';
    var SIDEBAR = '#hp-sidebar';
    var CONTROL = '#hp-sidebar-controls .hp-pin-right, .hp-sidebar-control .hp-pin-right';
    var PAGE = '.hp-page';
    //var FLYOUT_PIN = '.hp-banner .hp-banner-flyout.hp-active ' + PIN;
    //var PAGE_PIN = PAGE + ' .hp-sidebar-control .hp-pin-right';
    var SIDEBAR_OPEN = 'hp-sidebar-open';
    var SIDEBARRED = 'hp-sidebarred';
    var INACTIVE = 'hp-inactive';

    var Sidebar = (function () {
      
        var dispatcher = new EventDispatcher();
        var priorParent = null;
        var contents = null;
        var priorContents = null;
        var manuallyClosed = false;
        var manuallyOpened = false;
      
        function Sidebar() {
          
            function fireRelayout() {
                // we delay so any CSS animation can finish
                setTimeout(function () {
                    $(PAGE).trigger('relayout');
                }, style.animationDelay());
            }
            
            /**
             * Close the sidebar.
             */
            function close() {
                if ($(BODY).hasClass(SIDEBAR_OPEN)) {
                    $(BODY).removeClass(SIDEBAR_OPEN);
                    $(SIDEBAR).addClass(INACTIVE);
                    fireRelayout();
                }
            }

            /**
             * Open the sidebar.
             */
            function open() {
                if (! $(BODY).hasClass(SIDEBAR_OPEN)) {
                    $(BODY).addClass(SIDEBAR_OPEN);
                    $(SIDEBAR).removeClass(INACTIVE);
                    fireRelayout();
                }
            }
            
            /**
             * If any flyouts are flying, de-activate the sidebar,
             * since the flyouts obscure it.
             */
            function checkFlyouts() {
                if ($('.hp-banner-flyout.hp-active').
                    not('.hp-sidebarred').length === 0) {
                    $(SIDEBAR).removeClass('hp-inactive');
                } else {
                    $(SIDEBAR).addClass('hp-inactive');
                }
            }
            
            function sizeContents() {
                if (contents) {
                    if (contents.hasClass(SIDEBARRED)) {
                        $('.hp-flyout-contents', contents).css('height',
                            $(SIDEBAR).innerHeight() - $('header', contents).outerHeight() -
                            $('footer', contents).outerHeight());
                    } else {
                        $('.hp-flyout-contents', contents).css('height', '');
                    }
                }
            }
            
            /**
             * Put the current sidebar contents back where it came from.
             */
            function remove() {
                if (contents && contents.hasClass(SIDEBARRED)) {
                    contents.removeClass(SIDEBARRED);
                    priorParent.append(contents);
                    dispatcher.fire('sidebarRemove', contents);
                    contents = null;
                }
            }
            
            /**
             * Add to the sidebar.
             */
            function add(element) {
                if (! element.hasClass(SIDEBARRED)) {
                    remove();
                    contents = element;
                    priorParent = contents.parent();
                    priorContents = contents;
                    $(SIDEBAR).append(contents);
                    contents.addClass(SIDEBARRED);
                    sizeContents();
                    dispatcher.fire('sidebarAdd', contents);
                    checkFlyouts();
                    open();
                }
            }
            
            /**
             * Put either the prior contents or the first pinnable flyout
             * into the sidebar.
             */
            function pin() {
                var element;
                if (priorContents) {
                    element = priorContents;
                } else {
                    element = $('.hp-banner-flyout.hp-notable header, ' +
                        '.hp-banner-flyout header').first().
                        parents('.hp-banner-flyout');
                }
                if (element && element.length > 0) {
                    add(element);
                }
            }
            
            /**
             * Close and remove whatever is in the sidebar.
             */
            function onClose() {
                close();
                remove();
                manuallyClosed = true;
                manuallyOpened = false;
            }
            
            /**
             * A page sub-nav is wanting to open the sidebar.
             */
            function onPagePin(event) {
                pin();
                manuallyOpened = true;
                manuallyClosed = false;
            }
            
            function onToggle(event) {
                if ($(BODY).hasClass(SIDEBAR_OPEN)) {
                    onClose();
                } else {
                    onPagePin();
                }
            }
            
            /**
             * Evaluate the window size to see if we should open or close
             * the sidebar.
             */
            function onResize() {
                sizeContents();
            }
            
            this.init = function () {
                $(BODY).on('click', CONTROL, onToggle);
                $(window).on('resize', onResize);
            };
            
            this.add = function (contentsArg) {
                add(contentsArg);
                manuallyOpened = true;
                manuallyClosed = false;
            };
            
            this.remove = function (contentsArg) {
                close();
                remove();
                manuallyClosed = true;
                manuallyOpened = false;
            };
            
            this.checkFlyouts = checkFlyouts;
            
            this.on = function (eventName, callback) {
                dispatcher.on(eventName, callback);
            };

            this.off = function (eventName, callback) {
                dispatcher.off(eventName, callback);
            };
        }

        return new Sidebar();
    }());

    return Sidebar;
});
