var __extends = (this && this.__extends) || function (d, b) {
    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
    function __() { this.constructor = d; }
    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
(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", "natural"], factory);
    }
})(function (require, exports) {
    "use strict";
    var natural = require("natural");
    (function (TokenCheckStatus) {
        TokenCheckStatus[TokenCheckStatus["Unknown"] = 0] = "Unknown";
        TokenCheckStatus[TokenCheckStatus["Correct"] = 1] = "Correct";
        TokenCheckStatus[TokenCheckStatus["Incorrect"] = 2] = "Incorrect";
    })(exports.TokenCheckStatus || (exports.TokenCheckStatus = {}));
    var TokenCheckStatus = exports.TokenCheckStatus;
    var SpellingManager = (function () {
        function SpellingManager() {
        }
        SpellingManager.prototype.add = function (token) { };
        SpellingManager.prototype.isCorrect = function (token) {
            return this.check(token) === TokenCheckStatus.Correct;
        };
        SpellingManager.prototype.check = function (token) {
            return TokenCheckStatus.Unknown;
        };
        SpellingManager.prototype.suggest = function (token) {
            return [];
        };
        return SpellingManager;
    }());
    exports.SpellingManager = SpellingManager;
    var TokenSpellingManager = (function (_super) {
        __extends(TokenSpellingManager, _super);
        function TokenSpellingManager() {
            _super.apply(this, arguments);
            this.maximumDistance = 0.9;
            this.sensitive = {};
            this.insensitive = {};
        }
        TokenSpellingManager.prototype.add = function (token) {
            var tokens;
            if (typeof token === "string") {
                tokens = [token];
            }
            else {
                tokens = token;
            }
            for (var _i = 0, tokens_1 = tokens; _i < tokens_1.length; _i++) {
                var t = tokens_1[_i];
                if (t && t.trim() !== "") {
                    if (/[A-Z]/.test(t)) {
                        this.addCaseSensitive(t);
                    }
                    else if (/^!/.test(t)) {
                        this.addCaseSensitive(t.substring(1));
                    }
                    else {
                        this.addCaseInsensitive(t);
                    }
                }
            }
        };
        TokenSpellingManager.prototype.addCaseSensitive = function (token) {
            if (token && token.trim() !== "") {
                this.sensitive[token] = true;
            }
        };
        TokenSpellingManager.prototype.addCaseInsensitive = function (token) {
            if (token && token.trim() !== "") {
                this.insensitive[token.toLowerCase()] = true;
            }
        };
        TokenSpellingManager.prototype.check = function (token) {
            if (token in this.sensitive)
                return TokenCheckStatus.Correct;
            if (token.toLowerCase() in this.insensitive)
                return TokenCheckStatus.Correct;
            return TokenCheckStatus.Unknown;
        };
        TokenSpellingManager.prototype.list = function () {
            var list = new Array();
            for (var token in this.sensitive) {
                if (token === token.toLowerCase()) {
                    list.push("!" + token);
                }
                else {
                    list.push(token);
                }
            }
            for (var token in this.insensitive) {
                list.push(token);
            }
            list.sort();
            return list;
        };
        TokenSpellingManager.prototype.remove = function (token) {
            if (token && token.trim() !== "") {
                this.removeCaseSensitive(token);
                this.removeCaseInsensitive(token.toLowerCase());
            }
        };
        TokenSpellingManager.prototype.removeCaseSensitive = function (token) {
            if (token && token.trim() !== "") {
                delete this.sensitive[token];
            }
        };
        TokenSpellingManager.prototype.removeCaseInsensitive = function (token) {
            if (token && token.trim() !== "") {
                delete this.insensitive[token];
            }
        };
        TokenSpellingManager.prototype.suggest = function (input) {
            if (!input || input.trim().length === 0)
                return [];
            var weights = [];
            for (var token in this.sensitive) {
                var distance = natural.JaroWinklerDistance(input, token);
                if (distance >= this.maximumDistance)
                    weights.push({ token: token, distance: distance });
            }
            for (var token in this.insensitive) {
                var test = token;
                if (/[A-Z].*[A-Z]/.test(input)) {
                    test = test.toUpperCase();
                }
                else if (/^[A-Z]/.test(input)) {
                    test = test.charAt(0).toUpperCase() + test.slice(1);
                }
                var distance = natural.JaroWinklerDistance(input, test);
                if (distance >= this.maximumDistance)
                    weights.push({ token: test, distance: distance });
            }
            var keys = Object.keys(weights).sort(function (key1, key2) {
                var value1 = weights[key1];
                var value2 = weights[key2];
                if (value1.distance !== value2.distance) {
                    return value1.distance - value2.distance;
                }
                return value1.token.localeCompare(value2.token);
            });
            var results = [];
            for (var _i = 0, keys_1 = keys; _i < keys_1.length; _i++) {
                var key = keys_1[_i];
                results.push(weights[key].token);
            }
            return results;
        };
        return TokenSpellingManager;
    }(SpellingManager));
    exports.TokenSpellingManager = TokenSpellingManager;
    var BufferSpellingChecker = (function () {
        function BufferSpellingChecker(spellingManager, tokenizer) {
            if (tokenizer === void 0) { tokenizer = null; }
            if (!tokenizer) {
                tokenizer = new natural.RegexpTokenizer({ pattern: /(\w+(?:\'\w+)?)/ });
            }
            this.spellingManager = spellingManager;
            this.tokenizer = tokenizer;
        }
        BufferSpellingChecker.prototype.check = function (buffer) {
            if (!buffer || buffer.trim() === "")
                return new Array();
            var startSearch = 0;
            var tokens = this.tokenizer.tokenize(buffer);
            var results = new Array();
            for (var _i = 0, tokens_2 = tokens; _i < tokens_2.length; _i++) {
                var token = tokens_2[_i];
                if (!/\w/.test(token))
                    continue;
                var tokenIndex = buffer.indexOf(token, startSearch);
                if (tokenIndex < 0) {
                    throw new Error("Cannot find token '" + token + "' starting at position " + startSearch + ".");
                }
                startSearch = tokenIndex + token.length;
                var checkStatus = this.spellingManager.check(token);
                var tokenStatus = {
                    token: token,
                    start: tokenIndex,
                    end: tokenIndex + token.length,
                    status: checkStatus
                };
                results.push(tokenStatus);
            }
            return results;
        };
        return BufferSpellingChecker;
    }());
    exports.BufferSpellingChecker = BufferSpellingChecker;
});
//# sourceMappingURL=init.js.map