/*
 * Copyright (C) 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.
 */

function createCodeMirrorTextMarkers({codeMirror, range, type, pattern, matchFunction, allowedTokens, callback})
{
    var createdMarkers = [];
    var start = range instanceof WI.TextRange ? range.startLine : 0;
    var end = range instanceof WI.TextRange ? range.endLine + 1 : codeMirror.lineCount();
    for (var lineNumber = start; lineNumber < end; ++lineNumber) {
        var lineContent = codeMirror.getLine(lineNumber);
        var match = pattern.exec(lineContent);
        while (match) {
            if (typeof matchFunction === "function" && !matchFunction(lineContent, match)) {
                match = pattern.exec(lineContent);
                continue;
            }

            var from = {line: lineNumber, ch: match.index};
            var to = {line: lineNumber, ch: match.index + match[0].length};

            var foundMarker = false;
            var markers = codeMirror.findMarksAt(to);
            for (var j = 0; j < markers.length; ++j) {
                if (WI.TextMarker.textMarkerForCodeMirrorTextMarker(markers[j]).type === WI.TextMarker.Type[type]) {
                    foundMarker = true;
                    break;
                }
            }

            if (foundMarker) {
                match = pattern.exec(lineContent);
                continue;
            }

            // We're not interested if the value is not inside a keyword.
            var tokenType = codeMirror.getTokenTypeAt(from);
            if (tokenType && !tokenType.includes("keyword") && (!allowedTokens || !allowedTokens.test(tokenType))) {
                match = pattern.exec(lineContent);
                continue;
            }

            let valueString = match[1];
            let value = WI[type] ? WI[type].fromString(valueString) : null;
            if (WI[type] && !value) {
                match = pattern.exec(lineContent);
                continue;
            }

            var marker = codeMirror.markText(from, to);
            marker = new WI.TextMarker(marker, WI.TextMarker.Type[type]);
            createdMarkers.push(marker);

            if (typeof callback === "function")
                callback(marker, value, valueString);

            match = pattern.exec(lineContent);
        }
    }

    return createdMarkers;
}

function createCodeMirrorColorTextMarkers(codeMirror, range, options = {})
{
    // Matches rgba(0, 0, 0, 0.5), rgb(0, 0, 0), hsl(), hsla(), #fff, #ffff, #ffffff, #ffffffff, white
    const pattern = /((?:rgb|hsl)a?\([^)]+\)|#[0-9a-fA-F]{8}|#[0-9a-fA-F]{6}|#[0-9a-fA-F]{3,4}|\b\w+\b(?![-.]))/g;
    function matchFunction(lineContent, match) {
        if (!lineContent || !lineContent.length)
            return false;

        // In order determine if the matched color is inside a gradient, first
        // look before the text to find the first unmatched open parenthesis.
        // This parenthesis, if it exists, will be immediately after the CSS
        // funciton whose name can be checked to see if it matches a gradient.
        let openParenthesis = 0;
        let index = match.index;
        let c = null;
        while (c = lineContent[index]) {
            if (c === "(")
                ++openParenthesis;
            if (c === ")")
                --openParenthesis;

            if (openParenthesis > 0)
                break;

            --index;
            if (index < 0)
                break;
        }

        if (/(repeating-)?(linear|radial)-gradient$/.test(lineContent.substring(0, index)))
            return false;

        // Act as a negative look-behind and disallow the color from being prefixing with certain characters.
        return !(match.index > 0 && /[-.\"\']/.test(lineContent[match.index - 1]));
    }

    return createCodeMirrorTextMarkers({codeMirror, range, type: "Color", pattern, matchFunction, ...options});
}

function createCodeMirrorGradientTextMarkers(codeMirror, range, options = {})
{
    var createdMarkers = [];

    var start = range instanceof WI.TextRange ? range.startLine : 0;
    var end = range instanceof WI.TextRange ? range.endLine + 1 : codeMirror.lineCount();

    var gradientRegex = /(repeating-)?(linear|radial)-gradient\s*\(\s*/g;

    for (var lineNumber = start; lineNumber < end; ++lineNumber) {
        var lineContent = codeMirror.getLine(lineNumber);
        var match = gradientRegex.exec(lineContent);
        while (match) {
            var startLine = lineNumber;
            var startChar = match.index;
            var endChar = match.index + match[0].length;

            var openParentheses = 0;
            var c = null;
            while (c = lineContent[endChar]) {
                if (c === "(")
                    openParentheses++;
                if (c === ")")
                    openParentheses--;

                if (openParentheses === -1) {
                    endChar++;
                    break;
                }

                endChar++;
                if (endChar >= lineContent.length) {
                    lineNumber++;
                    endChar = 0;
                    lineContent = codeMirror.getLine(lineNumber);
                    if (!lineContent)
                        break;
                }
            }

            if (openParentheses !== -1) {
                match = gradientRegex.exec(lineContent);
                continue;
            }

            var from = {line: startLine, ch: startChar};
            var to = {line: lineNumber, ch: endChar};

            var gradientString = codeMirror.getRange(from, to);
            var gradient = WI.Gradient.fromString(gradientString);
            if (!gradient) {
                match = gradientRegex.exec(lineContent);
                continue;
            }

            var marker = new WI.TextMarker(codeMirror.markText(from, to), WI.TextMarker.Type.Gradient);

            createdMarkers.push(marker);

            if (typeof callback === "function")
                options.callback(marker, gradient, gradientString);

            match = gradientRegex.exec(lineContent);
        }
    }

    return createdMarkers;
}

function createCodeMirrorCubicBezierTextMarkers(codeMirror, range, options = {})
{
    const pattern = /(cubic-bezier\([^)]+\)|\b\w+\b(?:-\b\w+\b){0,2})/g;
    return createCodeMirrorTextMarkers({codeMirror, range, type: "CubicBezier", pattern, ...options});
}

function createCodeMirrorSpringTextMarkers(codeMirror, range, options = {})
{
    const pattern = /(spring\([^)]+\))/g;
    return createCodeMirrorTextMarkers({codeMirror, range, type: "Spring", pattern, ...options});
}
