/*
 * Copyright (C) 2014-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.
 * 3.  Neither the name of Apple Inc. ("Apple") nor the names of
 *     its contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE 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 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.GradientSlider = class GradientSlider extends WI.Object
{
    constructor(delegate)
    {
        super();

        this.delegate = delegate;

        this._element = null;
        this._stops = [];
        this._knobs = [];

        this._selectedKnob = null;
        this._canvas = document.createElement("canvas");

        this._keyboardShortcutEsc = new WI.KeyboardShortcut(null, WI.KeyboardShortcut.Key.Escape);
    }

    // Public

    get element()
    {
        if (!this._element) {
            this._element = document.createElement("div");
            this._element.className = "gradient-slider";
            this._element.appendChild(this._canvas);

            this._addArea = this._element.appendChild(document.createElement("div"));
            this._addArea.addEventListener("mouseover", this);
            this._addArea.addEventListener("mousemove", this);
            this._addArea.addEventListener("mouseout", this);
            this._addArea.addEventListener("click", this);
            this._addArea.className = WI.GradientSlider.AddAreaClassName;
        }
        return this._element;
    }

    get stops()
    {
        return this._stops;
    }

    set stops(stops)
    {
        this._stops = stops;

        this._updateStops();
    }

    get selectedStop()
    {
        return this._selectedKnob ? this._selectedKnob.stop : null;
    }

    // Protected

    handleEvent(event)
    {
        switch (event.type) {
        case "mouseover":
            this._handleMouseover(event);
            break;
        case "mousemove":
            this._handleMousemove(event);
            break;
        case "mouseout":
            this._handleMouseout(event);
            break;
        case "click":
            this._handleClick(event);
            break;
        }
    }

    handleKeydownEvent(event)
    {
        if (!this._keyboardShortcutEsc.matchesEvent(event) || !this._selectedKnob || !this._selectedKnob.selected)
            return false;

        this._selectedKnob.selected = false;

        return true;
    }

    knobXDidChange(knob)
    {
        knob.stop.offset = knob.x / WI.GradientSlider.Width;
        this._sortStops();
        this._updateCanvas();
    }

    knobCanDetach(knob)
    {
        return this._knobs.length > 2;
    }

    knobWillDetach(knob)
    {
        knob.element.classList.add(WI.GradientSlider.DetachingClassName);

        this._stops.remove(knob.stop);
        this._knobs.remove(knob);
        this._sortStops();
        this._updateCanvas();
    }

    knobSelectionChanged(knob)
    {
        if (this._selectedKnob && this._selectedKnob !== knob && knob.selected)
            this._selectedKnob.selected = false;

        this._selectedKnob = knob.selected ? knob : null;

        if (this.delegate && typeof this.delegate.gradientSliderStopWasSelected === "function")
            this.delegate.gradientSliderStopWasSelected(this, knob.stop);

        if (this._selectedKnob)
            WI.addWindowKeydownListener(this);
        else
            WI.removeWindowKeydownListener(this);
    }

    // Private

    _handleMouseover(event)
    {
        this._updateShadowKnob(event);
    }

    _handleMousemove(event)
    {
        this._updateShadowKnob(event);
    }

    _handleMouseout(event)
    {
        if (!this._shadowKnob)
            return;

        this._shadowKnob.element.remove();
        delete this._shadowKnob;
    }

    _handleClick(event)
    {
        this._updateShadowKnob(event);

        this._knobs.push(this._shadowKnob);

        this._shadowKnob.element.classList.remove(WI.GradientSlider.ShadowClassName);

        var stop = {offset: this._shadowKnob.x / WI.GradientSlider.Width, color: this._shadowKnob.wellColor};
        this._stops.push(stop);
        this._sortStops();
        this._updateStops();

        this._knobs[this._stops.indexOf(stop)].selected = true;

        delete this._shadowKnob;
    }

    _updateShadowKnob(event)
    {
        if (!this._shadowKnob) {
            this._shadowKnob = new WI.GradientSliderKnob(this);
            this._shadowKnob.element.classList.add(WI.GradientSlider.ShadowClassName);
            this.element.appendChild(this._shadowKnob.element);
        }

        this._shadowKnob.x = event.pageX - this.element.getBoundingClientRect().x;

        var colorData = this._canvas.getContext("2d").getImageData(this._shadowKnob.x - 1, 0, 1, 1).data;
        this._shadowKnob.wellColor = new WI.Color(WI.Color.Format.RGB, [colorData[0], colorData[1], colorData[2], colorData[3] / 255]);
    }

    _sortStops()
    {
        this._stops.sort(function(a, b) {
            return a.offset - b.offset;
        });
    }

    _updateStops()
    {
        this._updateCanvas();
        this._updateKnobs();
    }

    _updateCanvas()
    {
        var w = WI.GradientSlider.Width;
        var h = WI.GradientSlider.Height;

        this._canvas.width = w;
        this._canvas.height = h;

        var ctx = this._canvas.getContext("2d");
        var gradient = ctx.createLinearGradient(0, 0, w, 0);
        for (var stop of this._stops)
            gradient.addColorStop(stop.offset, stop.color);

        ctx.clearRect(0, 0, w, h);
        ctx.fillStyle = gradient;
        ctx.fillRect(0, 0, w, h);

        if (this.delegate && typeof this.delegate.gradientSliderStopsDidChange === "function")
            this.delegate.gradientSliderStopsDidChange(this);
    }

    _updateKnobs()
    {
        var selectedStop = this._selectedKnob ? this._selectedKnob.stop : null;

        while (this._knobs.length > this._stops.length)
            this._knobs.pop().element.remove();

        while (this._knobs.length < this._stops.length) {
            var knob = new WI.GradientSliderKnob(this);
            this.element.appendChild(knob.element);
            this._knobs.push(knob);
        }

        for (var i = 0; i < this._stops.length; ++i) {
            var stop = this._stops[i];
            var knob = this._knobs[i];

            knob.stop = stop;
            knob.x = Math.round(stop.offset * WI.GradientSlider.Width);
            knob.selected = stop === selectedStop;
        }
    }
};

WI.GradientSlider.Width = 238;
WI.GradientSlider.Height = 19;

WI.GradientSlider.AddAreaClassName = "add-area";
WI.GradientSlider.DetachingClassName = "detaching";
WI.GradientSlider.ShadowClassName = "shadow";

WI.GradientSliderKnob = class GradientSliderKnob extends WI.Object
{
    constructor(delegate)
    {
        super();

        this._x = 0;
        this._y = 0;
        this._stop = null;

        this.delegate = delegate;

        this._element = document.createElement("div");
        this._element.className = "gradient-slider-knob";

        // Checkers pattern.
        this._element.appendChild(document.createElement("img"));

        this._well = this._element.appendChild(document.createElement("div"));

        this._element.addEventListener("mousedown", this);
    }

    // Public

    get element()
    {
        return this._element;
    }

    get stop()
    {
        return this._stop;
    }

    set stop(stop)
    {
        this.wellColor = stop.color;
        this._stop = stop;
    }

    get x()
    {
        return this._x;
    }

    set x(x) {
        this._x = x;
        this._updateTransform();
    }

    get y()
    {
        return this._x;
    }

    set y(y) {
        this._y = y;
        this._updateTransform();
    }

    get wellColor()
    {
        return this._wellColor;
    }

    set wellColor(color)
    {
        this._wellColor = color;
        this._well.style.backgroundColor = color;
    }

    get selected()
    {
        return this._element.classList.contains(WI.GradientSliderKnob.SelectedClassName);
    }

    set selected(selected)
    {
        if (this.selected === selected)
            return;

        this._element.classList.toggle(WI.GradientSliderKnob.SelectedClassName, selected);

        if (this.delegate && typeof this.delegate.knobSelectionChanged === "function")
            this.delegate.knobSelectionChanged(this);
    }

    // Protected

    handleEvent(event)
    {
        event.preventDefault();
        event.stopPropagation();

        switch (event.type) {
        case "mousedown":
            this._handleMousedown(event);
            break;
        case "mousemove":
            this._handleMousemove(event);
            break;
        case "mouseup":
            this._handleMouseup(event);
            break;
        case "transitionend":
            this._handleTransitionEnd(event);
            break;
        }
    }

    // Private

    _handleMousedown(event)
    {
        this._moved = false;
        this._detaching = false;

        window.addEventListener("mousemove", this, true);
        window.addEventListener("mouseup", this, true);

        this._startX = this.x;
        this._startMouseX = event.pageX;
        this._startMouseY = event.pageY;
    }

    _handleMousemove(event)
    {
        var w = WI.GradientSlider.Width;

        this._moved = true;

        if (!this._detaching && Math.abs(event.pageY - this._startMouseY) > 50) {
            this._detaching = this.delegate && typeof this.delegate.knobCanDetach === "function" && this.delegate.knobCanDetach(this);
            if (this._detaching && this.delegate && typeof this.delegate.knobWillDetach === "function") {
                var translationFromParentToBody = window.webkitConvertPointFromNodeToPage(this.element.parentNode, new WebKitPoint(0, 0));
                this._startMouseX -= translationFromParentToBody.x;
                this._startMouseY -= translationFromParentToBody.y;
                document.body.appendChild(this.element);
                this.delegate.knobWillDetach(this);
            }
        }

        var x = this._startX + event.pageX - this._startMouseX;
        if (!this._detaching)
            x = Math.min(Math.max(0, x), w);
        this.x = x;

        if (this._detaching)
            this.y = event.pageY - this._startMouseY;
        else if (this.delegate && typeof this.delegate.knobXDidChange === "function")
            this.delegate.knobXDidChange(this);
    }

    _handleMouseup(event)
    {
        window.removeEventListener("mousemove", this, true);
        window.removeEventListener("mouseup", this, true);

        if (this._detaching) {
            this.element.addEventListener("transitionend", this);
            this.element.classList.add(WI.GradientSliderKnob.FadeOutClassName);
            this.selected = false;
        } else if (!this._moved)
            this.selected = !this.selected;
    }

    _handleTransitionEnd(event)
    {
        this.element.removeEventListener("transitionend", this);
        this.element.classList.remove(WI.GradientSliderKnob.FadeOutClassName);
        this.element.remove();
    }

    _updateTransform()
    {
        this.element.style.webkitTransform = "translate3d(" + this._x + "px, " + this._y + "px, 0)";
    }
};

WI.GradientSliderKnob.SelectedClassName = "selected";
WI.GradientSliderKnob.FadeOutClassName = "fade-out";
