/*
 * 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.ButtonNavigationItem = class ButtonNavigationItem extends WI.NavigationItem
{
    constructor(identifier, toolTipOrLabel, image, imageWidth, imageHeight, role, label)
    {
        super(identifier, role || "button");

        console.assert(identifier);
        console.assert(toolTipOrLabel);

        this._enabled = true;

        this.element.addEventListener("click", this._mouseClicked.bind(this));

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

        this._buttonStyle = null;
        this._disabled = false;
        this._image = image || null;
        this._imageWidth = imageWidth || 16;
        this._imageHeight = imageHeight || 16;
        this._label = toolTipOrLabel;

        this.buttonStyle = this._image ? WI.ButtonNavigationItem.Style.Image : WI.ButtonNavigationItem.Style.Text;

        if (this.buttonStyle === WI.ButtonNavigationItem.Style.Image)
            this.tooltip = toolTipOrLabel;
    }

    // Public

    get label()
    {
        return this._label;
    }

    set label(newLabel)
    {
        newLabel = newLabel || "";
        if (this._label === newLabel)
            return;

        this._label = newLabel;
        this._update();

        if (this.parentNavigationBar)
            this.parentNavigationBar.needsLayout();
    }

    get image()
    {
        return this._image;
    }

    set image(newImage)
    {
        newImage = newImage || null;
        if (this._image === newImage)
            return;

        this._image = newImage;
        this._update();
    }

    get enabled()
    {
        return this._enabled;
    }

    set enabled(flag)
    {
        flag = !!flag;
        if (this._enabled === flag)
            return;

        this._enabled = flag;
        this.element.classList.toggle("disabled", !this._enabled);
    }

    get buttonStyle()
    {
        return this._buttonStyle;
    }

    set buttonStyle(newButtonStyle)
    {
        newButtonStyle = newButtonStyle || WI.ButtonNavigationItem.Style.Image;
        if (this._buttonStyle === newButtonStyle)
            return;

        this.element.classList.remove(...Object.values(WI.ButtonNavigationItem.Style));
        this.element.classList.add(newButtonStyle);

        this._buttonStyle = newButtonStyle;
        this._update();

        if (this.parentNavigationBar)
            this.parentNavigationBar.needsLayout();
    }

    // Protected

    get totalMargin()
    {
        let totalMargin = super.totalMargin;
        if (this._buttonStyle === ButtonNavigationItem.Style.Text)
            return totalMargin + 4; /* .navigation-bar .item.button.text-only */
        return totalMargin;
    }

    get additionalClassNames()
    {
        return ["button"];
    }

    // Private

    _mouseClicked(event)
    {
        if (!this.enabled)
            return;
        this.dispatchEventToListeners(WI.ButtonNavigationItem.Event.Clicked, {nativeEvent: event});
    }

    _update()
    {
        this.element.removeChildren();

        if (this._buttonStyle === WI.ButtonNavigationItem.Style.Text)
            this.element.textContent = this._label;
        else {
            let glyphElement = WI.ImageUtilities.useSVGSymbol(this._image, "glyph");
            glyphElement.style.width = this._imageWidth + "px";
            glyphElement.style.height = this._imageHeight + "px";
            this.element.appendChild(glyphElement);

            if (this._buttonStyle === WI.ButtonNavigationItem.Style.ImageAndText) {
                let labelElement = this.element.appendChild(document.createElement("span"));
                labelElement.textContent = this._label;
            }
        }
    }
};

WI.ButtonNavigationItem.Event = {
    Clicked: "button-navigation-item-clicked"
};

WI.ButtonNavigationItem.Style = {
    Image: "image-only",
    Text: "text-only",
    ImageAndText: "image-and-text",
};
