/*
 * 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 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",
};
