/*
 * Copyright (C) 2013-2019 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.ImageResourceContentView = class ImageResourceContentView extends WI.ResourceContentView
{
    constructor(resource, {disableInteractions} = {})
    {
        console.assert(resource instanceof WI.Resource);

        super(resource, "image");

        this._imageElement = null;
        this._draggingInternalImageElement = false;
        this._disableInteractions = disableInteractions || false;

        const toolTip = WI.repeatedUIString.showTransparencyGridTooltip();
        const activatedToolTip = WI.UIString("Hide transparency grid");
        this._showGridButtonNavigationItem = new WI.ActivateButtonNavigationItem("show-grid", toolTip, activatedToolTip, "Images/NavigationItemCheckers.svg", 13, 13);
        this._showGridButtonNavigationItem.addEventListener(WI.ButtonNavigationItem.Event.Clicked, this._showGridButtonClicked, this);
        this._showGridButtonNavigationItem.activated = !!WI.settings.showImageGrid.value;

        if (!this._disableInteractions) {
            this._resetGestureButtonNavitationItem = new WI.ButtonNavigationItem("image-gesture-reset", "");
            this._resetGestureButtonNavitationItem.tooltip = WI.UIString("Click to reset", "Click to reset @ Image Resource Content View Gesture Controls", "Title of text button that resets the gesture controls in the image resource content view.");
            this._resetGestureButtonNavitationItem.hidden = true;
            this._resetGestureButtonNavitationItem.addEventListener(WI.ButtonNavigationItem.Event.Clicked, this._handleResetGestureButtonNavitationItemClicked, this);

            this._zoomOutGestureButtonNavitationItem = new WI.ButtonNavigationItem("image-gesture-zoom-out", WI.UIString("Zoom Out", "Zoom Out @ Image Resource Content View Gesture Controls", "Title of image button that decreases the zoom of the image resource content view."), "Images/ZoomOut.svg", 16, 16);
            this._zoomOutGestureButtonNavitationItem.visibilityPriority = WI.NavigationItem.VisibilityPriority.Low;
            this._zoomOutGestureButtonNavitationItem.hidden = true;
            this._zoomOutGestureButtonNavitationItem.addEventListener(WI.ButtonNavigationItem.Event.Clicked, this._handleZoomOutGestureButtonNavitationItemClicked, this);

            this._zoomInGestureButtonNavitationItem = new WI.ButtonNavigationItem("image-gesture-zoom-in", WI.UIString("Zoom In", "Zoom In @ Image Resource Content View Gesture Controls", "Title of image button that increases the zoom of the image resource content view."), "Images/ZoomIn.svg", 16, 16);
            this._zoomInGestureButtonNavitationItem.visibilityPriority = WI.NavigationItem.VisibilityPriority.Low;
            this._zoomInGestureButtonNavitationItem.hidden = true;
            this._zoomInGestureButtonNavitationItem.addEventListener(WI.ButtonNavigationItem.Event.Clicked, this._handleZoomInGestureButtonNavitationItemClicked, this);

            this._gestureNavigationItemsDivider = new WI.DividerNavigationItem;
            this._gestureNavigationItemsDivider.hidden = true;

        }
    }

    // Public

    get navigationItems()
    {
        let items = [];
        if (!this._disableInteractions) {
            items.push(this._resetGestureButtonNavitationItem);
            items.push(this._zoomOutGestureButtonNavitationItem);
            items.push(this._zoomInGestureButtonNavitationItem);
            items.push(new WI.DividerNavigationItem);
        }
        items.pushAll(super.navigationItems);
        items.push(this._showGridButtonNavigationItem);
        return items;
    }

    contentAvailable(content, base64Encoded)
    {
        this.removeLoadingIndicator();

        if (!content) {
            this.showGenericNoContentMessage();
            return;
        }

        let objectURL = this.resource.createObjectURL();
        if (!objectURL) {
            this.showGenericErrorMessage();
            return;
        }

        this._imageContainer = this.element.appendChild(document.createElement("div"));
        this._imageContainer.className = "img-container";

        this._imageElement = this._imageContainer.appendChild(document.createElement("img"));
        this._imageElement.addEventListener("load", function() { URL.revokeObjectURL(objectURL); });
        this._imageElement.src = objectURL;
        this._imageElement.setAttribute("filename", this.resource.urlComponents.lastPathComponent || "");
        this._imageElement.draggable = true;
        this._updateImageGrid();

        // Drag-and-Drop should not be considered as the same "kind" of interaction as those below.
        this._imageElement.addEventListener("dragstart", (event) => {
            console.assert(!this._draggingInternalImageElement);
            this._draggingInternalImageElement = true;
        });
        this._imageElement.addEventListener("dragend", (event) => {
            console.assert(this._draggingInternalImageElement);
            this._draggingInternalImageElement = false;
        });

        if (!this._disableInteractions) {
            this._gestureController = new WI.GestureController(this._imageElement, this, {container: this._imageContainer, supportsScale: true, supportsTranslate: true});

            this._resetGestureButtonNavitationItem.hidden = false;
            this._zoomOutGestureButtonNavitationItem.hidden = false;
            this._zoomInGestureButtonNavitationItem.hidden = false;
            this._gestureNavigationItemsDivider.hidden = false;
            this._updateResetGestureButtonNavigationItemLabel();

            if (WI.NetworkManager.supportsOverridingResponses()) {
                let dropZoneView = new WI.DropZoneView(this);
                dropZoneView.targetElement = this._imageContainer;
                this.addSubview(dropZoneView);

                if (this.resource.localResourceOverride)
                    this.resource.addEventListener(WI.SourceCode.Event.ContentDidChange, this._handleLocalResourceContentDidChange, this);
            }
        }
    }

    // Protected

    attached()
    {
        super.attached();

        this._updateImageGrid();

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

    detached()
    {
        WI.settings.showImageGrid.removeEventListener(WI.Setting.Event.Changed, this._updateImageGrid, this);

        super.detached();
    }

    // GestureController delegate

    gestureControllerDidScale(gestureController)
    {
        this._imageElement.style.setProperty("scale", this._gestureController.scale);

        this._updateResetGestureButtonNavigationItemLabel();
    }

    gestureControllerDidTranslate(gestureController, x, y)
    {
        this._imageElement.style.setProperty("translate", `${this._gestureController.translate.x}px ${this._gestureController.translate.y}px`);
    }

    // DropZoneView delegate

    dropZoneShouldAppearForDragEvent(dropZone, event)
    {
        // Do not appear if the drag is the current image inside this view.
        if (this._draggingInternalImageElement)
            return false;

        let existingOverrides = WI.networkManager.localResourceOverridesForURL(this.resource.url);
        if (existingOverrides.length > 1)
            return false;

        // Request overrides cannot be created/updated from a file as files don't have network info.
        let localResourceOverride = this.resource.localResourceOverride || existingOverrides[0];
        if (localResourceOverride?.type === WI.LocalResourceOverride.InterceptType.Request)
            return false;

        // Appear if the drop contains a file.
        return event.dataTransfer.types.includes("Files");
    }

    dropZoneHandleDragEnter(dropZone, event)
    {
        if (this.resource.localResourceOverride)
            dropZone.text = WI.UIString("Update Image");
        else if (WI.networkManager.localResourceOverridesForURL(this.resource.url).length)
            dropZone.text = WI.UIString("Update Local Override");
        else
            dropZone.text = WI.UIString("Create Local Override");
    }

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

        WI.FileUtilities.readData(files, async ({dataURL, mimeType, base64Encoded, content}) => {
            let localResourceOverride = this.resource.localResourceOverride || WI.networkManager.localResourceOverridesForURL(this.resource.url)[0];
            if (!localResourceOverride) {
                localResourceOverride = await this.resource.createLocalResourceOverride(WI.LocalResourceOverride.InterceptType.Response);
                WI.networkManager.addLocalResourceOverride(localResourceOverride);
            }
            console.assert(localResourceOverride);

            let revision = localResourceOverride.localResource.editableRevision;
            revision.updateRevisionContent(content, {base64Encoded, mimeType});

            if (!this.resource.localResourceOverride)
                WI.showLocalResourceOverride(localResourceOverride);
        });
    }

    // Private

    _updateImageGrid()
    {
        if (!this._imageElement)
            return;

        let activated = WI.settings.showImageGrid.value;
        this._showGridButtonNavigationItem.activated = activated;
        this._imageElement.classList.toggle("show-grid", activated);
    }

    _updateResetGestureButtonNavigationItemLabel()
    {
        const precision = 0;
        this._resetGestureButtonNavitationItem.label = Number.percentageString(this._gestureController.scale, precision);
    }

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

        this._updateImageGrid();
    }

    _handleResetGestureButtonNavitationItemClicked(event)
    {
        this._gestureController.reset();
    }

    _handleZoomOutGestureButtonNavitationItemClicked(event)
    {
        this._gestureController.scale /= 2;
    }

    _handleZoomInGestureButtonNavitationItemClicked(event)
    {
        this._gestureController.scale *= 2;
    }

    _handleLocalResourceContentDidChange(event)
    {
        this._imageElement.src = this.resource.createObjectURL();
    }
};
