/*
 * Copyright (C) 2013 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.GeneralTreeElement = class GeneralTreeElement extends WI.TreeElement
{
    constructor(classNames, title, subtitle, representedObject, options)
    {
        super("", representedObject, options);

        this.classNames = classNames;

        this._tooltipHandledSeparately = false;
        this._mainTitle = title || "";
        this._subtitle = subtitle || "";
        this._status = "";
    }

    // Public

    get element()
    {
        return this._listItemNode;
    }

    get iconElement()
    {
        this._createElementsIfNeeded();
        return this._iconElement;
    }

    get statusElement()
    {
        return this._statusElement;
    }

    get titlesElement()
    {
        this._createElementsIfNeeded();
        return this._titlesElement;
    }

    get mainTitleElement()
    {
        this._createElementsIfNeeded();
        return this._mainTitleElement;
    }

    get subtitleElement()
    {
        this._createElementsIfNeeded();
        this._createSubtitleElementIfNeeded();
        return this._subtitleElement;
    }

    get classNames()
    {
        return this._classNames;
    }

    set classNames(x)
    {
        x = x || [];

        if (typeof x === "string")
            x = [x];

        if (Array.shallowEqual(this._classNames, x))
            return;

        if (this._listItemNode && this._classNames)
            this._listItemNode.classList.remove(...this._classNames);

        this._classNames = x;

        if (this._listItemNode)
            this._listItemNode.classList.add(...this._classNames);
    }

    addClassName(className)
    {
        if (this._classNames.includes(className))
            return;

        this._classNames.push(className);

        if (this._listItemNode)
            this._listItemNode.classList.add(className);
    }

    removeClassName(className)
    {
        if (!this._classNames.includes(className))
            return;

        this._classNames.remove(className);

        if (this._listItemNode)
            this._listItemNode.classList.remove(className);
    }

    get mainTitle()
    {
        return this._mainTitle;
    }

    set mainTitle(x)
    {
        x = x || "";

        if (this._mainTitle === x)
            return;

        this._mainTitle = x;
        this._updateTitleElements();
        this.didChange();
        this.dispatchEventToListeners(WI.GeneralTreeElement.Event.MainTitleDidChange);
    }

    get subtitle()
    {
        return this._subtitle;
    }

    set subtitle(x)
    {
        x = x || "";

        if (this._subtitle === x)
            return;

        this._subtitle = x;
        this._updateTitleElements();
        this.didChange();
    }

    get status()
    {
        return this._status;
    }

    set status(x)
    {
        x = x || "";

        if (this._status === x)
            return;

        if (!this._statusElement) {
            this._statusElement = document.createElement("div");
            this._statusElement.className = WI.GeneralTreeElement.StatusElementStyleClassName;
        }

        this._status = x;
        this._updateStatusElement();
    }

    get filterableData()
    {
        return {text: [this.mainTitle, this.subtitle]};
    }

    get tooltipHandledSeparately()
    {
        return this._tooltipHandledSeparately;
    }

    set tooltipHandledSeparately(x)
    {
        this._tooltipHandledSeparately = !!x;
    }

    createFoldersAsNeededForSubpath(subpath)
    {
        if (!subpath)
            return this;

        let components = subpath.split("/");
        if (components.length === 1)
            return this;

        if (!this._subpathFolderTreeElementMap)
            this._subpathFolderTreeElementMap = new Map;

        let currentPath = "";
        let currentFolderTreeElement = this;

        for (let component of components) {
            if (component === components.lastValue)
                break;

            if (currentPath)
                currentPath += "/";
            currentPath += component;

            let cachedFolder = this._subpathFolderTreeElementMap.get(currentPath);
            if (cachedFolder) {
                currentFolderTreeElement = cachedFolder;
                continue;
            }

            let newFolder = new WI.FolderTreeElement(component);
            this._subpathFolderTreeElementMap.set(currentPath, newFolder);

            let index = insertionIndexForObjectInListSortedByFunction(newFolder, currentFolderTreeElement.children, WI.ResourceTreeElement.compareFolderAndResourceTreeElements);
            currentFolderTreeElement.insertChild(newFolder, index);
            currentFolderTreeElement = newFolder;
        }

        return currentFolderTreeElement;
    }

    // Overrides from TreeElement (Private)

    isEventWithinDisclosureTriangle(event)
    {
        return event.target === this._disclosureButton;
    }

    onattach()
    {
        this._createElementsIfNeeded();
        this._updateTitleElements();

        this._listItemNode.classList.add("item");

        if (this._classNames)
            this._listItemNode.classList.add(...this._classNames);

        this._listItemNode.appendChild(this._disclosureButton);
        this._listItemNode.appendChild(this._iconElement);
        if (this._statusElement)
            this._listItemNode.appendChild(this._statusElement);
        this._listItemNode.appendChild(this._titlesElement);
    }

    ondetach()
    {
        // Overridden by subclasses.
    }

    onreveal()
    {
        if (this._listItemNode)
            this._listItemNode.scrollIntoViewIfNeeded(false);
    }

    // Protected

    callFirstAncestorFunction(functionName, args)
    {
        // Call the first ancestor that implements a function named functionName (if any).
        var currentNode = this.parent;
        while (currentNode) {
            if (typeof currentNode[functionName] === "function") {
                currentNode[functionName].apply(currentNode, args);
                break;
            }

            currentNode = currentNode.parent;
        }
    }

    customTitleTooltip()
    {
        // Implemented by subclasses.
    }

    // Private

    _createElementsIfNeeded()
    {
        if (this._createdElements)
            return;

        this._disclosureButton = document.createElement("button");
        this._disclosureButton.className = WI.GeneralTreeElement.DisclosureButtonStyleClassName;

        // Don't allow the disclosure button to be keyboard focusable. The TreeOutline is focusable and has
        // its own keybindings for toggling expand and collapse.
        this._disclosureButton.tabIndex = -1;

        this._iconElement = document.createElement("img");
        this._iconElement.className = WI.GeneralTreeElement.IconElementStyleClassName;

        this._titlesElement = document.createElement("div");
        this._titlesElement.className = WI.GeneralTreeElement.TitlesElementStyleClassName;

        this._mainTitleElement = document.createElement("span");
        this._mainTitleElement.className = WI.GeneralTreeElement.MainTitleElementStyleClassName;
        this._titlesElement.appendChild(this._mainTitleElement);

        this._createdElements = true;
    }

    _createSubtitleElementIfNeeded()
    {
        if (this._subtitleElement)
            return;

        this._subtitleElement = document.createElement("span");
        this._subtitleElement.className = WI.GeneralTreeElement.SubtitleElementStyleClassName;
        this._titlesElement.appendChild(this._subtitleElement);
    }

    _updateTitleElements()
    {
        if (!this._createdElements)
            return;

        if (typeof this._mainTitle === "string") {
            if (this._mainTitleElement.textContent !== this._mainTitle)
                this._mainTitleElement.textContent = this._mainTitle;
        } else if (this._mainTitle instanceof Node) {
            this._mainTitleElement.removeChildren();
            this._mainTitleElement.appendChild(this._mainTitle);
        }

        if (typeof this._subtitle === "string" && this._subtitle) {
            this._createSubtitleElementIfNeeded();
            if (this._subtitleElement.textContent !== this._subtitle)
                this._subtitleElement.textContent = this._subtitle;
            this._titlesElement.classList.remove(WI.GeneralTreeElement.NoSubtitleStyleClassName);
        } else if (this._subtitle instanceof Node) {
            this._createSubtitleElementIfNeeded();
            this._subtitleElement.removeChildren();
            this._subtitleElement.appendChild(this._subtitle);
            this._titlesElement.classList.remove(WI.GeneralTreeElement.NoSubtitleStyleClassName);
        } else {
            if (this._subtitleElement)
                this._subtitleElement.textContent = "";
            this._titlesElement.classList.add(WI.GeneralTreeElement.NoSubtitleStyleClassName);
        }

        // Set a default tooltip if there isn't a custom one already assigned.
        if (!this.tooltip && !this._tooltipHandledSeparately)
            this._updateTitleTooltip();
    }

    _updateTitleTooltip()
    {
        console.assert(this._listItemNode);
        if (!this._listItemNode)
            return;

        let tooltip = this.customTitleTooltip();
        if (!tooltip) {
            // Get the textContent for the elements since they can contain other nodes,
            // and the tool tip only cares about the text.
            let mainTitleText = this._mainTitleElement.textContent;
            let subtitleText = this._subtitleElement ? this._subtitleElement.textContent : "";
            let large = this.treeOutline && this.treeOutline.large;
            if (mainTitleText && subtitleText)
                tooltip = mainTitleText + (large ? "\n" : " \u2014 ") + subtitleText;
            else if (mainTitleText)
                tooltip = mainTitleText;
            else
                tooltip = subtitleText;
        }

        this._listItemNode.title = tooltip;
    }

    _updateStatusElement()
    {
        if (!this._statusElement)
            return;

        if (!this._statusElement.parentNode && this._listItemNode)
            this._listItemNode.insertBefore(this._statusElement, this._titlesElement);

        if (this._status instanceof Node) {
            this._statusElement.removeChildren();
            this._statusElement.appendChild(this._status);
        } else
            this._statusElement.textContent = this._status;
    }
};

WI.GeneralTreeElement.DisclosureButtonStyleClassName = "disclosure-button";
WI.GeneralTreeElement.IconElementStyleClassName = "icon";
WI.GeneralTreeElement.StatusElementStyleClassName = "status";
WI.GeneralTreeElement.TitlesElementStyleClassName = "titles";
WI.GeneralTreeElement.MainTitleElementStyleClassName = "title";
WI.GeneralTreeElement.SubtitleElementStyleClassName = "subtitle";
WI.GeneralTreeElement.NoSubtitleStyleClassName = "no-subtitle";

WI.GeneralTreeElement.Event = {
    MainTitleDidChange: "general-tree-element-main-title-did-change"
};
