/*
 * 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.BreakpointActionView = class BreakpointActionView extends WI.Object
{
    constructor(action, delegate, {omitFocus} = {})
    {
        super();

        console.assert(action);
        console.assert(delegate);

        this._action = action;
        this._delegate = delegate;

        this._element = document.createElement("div");
        this._element.className = "breakpoint-action-block";

        var header = this._element.appendChild(document.createElement("div"));
        header.className = "breakpoint-action-block-header";

        var picker = header.appendChild(document.createElement("select"));
        picker.addEventListener("change", this._pickerChanged.bind(this));

        for (var key in WI.BreakpointAction.Type) {
            var type = WI.BreakpointAction.Type[key];
            var option = document.createElement("option");
            option.textContent = WI.BreakpointActionView.displayStringForType(type);
            option.selected = this._action.type === type;
            option.value = type;
            picker.add(option);
        }

        let buttonContainerElement = header.appendChild(document.createElement("div"));
        buttonContainerElement.classList.add("breakpoint-action-button-container");

        let appendActionButton = buttonContainerElement.appendChild(document.createElement("button"));
        appendActionButton.className = "breakpoint-action-append-button";
        appendActionButton.addEventListener("click", this._appendActionButtonClicked.bind(this));
        appendActionButton.title = WI.UIString("Add new breakpoint action after this action");

        let removeActionButton = buttonContainerElement.appendChild(document.createElement("button"));
        removeActionButton.className = "breakpoint-action-remove-button";
        removeActionButton.addEventListener("click", this._removeAction.bind(this));
        removeActionButton.title = WI.UIString("Delete this breakpoint action");

        this._bodyElement = this._element.appendChild(document.createElement("div"));
        this._bodyElement.className = "breakpoint-action-block-body";

        this._updateBody(omitFocus);
    }

    // Static

    static displayStringForType(type)
    {
        switch (type) {
        case WI.BreakpointAction.Type.Log:
            return WI.UIString("Log Message");
        case WI.BreakpointAction.Type.Evaluate:
            return WI.UIString("Evaluate JavaScript");
        case WI.BreakpointAction.Type.Sound:
            return WI.UIString("Play Sound");
        case WI.BreakpointAction.Type.Probe:
            return WI.UIString("Probe Expression");
        default:
            console.assert(false);
            return "";
        }
    }

    // Public

    get action()
    {
        return this._action;
    }

    get element()
    {
        return this._element;
    }

    // Private

    _pickerChanged(event)
    {
        this._action.type = event.target.value;
        this._updateBody();
        this._delegate.breakpointActionViewResized(this);
    }

    _appendActionButtonClicked(event)
    {
        this._delegate.breakpointActionViewAppendActionView(this, new WI.BreakpointAction(this._action.type));
    }

    _removeAction()
    {
        this._delegate.breakpointActionViewRemoveActionView(this);
    }

    _updateBody(omitFocus)
    {
        this._bodyElement.removeChildren();

        let createOptionsElements = () => {
            let optionsElement = document.createElement("div");

            let emulateUserGestureLabel = optionsElement.appendChild(document.createElement("label"));

            this._emulateUserGestureCheckbox = emulateUserGestureLabel.appendChild(document.createElement("input"));
            this._emulateUserGestureCheckbox.type = "checkbox";
            this._emulateUserGestureCheckbox.checked = this._action.emulateUserGesture;
            this._emulateUserGestureCheckbox.addEventListener("change", this._handleEmulateUserGestureCheckboxChange.bind(this));

            emulateUserGestureLabel.appendChild(document.createTextNode(WI.UIString("Emulate User Gesture", "Emulate User Gesture @ breakpoint action configuration", "Checkbox shown when configuring log/evaluate/probe breakpoint actions to cause it to be evaluated as though it was in response to user interaction.")));

            return optionsElement;
        };

        switch (this._action.type) {
        case WI.BreakpointAction.Type.Log:
            this._bodyElement.hidden = false;

            var input = this._bodyElement.appendChild(document.createElement("input"));
            input.placeholder = WI.UIString("Message");
            input.addEventListener("input", this._handleLogInputInput.bind(this));
            input.value = this._action.data || "";
            input.spellcheck = false;
            if (!omitFocus)
                setTimeout(function() { input.focus(); }, 0);

            var flexWrapper = this._bodyElement.appendChild(document.createElement("div"));
            flexWrapper.className = "flex";

            if (WI.BreakpointAction.supportsEmulateUserAction())
                flexWrapper.appendChild(createOptionsElements());

            var descriptionElement = flexWrapper.appendChild(document.createElement("div"));
            descriptionElement.classList.add("description");
            descriptionElement.setAttribute("dir", "ltr");
            descriptionElement.textContent = WI.UIString("${expr} = expression");
            break;

        case WI.BreakpointAction.Type.Evaluate:
        case WI.BreakpointAction.Type.Probe:
            this._bodyElement.hidden = false;

            var editorElement = this._bodyElement.appendChild(document.createElement("div"));
            editorElement.classList.add("breakpoint-action-eval-editor");
            editorElement.classList.add(WI.SyntaxHighlightedStyleClassName);

            this._codeMirror = WI.CodeMirrorEditor.create(editorElement, {
                lineWrapping: true,
                mode: "text/javascript",
                matchBrackets: true,
                value: this._action.data || "",
            });

            this._codeMirror.on("viewportChange", this._codeMirrorViewportChanged.bind(this));
            this._codeMirror.on("change", this._handleJavaScriptCodeMirrorChange.bind(this));

            this._codeMirrorViewport = {from: null, to: null};

            var completionController = new WI.CodeMirrorCompletionController(this._delegate.breakpointActionViewCodeMirrorCompletionControllerMode(this, this._codeMirror), this._codeMirror);
            completionController.addExtendedCompletionProvider("javascript", WI.javaScriptRuntimeCompletionProvider);

            if (WI.BreakpointAction.supportsEmulateUserAction())
                this._bodyElement.appendChild(createOptionsElements());

            // CodeMirror needs a refresh after the popover displays to layout otherwise it doesn't appear.
            setTimeout(() => {
                this._codeMirror.refresh();
                if (!omitFocus)
                    this._codeMirror.focus();
            }, 0);

            break;

        case WI.BreakpointAction.Type.Sound:
            this._bodyElement.hidden = true;
            break;

        default:
            console.assert(false);
            this._bodyElement.hidden = true;
            break;
        }
    }

    _handleLogInputInput(event)
    {
        this._action.data = event.target.value;
    }

    _handleJavaScriptCodeMirrorChange(event)
    {
        // Throw away the expression if it's just whitespace.
        this._action.data = this._codeMirror.getValue().trim();
    }

    _codeMirrorViewportChanged(event, from, to)
    {
        if (this._codeMirrorViewport.from === from && this._codeMirrorViewport.to === to)
            return;

        this._codeMirrorViewport.from = from;
        this._codeMirrorViewport.to = to;
        this._delegate.breakpointActionViewResized(this);
    }

    _handleEmulateUserGestureCheckboxChange(event)
    {
        this._action.emulateUserGesture = this._emulateUserGestureCheckbox.checked;
    }
};
