/*
 * 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.FontResourceContentView = class FontResourceContentView extends WI.ResourceContentView
{
    constructor(resource)
    {
        super(resource, "font");

        this._styleElement = null;
        this._previewElement = null;
        this._previewContainer = null;
    }

    // Public

    sizeToFit()
    {
        if (!this._previewElement)
            return;

        // Start at the maximum size and try progressively smaller font sizes until minimum is reached or the preview element is not as wide as the main element.
        for (var fontSize = WI.FontResourceContentView.MaximumFontSize; fontSize >= WI.FontResourceContentView.MinimumFontSize; fontSize -= 5) {
            this._previewElement.style.fontSize = fontSize + "px";
            if (this._previewElement.offsetWidth <= this.element.offsetWidth)
                break;
        }
    }

    contentAvailable(content, base64Encoded)
    {
        this._fontObjectURL = this.resource.createObjectURL();

        if (!this._fontObjectURL) {
            this.showGenericErrorMessage();
            return;
        }

        this.removeLoadingIndicator();

        this._previewContainer = this.element.appendChild(document.createElement("div"));
        this._previewContainer.className = "preview-container";

        this._updatePreviewElement();

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

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

    shown()
    {
        super.shown();

        // Add the style element since it is removed when hidden.
        if (this._styleElement)
            document.head.appendChild(this._styleElement);
    }

    hidden()
    {
        // Remove the style element so it will not stick around when this content view is destroyed.
        if (this._styleElement)
            this._styleElement.remove();

        super.hidden();
    }

    closed()
    {
        // This is a workaround for the fact that the browser does not send any events
        // when a @font-face resource is loaded. So, we assume it could be needed until
        // the content view is destroyed, as re-attaching the style element would cause
        // the object URL to be resolved again.
        if (this._fontObjectURL)
            URL.revokeObjectURL(this._fontObjectURL);

        super.closed();
    }

    // Protected

    layout()
    {
        this.sizeToFit();
    }

    // DropZoneView delegate

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

    dropZoneHandleDragEnter(dropZone, event)
    {
        if (this.showingLocalResourceOverride)
            dropZone.text = WI.UIString("Update Font");
        else if (WI.networkManager.localResourceOverrideForURL(this.resource.url))
            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 = WI.networkManager.localResourceOverrideForURL(this.resource.url);
            if (!localResourceOverride && !this.showingLocalResourceOverride) {
                localResourceOverride = await this.resource.createLocalResourceOverride();
                WI.networkManager.addLocalResourceOverride(localResourceOverride);
            }

            console.assert(localResourceOverride);

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

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

    // Private

    _updatePreviewElement()
    {
        if (this._styleElement)
            this._styleElement.remove();
        if (this._previewElement)
            this._previewElement.remove();

        const uniqueFontName = "WebInspectorFontPreview" + (++WI.FontResourceContentView._uniqueFontIdentifier);

        let format = "";

        // We need to specify a format when loading SVG fonts to make them work.
        if (this.resource.mimeTypeComponents.type === "image/svg+xml")
            format = " format(\"svg\")";

        this._styleElement = document.createElement("style");
        this._styleElement.textContent = `@font-face { font-family: "${uniqueFontName}"; src: url(${this._fontObjectURL}) ${format}; }`;

        // The style element will be added when shown later if we are not visible now.
        if (this.visible)
            document.head.appendChild(this._styleElement);

        this._previewElement = document.createElement("div");
        this._previewElement.className = "preview";
        this._previewElement.style.fontFamily = uniqueFontName;

        function createMetricElement(className) {
            let metricElement = document.createElement("div");
            metricElement.className = "metric " + className;
            return metricElement;
        }

        for (let line of WI.FontResourceContentView.PreviewLines) {
            let lineElement = document.createElement("div");
            lineElement.className = "line";

            lineElement.appendChild(createMetricElement("top"));
            lineElement.appendChild(createMetricElement("xheight"));
            lineElement.appendChild(createMetricElement("middle"));
            lineElement.appendChild(createMetricElement("baseline"));
            lineElement.appendChild(createMetricElement("bottom"));

            let contentElement = document.createElement("div");
            contentElement.className = "content";
            contentElement.textContent = line;
            lineElement.appendChild(contentElement);

            this._previewElement.appendChild(lineElement);
        }

        this._previewContainer.appendChild(this._previewElement);

        this.sizeToFit();
    }

    _handleLocalResourceContentDidChange(event)
    {
        this._fontObjectURL = this.resource.createObjectURL();
        this._updatePreviewElement();
    }
};

WI.FontResourceContentView._uniqueFontIdentifier = 0;

WI.FontResourceContentView.PreviewLines = ["ABCDEFGHIJKLM", "NOPQRSTUVWXYZ", "abcdefghijklm", "nopqrstuvwxyz", "1234567890"];

WI.FontResourceContentView.MaximumFontSize = 72;
WI.FontResourceContentView.MinimumFontSize = 12;
