"use strict";
module.exports = class ModificationToken {
    constructor(token, tokenIndice, containError) {
        this.token = token;
        this.prev = null;
        this.next = null;
        this.status = 1;
        this.modified = 0;
        this.actions = [];
        if (tokenIndice != undefined) {
            this.tokenIndice = tokenIndice;
        }
        this.containError = containError;
    }
    SetId(id) {
        this.id = id;
    }

    SetModified(modified) {
        this.modified = modified != undefined ? modified : 1;
        this.containError = 0;
    }
    MultipleModified(ctStart, ctEnd, modified) {
        var ct = ctStart;
        while (ct) {
            ct.SetModified(modified);
            if (ct == ctEnd) {
                break;
            }
            ct = ct.next;
        }
    }
    Next(usedCts) {
        if (!this.next) {
            return null;
        }
        if (usedCts.indexOf(this.next) != -1)
        {
            debugger;
            return null;
        }
        usedCts.push(this.next);
        return this.next;
    }
    NextActive(usedCts) {
        if (!this.next) {
            return null;
        }
        if (usedCts.indexOf(this.next) != -1)
        {
            debugger;
            return null;
        }
        usedCts.push(this.next);
        if (!this.next.status) {
            return this.next.NextActive(usedCts);
        }
        return this.next;
    }
    AddAction(type, error) {
        if (error) {
            this.actions.push({
                type: type,
                error: error
            });
        }
    }
    MultipleAddAction(ctStart, ctEnd, type, error) {
        if (error) {
            var ct = ctStart;
            while (ct) {
                ct.AddAction(type, error);
                if (ct == ctEnd) {
                    break;
                }
                ct = ct.next;
            }
        }
    }
    SetDelete(options) {
        this.status = 0;
        this.SetModified(options.modified);
        this.AddAction("delete", options.error);
    }
    InsertNewToken(token, options) {
        if (!token) {
            debugger;
            return;
        }

        var correctionToken = new ModificationToken(token, undefined, false);
        correctionToken.AddAction("new", options.error);
        correctionToken.SetModified(options.modified);
        if (options.prefixId && options.indice != undefined) {
            correctionToken.id = options.prefixId + "-" + options.indice;
            options.indice++;
        }
        if (token.spaceBefore == undefined)
        {
            token.spaceBefore = this.prev ? 1:0;
        }
        if (this.token.spaceBefore == undefined ||
            this.token.spaceBefore == 0)
        {
            this.token.spaceBefore = 1;
        }
        if (this.prev) {
            this.prev.next = correctionToken;
            correctionToken.prev = this.prev;
        }

        this.prev = correctionToken;
        correctionToken.next = this;
    }
    InsertNewAfterToken(token, options) {
        if (!token) {
            debugger;
            return;
        }
        if (token.spaceBefore == undefined) {
            token.spaceBefore = 1;
        }
        // if (token.word == "does")
        // {
        //     debugger;
        //     token.word = "do";
        // }
        var correctionToken = new ModificationToken(token, undefined, false);
        correctionToken.AddAction("new", options.error);
        correctionToken.SetModified(options.modified);
        if (options.prefixId && options.indice != undefined) {
            correctionToken.id = options.prefixId + "-" + options.indice;
            options.indice++;
        }
        if (this.next) {
            this.next.prev = correctionToken;
            correctionToken.next = this.next;
        }
        this.next = correctionToken;
        correctionToken.prev = this;
    }
    MoveBefore(ctStart, ctEnd, options) {
        if (ctStart.prev) {
            if (ctStart.prev == ctEnd.next)
            {
                debugger;
            }
            ctStart.prev.next = ctEnd.next;
        }
        if (ctEnd.next) {
            ctEnd.next.prev = ctStart.prev;
        }
        if (this.prev) {
            this.prev.next = ctStart;
        }
        ctStart.prev = this.prev;
        this.prev = ctEnd;
        if (ctEnd==this) {
            debugger;
        }
        ctEnd.next = this;
        this.MultipleModified(ctStart, ctEnd, options.modified);
        this.MultipleAddAction(ctStart, ctEnd, "move", options.error);
    }
    MoveAfter(ctStart, ctEnd, options) {
        if (ctStart.prev) {
            if (ctStart.prev == ctEnd.next)
            {
                debugger;
            }
            ctStart.prev.next = ctEnd.next;
        }
        if (ctEnd.next) {
            ctEnd.next.prev = ctStart.prev;
        }
        if (this.next) {
            this.next.prev = ctEnd;
        }
        if (ctEnd == this.next)
        {
            debugger;
        }
        ctEnd.next = this.next;
        if (this == ctStart)
        {
            debugger;
        }
        this.next = ctStart;
        ctStart.prev = this;
        this.MultipleModified(ctStart, ctEnd, options.modified);
        this.MultipleAddAction(ctStart, ctEnd, "move", options.error);
    }
    GetModifiedToken()
    {
        if (this.modifiedToken) {
            return this.modifiedToken;
        }
        return this.token;
    }
    DuplicateToken()
    {
        if (Object.assign)
        {
            return Object.assign({},this.token , {});
        }
        return TFSCommon.DuplicateObject(this.token);
    }

    ReplaceAttValue(modification, ctEnd, options) {
        if (modification.att &&
            modification.text) {
            if (!this.modifiedToken) {
                this.modifiedToken = this.DuplicateToken();
            }
            if (this.modifiedToken[modification.att] == undefined) {
                debugger;
            }
            this.SetModified(options.modified);
            this.AddAction("modifyAtt", options.error);
            this.modifiedToken[modification.att] = modification.text;
            if (modification.att == "word" && 
                modification.text)
            {
                var results = modification.text.match(/^[A-Z]/);
                if (results)
                {
                    this.modifiedToken.keepCase = true;
                }
            }
            //
            if (ctEnd != undefined && ctEnd != this) {
                var ctStart = this.next;
                var ct = ctStart;
                while (ct) {
                    ct.SetDelete(options);
                    if (ct == ctEnd) {
                        break;
                    }
                    ct = ct.next;
                }
            }
        }
        else {
            debugger;
        }
    }
    GetOriginalWord() {
        return this.token.word;
    }
    GetModifiedWord() {
        if (this.modifiedToken) {
            return this.modifiedToken.word;
        }
        return this.token.word;
    }
    SetModifiedWord(word) {
        if (!this.modifiedToken)
        {
            this.modifiedToken = this.DuplicateToken();
        }
        this.modifiedToken.word = word;
    }
    SetModifiedSpaceBefore(spaceBefore) {
        if (!this.modifiedToken)
        {
            this.modifiedToken = this.DuplicateToken();
        }
        this.modifiedToken.spaceBefore = spaceBefore;
    }
    GetModifiedSpaceBefore() {
        if (this.modifiedToken)
        {
            return this.modifiedToken.spaceBefore;
        }
        return this.token.spaceBefore;
    }
    _GetLightToken(token)
    {
        return {
            word: token.word,
            lemma: token.lemma,
            pos: token.pos
        };
    }
    GetLightOriginalToken(){
        return this._GetLightToken(this.token);
    }
    GetLightModifiedToken()
    {
        if (this.modifiedToken) {
            return this._GetLightToken(this.modifiedToken);
        }
        return this._GetLightToken(this.token);
    }
}
