/*
 * Copyright (C) 2017 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.CanvasContentView = class CanvasContentView extends WI.ContentView
{
    constructor(representedObject)
    {
        console.assert(representedObject instanceof WI.Canvas);

        super(representedObject);

        this.element.classList.add("canvas");

        this._progressView = null;
        this._previewContainerElement = null;
        this._previewImageElement = null;
        this._errorElement = null;
        this._memoryCostElement = null;
        this._pendingContent = null;
        this._pixelSize = null;
        this._pixelSizeElement = null;
        this._canvasNode = null;

        this._refreshButtonNavigationItem = new WI.ButtonNavigationItem("refresh", WI.UIString("Refresh"), "Images/ReloadFull.svg", 13, 13);
        this._refreshButtonNavigationItem.visibilityPriority = WI.NavigationItem.VisibilityPriority.Low;
        this._refreshButtonNavigationItem.addEventListener(WI.ButtonNavigationItem.Event.Clicked, this.handleRefreshButtonClicked, this);

        this._showGridButtonNavigationItem = new WI.ActivateButtonNavigationItem("show-grid", WI.UIString("Show transparency grid"), WI.UIString("Hide transparency grid"), "Images/NavigationItemCheckers.svg", 13, 13);
        this._showGridButtonNavigationItem.addEventListener(WI.ButtonNavigationItem.Event.Clicked, this._showGridButtonClicked, this);
        this._showGridButtonNavigationItem.visibilityPriority = WI.NavigationItem.VisibilityPriority.Low;
        this._showGridButtonNavigationItem.activated = !!WI.settings.showImageGrid.value;
    }

    // Public

    get navigationItems()
    {
        // The toggle recording NavigationItem isn't added to the ContentBrowser's NavigationBar.
        // It's added to the "quick access" NavigationBar shown when hovering the canvas in the overview.
        return [this._refreshButtonNavigationItem, this._showGridButtonNavigationItem];
    }

    refreshPreview()
    {
        this._pendingContent = null;

        this.representedObject.requestContent().then((content) => {
            this._pendingContent = content;
            if (!this._pendingContent) {
                this._showError();
                return;
            }

            this.needsLayout();
        });
    }

    handleRefreshButtonClicked()
    {
        this.refreshPreview();
    }

    // DropZoneView delegate

    dropZoneShouldAppearForDragEvent(dropZone, event)
    {
        return event.dataTransfer.types.includes("Files");
    }

    dropZoneHandleDrop(dropZone, event)
    {
        let files = event.dataTransfer.files;
        if (files.length !== 1) {
            InspectorFrontendHost.beep();
            return;
        }

        WI.FileUtilities.readJSON(files, (result) => WI.canvasManager.processJSON(result));
    }

    // Protected

    initialLayout()
    {
        super.initialLayout();

        let isCard = !this._refreshButtonNavigationItem.parentNavigationBar;

        if (isCard) {
            let header = this.element.appendChild(document.createElement("header"));
            header.addEventListener("click", (event) => { event.stopPropagation(); });

            let titles = header.appendChild(document.createElement("div"));
            titles.className = "titles";

            let title = titles.appendChild(document.createElement("span"));
            title.className = "title";
            title.textContent = this.representedObject.displayName;

            let subtitle = titles.appendChild(document.createElement("span"));
            subtitle.className = "subtitle";
            subtitle.textContent = WI.Canvas.displayNameForContextType(this.representedObject.contextType);

            let navigationBar = new WI.NavigationBar;

            if (this.representedObject.contextType === WI.Canvas.ContextType.Canvas2D || this.representedObject.contextType === WI.Canvas.ContextType.BitmapRenderer || this.representedObject.contextType === WI.Canvas.ContextType.WebGL || this.representedObject.contextType === WI.Canvas.ContextType.WebGL2) {
                const toolTip = WI.UIString("Start recording canvas actions.\nShift-click to record a single frame.");
                const altToolTip = WI.UIString("Stop recording canvas actions");
                this._recordButtonNavigationItem = new WI.ToggleButtonNavigationItem("record-start-stop", toolTip, altToolTip, "Images/Record.svg", "Images/Stop.svg", 13, 13);
                this._recordButtonNavigationItem.visibilityPriority = WI.NavigationItem.VisibilityPriority.High;
                this._recordButtonNavigationItem.addEventListener(WI.ButtonNavigationItem.Event.Clicked, this._toggleRecording, this);
                navigationBar.addNavigationItem(this._recordButtonNavigationItem);
            }

            let canvasElementButtonNavigationItem = new WI.ButtonNavigationItem("canvas-element", WI.UIString("Canvas Element"), "Images/Markup.svg", 16, 16);
            canvasElementButtonNavigationItem.visibilityPriority = WI.NavigationItem.VisibilityPriority.Low;
            WI.addMouseDownContextMenuHandlers(canvasElementButtonNavigationItem.element, this._populateCanvasElementButtonContextMenu.bind(this));
            navigationBar.addNavigationItem(canvasElementButtonNavigationItem);

            navigationBar.addNavigationItem(this._refreshButtonNavigationItem);

            header.append(navigationBar.element);
        }

        this._previewContainerElement = this.element.appendChild(document.createElement("div"));
        this._previewContainerElement.className = "preview";

        if (isCard) {
            let footer = this.element.appendChild(document.createElement("footer"));
            footer.addEventListener("click", (event) => { event.stopPropagation(); });

            this._viewRelatedItemsContainer = footer.appendChild(document.createElement("div"));
            this._viewRelatedItemsContainer.classList.add("view-related-items");

            this._viewShaderButton = document.createElement("img");
            this._viewShaderButton.classList.add("view-shader");
            this._viewShaderButton.title = WI.UIString("View Shader");
            WI.addMouseDownContextMenuHandlers(this._viewShaderButton, this._populateViewShaderButtonContextMenu.bind(this));

            this._viewRecordingButton = document.createElement("img");
            this._viewRecordingButton.classList.add("view-recording");
            this._viewRecordingButton.title = WI.UIString("View Recording");
            WI.addMouseDownContextMenuHandlers(this._viewRecordingButton, this._populateViewRecordingButtonContextMenu.bind(this));

            this._updateViewRelatedItems();

            let flexibleSpaceElement = footer.appendChild(document.createElement("div"));
            flexibleSpaceElement.className = "flexible-space";

            let metrics = footer.appendChild(document.createElement("div"));

            this._pixelSizeElement = metrics.appendChild(document.createElement("span"));
            this._pixelSizeElement.className = "pixel-size";

            this._memoryCostElement = metrics.appendChild(document.createElement("span"));
            this._memoryCostElement.className = "memory-cost";
        }

        if (this._errorElement)
            this._showError();

        if (isCard)
            this._refreshPixelSize();

        if (!isCard) {
            let dropZoneView = new WI.DropZoneView(this);
            dropZoneView.text = WI.UIString("Import Recording");
            dropZoneView.targetElement = this.element;
            this.addSubview(dropZoneView);
        }
    }

    layout()
    {
        super.layout();

        if (this._pendingContent) {
            if (this._errorElement) {
                this._errorElement.remove();
                this._errorElement = null;
            }

            if (!this._previewImageElement) {
                this._previewImageElement = document.createElement("img");
                this._previewImageElement.addEventListener("error", this._showError.bind(this));
            }

            this._previewImageElement.src = this._pendingContent;
            this._pendingContent = null;

            if (!this._previewImageElement.parentNode)
                this._previewContainerElement.appendChild(this._previewImageElement);
        }

        this._updateRecordNavigationItem();
        this._updateProgressView();
        this._updateViewRelatedItems();
        this._updateMemoryCost();
        this._updateImageGrid();
    }

    attached()
    {
        super.attached();

        this.representedObject.addEventListener(WI.Canvas.Event.MemoryChanged, this._updateMemoryCost, this);
        this.representedObject.addEventListener(WI.Canvas.Event.RecordingStarted, this.needsLayout, this);
        this.representedObject.addEventListener(WI.Canvas.Event.RecordingProgress, this.needsLayout, this);
        this.representedObject.addEventListener(WI.Canvas.Event.RecordingStopped, this.needsLayout, this);
        this.representedObject.shaderProgramCollection.addEventListener(WI.Collection.Event.ItemAdded, this.needsLayout, this);
        this.representedObject.shaderProgramCollection.addEventListener(WI.Collection.Event.ItemRemoved, this.needsLayout, this);

        this.representedObject.requestNode().then((node) => {
            if (!node)
                return;

            console.assert(!this._canvasNode || this._canvasNode === node);
            if (this._canvasNode === node)
                return;

            this._canvasNode = node;
            this._canvasNode.addEventListener(WI.DOMNode.Event.AttributeModified, this._refreshPixelSize, this);
            this._canvasNode.addEventListener(WI.DOMNode.Event.AttributeRemoved, this._refreshPixelSize, this);
        });

        WI.settings.showImageGrid.addEventListener(WI.Setting.Event.Changed, this._updateImageGrid, this);

        this.refreshPreview();
    }

    detached()
    {
        this.representedObject.removeEventListener(null, null, this);
        this.representedObject.shaderProgramCollection.removeEventListener(null, null, this);

        if (this._canvasNode) {
            this._canvasNode.removeEventListener(null, null, this);
            this._canvasNode = null;
        }

        WI.settings.showImageGrid.removeEventListener(null, null, this);

        super.detached();
    }

    // Private

    _showError()
    {
        if (this._previewImageElement)
            this._previewImageElement.remove();

        if (!this._errorElement) {
            let isError = WI.Canvas.supportsRequestContentForContextType(this.representedObject.contextType);
            this._errorElement = WI.createMessageTextView(WI.UIString("No Preview Available"), isError);
        }

        if (this._previewContainerElement)
            this._previewContainerElement.appendChild(this._errorElement);
    }

    _toggleRecording(event)
    {
        if (this.representedObject.recordingActive)
            this.representedObject.stopRecording();
        else {
            let singleFrame = event.data.nativeEvent.shiftKey;
            this.representedObject.startRecording(singleFrame);
        }
    }

    _refreshPixelSize()
    {
        let updatePixelSize = (size) => {
            if (Object.shallowEqual(this._pixelSize, size))
                return;

            this._pixelSize = size;

            if (this._pixelSizeElement) {
                if (this._pixelSize)
                    this._pixelSizeElement.textContent = `${this._pixelSize.width} ${multiplicationSign} ${this._pixelSize.height}`;
                else
                    this._pixelSizeElement.textContent = emDash;
            }

            this.refreshPreview();
        };

        this.representedObject.requestSize().then((size) => {
            updatePixelSize(size);
        });
    }

    _populateCanvasElementButtonContextMenu(contextMenu)
    {
        contextMenu.appendItem(WI.UIString("Log Canvas Context"), () => {
            WI.RemoteObject.resolveCanvasContext(this.representedObject, WI.RuntimeManager.ConsoleObjectGroup, (remoteObject) => {
                if (!remoteObject)
                    return;

                const text = WI.UIString("Selected Canvas Context");
                const addSpecialUserLogClass = true;
                WI.consoleLogViewController.appendImmediateExecutionWithResult(text, remoteObject, addSpecialUserLogClass);
            });
        });

        contextMenu.appendSeparator();

        if (this._canvasNode)
            WI.appendContextMenuItemsForDOMNode(contextMenu, this._canvasNode);
    }

    _showGridButtonClicked()
    {
        WI.settings.showImageGrid.value = !this._showGridButtonNavigationItem.activated;
    }

    _updateImageGrid()
    {
        let activated = WI.settings.showImageGrid.value;
        this._showGridButtonNavigationItem.activated = activated;

        if (this._previewImageElement)
            this._previewImageElement.classList.toggle("show-grid", activated);
    }

    _updateMemoryCost()
    {
        if (!this._memoryCostElement)
            return;

        let memoryCost = this.representedObject.memoryCost;
        if (isNaN(memoryCost))
            this._memoryCostElement.textContent = emDash;
        else {
            const higherResolution = false;
            let bytesString = Number.bytesToString(memoryCost, higherResolution);
            this._memoryCostElement.textContent = `(${bytesString})`;
        }
    }

    _updateRecordNavigationItem()
    {
        if (!this._recordButtonNavigationItem)
            return;

        let recordingActive = this.representedObject.recordingActive;
        this._recordButtonNavigationItem.toggled = recordingActive;
        this._refreshButtonNavigationItem.enabled = !recordingActive;
        this.element.classList.toggle("recording-active", recordingActive);
    }

    _updateProgressView()
    {
        if (!this._previewContainerElement)
            return;

        if (!this.representedObject.recordingActive) {
            if (this._progressView && this._progressView.parentView) {
                this.removeSubview(this._progressView);
                this._progressView = null;
            }
            return;
        }

        if (!this._progressView) {
            this._progressView = new WI.ProgressView;
            this.element.insertBefore(this._progressView.element, this._previewContainerElement);
            this.addSubview(this._progressView);
        }

        let title = null;
        if (this.representedObject.recordingFrameCount) {
            let formatString = this.representedObject.recordingFrameCount === 1 ? WI.UIString("%d Frame") : WI.UIString("%d Frames");
            title = formatString.format(this.representedObject.recordingFrameCount);
        } else
            title = WI.UIString("Waiting for frames\u2026");

        this._progressView.title = title;
        this._progressView.subtitle = this.representedObject.recordingBufferUsed ? Number.bytesToString(this.representedObject.recordingBufferUsed) : "";
    }

    _updateViewRelatedItems()
    {
        if (!this._viewRelatedItemsContainer)
            return;

        this._viewRelatedItemsContainer.removeChildren();

        if (this.representedObject.shaderProgramCollection.size)
            this._viewRelatedItemsContainer.appendChild(this._viewShaderButton);

        if (this.representedObject.recordingCollection.size)
            this._viewRelatedItemsContainer.appendChild(this._viewRecordingButton);
    }

    _populateViewShaderButtonContextMenu(contextMenu, event)
    {
        let shaderPrograms = this.representedObject.shaderProgramCollection;
        console.assert(shaderPrograms.size);
        if (!shaderPrograms.size)
            return;

        if (event.button === 0 && shaderPrograms.size === 1) {
            WI.showRepresentedObject(Array.from(shaderPrograms)[0]);
            return;
        }

        for (let shaderProgram of shaderPrograms) {
            contextMenu.appendItem(shaderProgram.displayName, () => {
                WI.showRepresentedObject(shaderProgram);
            });
        }
    }

    _populateViewRecordingButtonContextMenu(contextMenu, event)
    {
        let recordings = this.representedObject.recordingCollection;
        console.assert(recordings.size);
        if (!recordings.size)
            return;

        if (event.button === 0 && recordings.size === 1) {
            WI.showRepresentedObject(Array.from(recordings)[0]);
            return;
        }

        for (let recording of recordings) {
            contextMenu.appendItem(recording.displayName, () => {
                WI.showRepresentedObject(recording);
            });
        }
    }
};
