/*
 * 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.ShaderProgramContentView = class ShaderProgramContentView extends WI.ContentView
{
    constructor(shaderProgram)
    {
        console.assert(shaderProgram instanceof WI.ShaderProgram);

        super(shaderProgram);

        let contentDidChangeDebouncer = new Debouncer((event) => {
            this._contentDidChange(event);
        });

        this.element.classList.add("shader-program");

        let createEditor = (shaderType) => {
            let textEditor = new WI.TextEditor;
            textEditor.readOnly = false;
            textEditor.addEventListener(WI.TextEditor.Event.Focused, this._editorFocused, this);
            textEditor.addEventListener(WI.TextEditor.Event.NumberOfSearchResultsDidChange, this._numberOfSearchResultsDidChange, this);
            textEditor.addEventListener(WI.TextEditor.Event.ContentDidChange, (event) => {
                contentDidChangeDebouncer.delayForTime(250, event);
            }, this);
            textEditor.element.classList.add("shader");

            let shaderTypeContainer = textEditor.element.insertAdjacentElement("afterbegin", document.createElement("div"));
            shaderTypeContainer.classList.add("type-title");

            switch (shaderType) {
            case WI.ShaderProgram.ShaderType.Vertex:
                shaderTypeContainer.textContent = WI.UIString("Vertex Shader");
                textEditor.mimeType = "x-shader/x-vertex";
                textEditor.element.classList.add("vertex");
                break;

            case WI.ShaderProgram.ShaderType.Fragment:
                shaderTypeContainer.textContent = WI.UIString("Fragment Shader");
                textEditor.mimeType = "x-shader/x-fragment";
                textEditor.element.classList.add("fragment");
                break;
            }

            this.addSubview(textEditor);
            return textEditor;
        };

        this._vertexEditor = createEditor(WI.ShaderProgram.ShaderType.Vertex);
        this._fragmentEditor = createEditor(WI.ShaderProgram.ShaderType.Fragment);
        this._lastActiveEditor = this._vertexEditor;
    }

    // Protected

    shown()
    {
        super.shown();

        this._vertexEditor.shown();
        this._fragmentEditor.shown();

        this.representedObject.requestVertexShaderSource((content) => {
            this._vertexEditor.string = content || "";
        });

        this.representedObject.requestFragmentShaderSource((content) => {
            this._fragmentEditor.string = content || "";
        });
    }

    hidden()
    {
        this._vertexEditor.hidden();
        this._fragmentEditor.hidden();

        super.hidden();
    }

    get supportsSave()
    {
        return true;
    }

    get saveData()
    {
        let filename = WI.UIString("Shader");
        if (this._lastActiveEditor === this._vertexEditor)
            filename = WI.UIString("Vertex");
        else if (this._lastActiveEditor === this._fragmentEditor)
            filename = WI.UIString("Fragment");

        return {
            url: WI.FileUtilities.inspectorURLForFilename(filename + ".glsl"),
            content: this._lastActiveEditor.string,
            forceSaveAs: true,
        };
    }

    get supportsSearch()
    {
        return true;
    }

    get numberOfSearchResults()
    {
        return this._lastActiveEditor.numberOfSearchResults;
    }

    get hasPerformedSearch()
    {
        return this._lastActiveEditor.currentSearchQuery !== null;
    }

    set automaticallyRevealFirstSearchResult(reveal)
    {
        this._lastActiveEditor.automaticallyRevealFirstSearchResult = reveal;
    }

    performSearch(query)
    {
        this._lastActiveEditor.performSearch(query);
    }

    searchCleared()
    {
        this._lastActiveEditor.searchCleared();
    }

    searchQueryWithSelection()
    {
        return this._lastActiveEditor.searchQueryWithSelection();
    }

    revealPreviousSearchResult(changeFocus)
    {
        this._lastActiveEditor.revealPreviousSearchResult(changeFocus);
    }

    revealNextSearchResult(changeFocus)
    {
        this._lastActiveEditor.revealNextSearchResult(changeFocus);
    }

    revealPosition(position, textRangeToSelect, forceUnformatted)
    {
        this._lastActiveEditor.revealPosition(position, textRangeToSelect, forceUnformatted);
    }

    // Private

    _editorFocused(event)
    {
        if (this._lastActiveEditor === event.target)
            return;

        let currentSearchQuery = null;

        if (this._lastActiveEditor) {
            currentSearchQuery = this._lastActiveEditor.currentSearchQuery;

            this._lastActiveEditor.searchCleared();
        }

        this._lastActiveEditor = event.target;

        if (currentSearchQuery)
            this._lastActiveEditor.performSearch(currentSearchQuery);
    }

    _numberOfSearchResultsDidChange(event)
    {
        this.dispatchEventToListeners(WI.ContentView.Event.NumberOfSearchResultsDidChange);
    }

    _contentDidChange(event)
    {
        if (event.target === this._vertexEditor)
            this.representedObject.updateVertexShader(this._vertexEditor.string);
        else if (event.target === this._fragmentEditor)
            this.representedObject.updateFragmentShader(this._fragmentEditor.string);
    }
};
