(function (factory) {
    if (typeof module === "object" && typeof module.exports === "object") {
        var v = factory(require, exports);
        if (v !== undefined) module.exports = v;
    }
    else if (typeof define === "function" && define.amd) {
        define(["require", "exports", "../parser/cssNodes", "vscode-languageserver-types", "../parser/cssSymbolScope", "../services/languageFacts", "vscode-nls"], factory);
    }
})(function (require, exports) {
    /*---------------------------------------------------------------------------------------------
     *  Copyright (c) Microsoft Corporation. All rights reserved.
     *  Licensed under the MIT License. See License.txt in the project root for license information.
     *--------------------------------------------------------------------------------------------*/
    'use strict';
    Object.defineProperty(exports, "__esModule", { value: true });
    var nodes = require("../parser/cssNodes");
    var vscode_languageserver_types_1 = require("vscode-languageserver-types");
    var cssSymbolScope_1 = require("../parser/cssSymbolScope");
    var languageFacts_1 = require("../services/languageFacts");
    var nls = require("vscode-nls");
    var localize = nls.loadMessageBundle();
    var CSSNavigation = (function () {
        function CSSNavigation() {
        }
        CSSNavigation.prototype.findDefinition = function (document, position, stylesheet) {
            var symbols = new cssSymbolScope_1.Symbols(stylesheet);
            var offset = document.offsetAt(position);
            var node = nodes.getNodeAtOffset(stylesheet, offset);
            if (!node) {
                //workaround for https://github.com/Microsoft/vscode-languageserver-node/issues/45
                return {
                    uri: document.uri,
                    range: vscode_languageserver_types_1.Range.create(position, position)
                };
            }
            var symbol = symbols.findSymbolFromNode(node);
            if (!symbol) {
                //workaround for https://github.com/Microsoft/vscode-languageserver-node/issues/45
                return {
                    uri: document.uri,
                    range: vscode_languageserver_types_1.Range.create(position, position)
                };
            }
            return {
                uri: document.uri,
                range: getRange(symbol.node, document)
            };
        };
        CSSNavigation.prototype.findReferences = function (document, position, stylesheet) {
            var highlights = this.findDocumentHighlights(document, position, stylesheet);
            return highlights.map(function (h) {
                return {
                    uri: document.uri,
                    range: h.range
                };
            });
        };
        CSSNavigation.prototype.findDocumentHighlights = function (document, position, stylesheet) {
            var result = [];
            var offset = document.offsetAt(position);
            var node = nodes.getNodeAtOffset(stylesheet, offset);
            if (!node || node.type === nodes.NodeType.Stylesheet || node.type === nodes.NodeType.Declarations) {
                return result;
            }
            var symbols = new cssSymbolScope_1.Symbols(stylesheet);
            var symbol = symbols.findSymbolFromNode(node);
            var name = node.getText();
            stylesheet.accept(function (candidate) {
                if (symbol) {
                    if (symbols.matchesSymbol(candidate, symbol)) {
                        result.push({
                            kind: getHighlightKind(candidate),
                            range: getRange(candidate, document)
                        });
                        return false;
                    }
                }
                else if (node.type === candidate.type && node.length === candidate.length && name === candidate.getText()) {
                    // Same node type and data
                    result.push({
                        kind: getHighlightKind(candidate),
                        range: getRange(candidate, document)
                    });
                }
                return true;
            });
            return result;
        };
        CSSNavigation.prototype.findDocumentSymbols = function (document, stylesheet) {
            var result = [];
            stylesheet.accept(function (node) {
                var entry = {
                    name: null,
                    kind: vscode_languageserver_types_1.SymbolKind.Class,
                    location: null
                };
                var locationNode = node;
                if (node instanceof nodes.Selector) {
                    entry.name = node.getText();
                    locationNode = node.findParent(nodes.NodeType.Ruleset);
                }
                else if (node instanceof nodes.VariableDeclaration) {
                    entry.name = node.getName();
                    entry.kind = vscode_languageserver_types_1.SymbolKind.Variable;
                }
                else if (node instanceof nodes.MixinDeclaration) {
                    entry.name = node.getName();
                    entry.kind = vscode_languageserver_types_1.SymbolKind.Method;
                }
                else if (node instanceof nodes.FunctionDeclaration) {
                    entry.name = node.getName();
                    entry.kind = vscode_languageserver_types_1.SymbolKind.Function;
                }
                else if (node instanceof nodes.Keyframe) {
                    entry.name = localize('literal.keyframes', "@keyframes {0}", node.getName());
                }
                else if (node instanceof nodes.FontFace) {
                    entry.name = localize('literal.fontface', "@font-face");
                }
                if (entry.name) {
                    entry.location = vscode_languageserver_types_1.Location.create(document.uri, getRange(locationNode, document));
                    result.push(entry);
                }
                return true;
            });
            return result;
        };
        CSSNavigation.prototype.findColorSymbols = function (document, stylesheet) {
            var result = [];
            stylesheet.accept(function (node) {
                if (languageFacts_1.isColorValue(node)) {
                    result.push(getRange(node, document));
                }
                return true;
            });
            return result;
        };
        CSSNavigation.prototype.doRename = function (document, position, newName, stylesheet) {
            var highlights = this.findDocumentHighlights(document, position, stylesheet);
            var edits = highlights.map(function (h) { return vscode_languageserver_types_1.TextEdit.replace(h.range, newName); });
            return {
                changes: (_a = {}, _a[document.uri] = edits, _a)
            };
            var _a;
        };
        return CSSNavigation;
    }());
    exports.CSSNavigation = CSSNavigation;
    function getRange(node, document) {
        return vscode_languageserver_types_1.Range.create(document.positionAt(node.offset), document.positionAt(node.end));
    }
    function getHighlightKind(node) {
        if (node.type === nodes.NodeType.Selector) {
            return vscode_languageserver_types_1.DocumentHighlightKind.Write;
        }
        if (node instanceof nodes.Identifier) {
            if (node.parent && node.parent instanceof nodes.Property) {
                if (node.isCustomProperty) {
                    return vscode_languageserver_types_1.DocumentHighlightKind.Write;
                }
            }
        }
        if (node.parent) {
            switch (node.parent.type) {
                case nodes.NodeType.FunctionDeclaration:
                case nodes.NodeType.MixinDeclaration:
                case nodes.NodeType.Keyframe:
                case nodes.NodeType.VariableDeclaration:
                case nodes.NodeType.FunctionParameter:
                    return vscode_languageserver_types_1.DocumentHighlightKind.Write;
            }
        }
        return vscode_languageserver_types_1.DocumentHighlightKind.Read;
    }
});
//# sourceMappingURL=cssNavigation.js.map