/*
 * 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.HierarchicalPathNavigationItem = class HierarchicalPathNavigationItem extends WI.NavigationItem
{
    constructor(identifier, components)
    {
        super(identifier);

        this._collapsedComponent = null;
        this._needsUpdate = false;

        this.components = components;
    }

    // Public

    get components()
    {
        return this._components;
    }

    set components(newComponents)
    {
        if (!newComponents)
            newComponents = [];

        let componentsEqual = function(a, b) {
            let getRepresentedObjects = (component) => component.representedObject;
            let representedObjectsA = a.map(getRepresentedObjects);
            let representedObjectsB = b.map(getRepresentedObjects);
            if (!Array.shallowEqual(representedObjectsA, representedObjectsB))
                return false;

            let getExtraComparisonData = (component) => component.comparisonData;
            let extraComparisonDataA = a.map(getExtraComparisonData);
            let extraComparisonDataB = b.map(getExtraComparisonData);
            return Array.shallowEqual(extraComparisonDataA, extraComparisonDataB);
        };

        if (this._components && componentsEqual(this._components, newComponents))
            return;

        if (this._components) {
            for (let component of this._components)
                component.removeEventListener(WI.HierarchicalPathComponent.Event.SiblingWasSelected, this._siblingPathComponentWasSelected, this);
        }

        this._components = newComponents.slice(0);

        for (let component of this._components)
            component.addEventListener(WI.HierarchicalPathComponent.Event.SiblingWasSelected, this._siblingPathComponentWasSelected, this);

        // Wait until layout to update the DOM.
        this._needsUpdate = true;

        // Update layout for the so other items can adjust to the extra space (or lack thereof) too.
        if (this.parentNavigationBar)
            this.parentNavigationBar.needsLayout();
    }

    get lastComponent()
    {
        return this._components.lastValue || null;
    }

    get alwaysShowLastPathComponentSeparator()
    {
        return this.element.classList.contains(WI.HierarchicalPathNavigationItem.AlwaysShowLastPathComponentSeparatorStyleClassName);
    }

    set alwaysShowLastPathComponentSeparator(flag)
    {
        if (flag)
            this.element.classList.add(WI.HierarchicalPathNavigationItem.AlwaysShowLastPathComponentSeparatorStyleClassName);
        else
            this.element.classList.remove(WI.HierarchicalPathNavigationItem.AlwaysShowLastPathComponentSeparatorStyleClassName);
    }

    update(options = {})
    {
        this._updateComponentsIfNeeded();

        super.update(options);

        var navigationBar = this.parentNavigationBar;
        if (!navigationBar)
            return;

        if (this._collapsedComponent) {
            this.element.removeChild(this._collapsedComponent.element);
            this._collapsedComponent = null;
        }

        // Expand our components to full width to test if the items can fit at full width.
        for (var i = 0; i < this._components.length; ++i) {
            this._components[i].hidden = false;
            this._components[i].forcedWidth = null;
            this._components[i].hideTooltip = true;
        }

        if (options.expandOnly)
            return;

        if (navigationBar.sizesToFit)
            return;

        // Iterate over all the other navigation items in the bar and calculate their width.
        var totalOtherItemsWidth = 0;
        for (var i = 0; i < navigationBar.navigationItems.length; ++i) {
            // Skip ourself.
            if (navigationBar.navigationItems[i] === this)
                continue;

            // Skip flexible space items since they can take up no space at the minimum width.
            if (navigationBar.navigationItems[i] instanceof WI.FlexibleSpaceNavigationItem)
                continue;

            totalOtherItemsWidth += navigationBar.navigationItems[i].element.realOffsetWidth;
        }

        // Calculate the width for all the components.
        var thisItemWidth = 0;
        var componentWidths = [];
        for (var i = 0; i < this._components.length; ++i) {
            var componentWidth = this._components[i].element.realOffsetWidth;
            componentWidths.push(componentWidth);
            thisItemWidth += componentWidth;
        }

        // If all our components fit with the other navigation items in the width of the bar,
        // then we don't need to collapse any components.
        var barWidth = navigationBar.element.realOffsetWidth;
        if (totalOtherItemsWidth + thisItemWidth <= barWidth)
            return;

        // Calculate the width we need to remove from our components, then iterate over them
        // and force their width to be smaller.
        var widthToRemove = totalOtherItemsWidth + thisItemWidth - barWidth;
        for (var i = 0; i < this._components.length; ++i) {
            var componentWidth = componentWidths[i];

            this._components[i].hideTooltip = false;

            // Try to take the whole width we need to remove from each component.
            var forcedWidth = componentWidth - widthToRemove;
            this._components[i].forcedWidth = forcedWidth;

            // Since components have a minimum width, we need to see how much was actually
            // removed and subtract that from what remans to be removed.
            componentWidths[i] = Math.max(this._components[i].minimumWidth, forcedWidth);
            widthToRemove -= componentWidth - componentWidths[i];

            // If there is nothing else to remove, then we can stop.
            if (widthToRemove <= 0)
                break;
        }

        // If there is nothing else to remove, then we can stop.
        if (widthToRemove <= 0)
            return;

        // If there are 3 or fewer components, then we can stop. Collapsing the middle of 3 components
        // does not save more than a few pixels over just the icon, so it isn't worth it unless there
        // are 4 or more components.
        if (this._components.length <= 3)
            return;

        // We want to collapse the middle components, so find the nearest middle index.
        var middle = this._components.length >> 1;
        var distance = -1;
        var i = middle;

        // Create a component that will represent the hidden components with a ellipse as the display name.
        this._collapsedComponent = new WI.HierarchicalPathComponent(ellipsis, []);
        this._collapsedComponent.collapsed = true;

        // Insert it in the middle, it doesn't matter exactly where since the elements around it will be hidden soon.
        this.element.insertBefore(this._collapsedComponent.element, this._components[middle].element);

        // Add the width of the collapsed component to the width we need to remove.
        widthToRemove += this._collapsedComponent.minimumWidth;

        var hiddenDisplayNames = [];

        // Loop through the components starting at the middle and fanning out in each direction.
        while (i >= 0 && i <= this._components.length - 1) {
            // Only hide components in the middle and never the ends.
            if (i > 0 && i < this._components.length - 1) {
                var component = this._components[i];
                component.hidden = true;

                // Remember the displayName so it can be put in the tool tip of the collapsed component.
                if (distance > 0)
                    hiddenDisplayNames.unshift(component.displayName);
                else
                    hiddenDisplayNames.push(component.displayName);

                // Fully subtract the hidden component's width.
                widthToRemove -= componentWidths[i];

                // If there is nothing else to remove, then we can stop.
                if (widthToRemove <= 0)
                    break;
            }

            // Calculate the next index.
            i = middle + distance;

            // Increment the distance when it is in the positive direction.
            if (distance > 0)
                ++distance;

            // Flip the direction of the distance.
            distance *= -1;
        }

        // Set the tool tip of the collapsed component.
        this._collapsedComponent.element.title = hiddenDisplayNames.join("\n");
    }

    // Protected

    get additionalClassNames()
    {
        return ["hierarchical-path"];
    }

    // Private

    _updateComponentsIfNeeded()
    {
        if (!this._needsUpdate)
            return;

        this._needsUpdate = false;

        this.element.removeChildren();
        this._collapsedComponent = null;

        for (let component of this._components)
            this.element.appendChild(component.element);
    }

    _siblingPathComponentWasSelected(event)
    {
        this.dispatchEventToListeners(WI.HierarchicalPathNavigationItem.Event.PathComponentWasSelected, event.data);
    }
};

WI.HierarchicalPathNavigationItem.AlwaysShowLastPathComponentSeparatorStyleClassName = "always-show-last-path-component-separator";

WI.HierarchicalPathNavigationItem.Event = {
    PathComponentWasSelected: "hierarchical-path-navigation-item-path-component-was-selected"
};
