/*
 * Copyright (C) 2013, 2015 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 */

WI.Sidebar = class Sidebar extends WI.View
{
    constructor(element, side, sidebarPanels, role, label, hasNavigationBar)
    {
        super(element);

        console.assert(!side || side === WI.Sidebar.Sides.Left || side === WI.Sidebar.Sides.Right);
        this._side = side || WI.Sidebar.Sides.Left;
        this._collapsed = true;

        this.element.classList.add("sidebar", this._side, WI.Sidebar.CollapsedStyleClassName);

        this.element.setAttribute("role", role || "group");
        if (label)
            this.element.setAttribute("aria-label", label);

        if (hasNavigationBar) {
            this.element.classList.add("has-navigation-bar");

            this._navigationBar = new WI.SidebarNavigationBar(null, null, "tablist");
            this._navigationBar.addEventListener(WI.NavigationBar.Event.NavigationItemSelected, this._navigationItemSelected, this);
            this.addSubview(this._navigationBar);
        }

        this._resizer = new WI.Resizer(WI.Resizer.RuleOrientation.Vertical, this);
        this.element.insertBefore(this._resizer.element, this.element.firstChild);

        this._sidebarPanels = [];

        if (sidebarPanels) {
            for (let sidebarPanel of sidebarPanels)
                this.addSidebarPanel(sidebarPanel);
        }
    }

    // Public

    addSidebarPanel(sidebarPanel)
    {
        this.insertSidebarPanel(sidebarPanel, this._sidebarPanels.length);
    }

    insertSidebarPanel(sidebarPanel, index)
    {
        console.assert(sidebarPanel instanceof WI.SidebarPanel);
        if (!(sidebarPanel instanceof WI.SidebarPanel))
            return;

        console.assert(!sidebarPanel.parentSidebar);
        if (sidebarPanel.parentSidebar)
            return;

        console.assert(index >= 0 && index <= this._sidebarPanels.length);
        this._sidebarPanels.splice(index, 0, sidebarPanel);

        if (this._navigationBar) {
            console.assert(sidebarPanel.navigationItem);
            this._navigationBar.insertNavigationItem(sidebarPanel.navigationItem, index);
        }
    }

    removeSidebarPanel(sidebarPanelOrIdentifierOrIndex)
    {
        var sidebarPanel = this.findSidebarPanel(sidebarPanelOrIdentifierOrIndex);
        if (!sidebarPanel)
            return;

        if (sidebarPanel.visible) {
            sidebarPanel.hidden();
            sidebarPanel.visibilityDidChange();
        }

        sidebarPanel.selected = false;

        if (this._selectedSidebarPanel === sidebarPanel) {
            var index = this._sidebarPanels.indexOf(sidebarPanel);
            this.selectedSidebarPanel = this._sidebarPanels[index - 1] || this._sidebarPanels[index + 1] || null;
        }

        this._sidebarPanels.remove(sidebarPanel);

        if (this._navigationBar) {
            console.assert(sidebarPanel.navigationItem);
            this._navigationBar.removeNavigationItem(sidebarPanel.navigationItem);
        }
    }

    get selectedSidebarPanel()
    {
        return this._selectedSidebarPanel || null;
    }

    set selectedSidebarPanel(sidebarPanelOrIdentifierOrIndex)
    {
        var sidebarPanel = this.findSidebarPanel(sidebarPanelOrIdentifierOrIndex);
        if (this._selectedSidebarPanel === sidebarPanel)
            return;

        if (this._selectedSidebarPanel) {
            this._selectedSidebarPanel.hidden();
            this._selectedSidebarPanel.visibilityDidChange();
            this._selectedSidebarPanel.selected = false;
            this.removeSubview(this._selectedSidebarPanel);
        }

        this._selectedSidebarPanel = sidebarPanel || null;

        if (this._navigationBar)
            this._navigationBar.selectedNavigationItem = sidebarPanel ? sidebarPanel.navigationItem : null;

        if (this._selectedSidebarPanel) {
            this.addSubview(this._selectedSidebarPanel);
            this._selectedSidebarPanel.selected = true;
            this._selectedSidebarPanel.shown();
            this._selectedSidebarPanel.visibilityDidChange();
        }

        this.dispatchEventToListeners(WI.Sidebar.Event.SidebarPanelSelected);
    }

    get minimumWidth()
    {
        if (this._navigationBar)
            return Math.max(WI.Sidebar.AbsoluteMinimumWidth, this._navigationBar.minimumWidth);
        if (this._selectedSidebarPanel)
            return Math.max(WI.Sidebar.AbsoluteMinimumWidth, this._selectedSidebarPanel.minimumWidth);
        return WI.Sidebar.AbsoluteMinimumWidth;
    }

    get maximumWidth()
    {
        return WI.getMaximumSidebarWidth(this);
    }

    get width()
    {
        return this.element.offsetWidth;
    }

    set width(newWidth)
    {
        if (newWidth === this.width)
            return;

        this._recalculateWidth(newWidth);
    }

    get collapsed()
    {
        return this._collapsed;
    }

    set collapsed(flag)
    {
        if (flag === this._collapsed)
            return;

        this._collapsed = flag || false;
        this.element.classList.toggle(WI.Sidebar.CollapsedStyleClassName);

        if (!this._collapsed && this._navigationBar)
            this._navigationBar.needsLayout();

        if (this._selectedSidebarPanel) {
            if (this._selectedSidebarPanel.visible)
                this._selectedSidebarPanel.shown();
            else
                this._selectedSidebarPanel.hidden();

            this._selectedSidebarPanel.visibilityDidChange();
        }

        this.dispatchEventToListeners(WI.Sidebar.Event.CollapsedStateDidChange);
        this.dispatchEventToListeners(WI.Sidebar.Event.WidthDidChange);
    }

    get sidebarPanels()
    {
        return this._sidebarPanels;
    }

    get side()
    {
        return this._side;
    }

    findSidebarPanel(sidebarPanelOrIdentifierOrIndex)
    {
        var sidebarPanel = null;

        if (sidebarPanelOrIdentifierOrIndex instanceof WI.SidebarPanel) {
            if (this._sidebarPanels.includes(sidebarPanelOrIdentifierOrIndex))
                sidebarPanel = sidebarPanelOrIdentifierOrIndex;
        } else if (typeof sidebarPanelOrIdentifierOrIndex === "number") {
            sidebarPanel = this._sidebarPanels[sidebarPanelOrIdentifierOrIndex];
        } else if (typeof sidebarPanelOrIdentifierOrIndex === "string") {
            for (var i = 0; i < this._sidebarPanels.length; ++i) {
                if (this._sidebarPanels[i].identifier === sidebarPanelOrIdentifierOrIndex) {
                    sidebarPanel = this._sidebarPanels[i];
                    break;
                }
            }
        }

        return sidebarPanel;
    }

    // Protected

    resizerDragStarted(resizer)
    {
        this._widthBeforeResize = this.width;
    }

    resizerDragging(resizer, positionDelta)
    {
        if (this._side === WI.Sidebar.Sides.Left)
            positionDelta *= -1;

        if (WI.resolvedLayoutDirection() === WI.LayoutDirection.RTL)
            positionDelta *= -1;

        var newWidth = positionDelta + this._widthBeforeResize;
        this.width = newWidth;
        this.collapsed = newWidth < (this.minimumWidth / 2);
    }

    resizerDragEnded(resizer)
    {
        if (this._widthBeforeResize === this.width)
            return;

        if (!this.collapsed && this._navigationBar)
            this._navigationBar.sizeDidChange();

        if (!this.collapsed && this._selectedSidebarPanel)
            this._selectedSidebarPanel.sizeDidChange();
    }

    // Private

    _recalculateWidth(newWidth = this.width)
    {
        // Need to add 1 because of the 1px border-right.
        newWidth = Math.ceil(Number.constrain(newWidth, this.minimumWidth + 1, this.maximumWidth));
        this.element.style.width = `${newWidth}px`;

        if (this.collapsed)
            return;

        if (this._navigationBar)
            this._navigationBar.updateLayoutIfNeeded(WI.View.LayoutReason.Resize);

        if (this._selectedSidebarPanel)
            this._selectedSidebarPanel.updateLayoutIfNeeded(WI.View.LayoutReason.Resize);

        this.dispatchEventToListeners(WI.Sidebar.Event.WidthDidChange, {newWidth});
    }

    _navigationItemSelected(event)
    {
        this.selectedSidebarPanel = event.target.selectedNavigationItem ? event.target.selectedNavigationItem.identifier : null;
    }
};

WI.Sidebar.CollapsedStyleClassName = "collapsed";
WI.Sidebar.AbsoluteMinimumWidth = 200;

WI.Sidebar.Sides = {
    Right: "right",
    Left: "left"
};

WI.Sidebar.Event = {
    SidebarPanelSelected: "sidebar-panel-selected",
    CollapsedStateDidChange: "sidebar-collapsed-state-did-change",
    WidthDidChange: "sidebar-width-did-change",
};
