/*
 * SDK Pullenti Unitext, version 4.33, fabruary 2026. Copyright (c) 2013-2026, Pullenti. All rights reserved. 
 * Non-Commercial Freeware and Commercial Software. 
 * This class is generated using the converter UniSharping (www.unisharping.ru) from Pullenti C# project. 
 * The latest version of the code is available on the site www.pullenti.ru
 */

const Utils = require("./../../../unisharp/Utils");
const Hashtable = require("./../../../unisharp/Hashtable");
const StringBuilder = require("./../../../unisharp/StringBuilder");

const GetPlaintextParam = require("./../../GetPlaintextParam");
const HtmlNode = require("./HtmlNode");
const HtmlParser = require("./HtmlParser");

// Используется для встраивания узлов в HTML-тексты
class HtmlCorrector {
    
    constructor(_html) {
        this.m_Html = null;
        this.m_Root = null;
        this.m_Impls = null;
        this.m_Text = null;
        this.m_Html = _html;
        this.m_Impls = new Hashtable();
        this._parse();
        if (this.m_Text === null) 
            this.m_Text = "";
    }
    
    _parse() {
        let tmp = new StringBuilder(this.m_Html);
        this.m_Root = HtmlParser.parse(tmp, true);
        if (this.m_Root !== null) {
            if (this.m_Root.tagName === "HTML") 
                this.m_Root.tagName = "DIV";
            if (!Utils.isNullOrEmpty(this.m_Root.text) && this.m_Root.tagName === null) {
                let hh = HtmlNode._new1("span");
                hh.children.push(this.m_Root);
                this.m_Root.parent = hh;
                this.m_Root = hh;
            }
            this._createText();
        }
    }
    
    _createText() {
        let pars = GetPlaintextParam._new2("\n", "  ", "\n\n");
        this.m_Text = this.m_Root.getPlaintext(pars);
    }
    
    get plainText() {
        return this.m_Text;
    }
    
    get htmlText() {
        if (this.m_Root === null) 
            return "";
        let res = new StringBuilder();
        this.m_Root.getHtml(res);
        return res.toString();
    }
    
    setText(beginChar, endChar, newText) {
        if (this.m_Root === null || this.m_Text === null) 
            return false;
        if (beginChar > this.m_Text.length || endChar > this.m_Text.length || beginChar > endChar) 
            return false;
        let nod = this.m_Root.implantateNode(beginChar, endChar, "span");
        if (nod === null) 
            return false;
        if (Utils.isNullOrEmpty(newText)) {
            if (nod.parent !== null && nod.parent.children.includes(nod)) {
                Utils.removeItem(nod.parent.children, nod);
                this._createText();
                return true;
            }
            return false;
        }
        if (nod.children !== null && nod.children.length > 0) 
            nod.children.splice(0, nod.children.length);
        nod.text = newText;
        nod.tagName = null;
        this._createText();
        return true;
    }
    
    implantateNode(beginChar, endChar, tagName, id, attrs) {
        if ((this.m_Root === null || Utils.isNullOrEmpty(tagName) || (beginChar < 0)) || beginChar > endChar || endChar >= this.m_Text.length) 
            return false;
        if (id === null) 
            return false;
        if (this.m_Impls.containsKey(id)) 
            this.removeNode(id);
        for (; (beginChar < endChar) && (beginChar < this.m_Text.length); beginChar++) {
            if (!Utils.isWhitespace(this.m_Text[beginChar])) 
                break;
        }
        for (; endChar > beginChar; endChar--) {
            if (!Utils.isWhitespace(this.m_Text[endChar])) 
                break;
        }
        let nod = this.m_Root.implantateNode(beginChar, endChar, tagName);
        if (nod === null) 
            return false;
        nod.attrs = new Hashtable();
        nod.attrs.put("ID", id);
        if (attrs !== null) {
            for (const kp of attrs.entries) {
                if (!nod.attrs.containsKey(kp.key.toUpperCase())) 
                    nod.attrs.put(kp.key.toUpperCase(), kp.value);
            }
        }
        this.m_Impls.put(id, nod);
        return true;
    }
    
    replaceText(oldText, newText, tagName, id, attrs) {
        if ((this.m_Root === null || Utils.isNullOrEmpty(tagName))) 
            return false;
        if (id === null) 
            return false;
        if (this.m_Impls.containsKey(id)) 
            this.removeNode(id);
        let bChar = this.m_Text.indexOf(oldText);
        let eChar = (bChar + oldText.length) - 1;
        let nod = this.m_Root.replaceTextRange(bChar, eChar, newText, tagName, null);
        if (nod === null) 
            return false;
        nod.attrs = new Hashtable();
        nod.attrs.put("ID", id);
        if (attrs !== null) {
            for (const kp of attrs.entries) {
                if (!nod.attrs.containsKey(kp.key.toUpperCase())) 
                    nod.attrs.put(kp.key.toUpperCase(), kp.value);
            }
        }
        this.m_Impls.put(id, nod);
        return true;
    }
    
    removeNode(id) {
        if (this.m_Impls.containsKey(id)) {
            this.m_Impls.get(id).remove();
            this.m_Impls.remove(id);
            if (this.m_Impls.length === 0) 
                this._parse();
            return true;
        }
        else 
            return false;
    }
    
    findNode(tagName, attrName, attrValue) {
        if (this.m_Root === null) 
            return null;
        return this.m_Root.findSubnode(tagName, attrName, attrValue);
    }
    
    clearAll() {
        for (const kp of this.m_Impls.entries) {
            kp.value.remove();
        }
        this.m_Impls.clear();
        this._parse();
    }
}


module.exports = HtmlCorrector