/*
 * 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 StringBuilder = require("./../unisharp/StringBuilder");

const UnitextContainerType = require("./UnitextContainerType");
const MiscHelper = require("./../util/MiscHelper");
const UnitextContainer = require("./UnitextContainer");
const UnitextDocblockType = require("./UnitextDocblockType");
const UnitextItem = require("./UnitextItem");

/**
 * Cтруктурирующий блок из заголовочной части, тела, окончания и приложений. 
 * Выделяется только для некоторых форматов, если задать LoadDocumentStructure = true в параметрах создания. 
 * Но этот элемент активно используется на других этапах анализа, когда структура документа восстанавливается 
 * по плоскому тексту, а затем их иерархия оформляется этими элементами. Например, для нормативных актов 
 * это главы, статьи, части, пункты и подпункты.
 * Структурирующий блок с заголовком
 */
class UnitextDocblock extends UnitextItem {
    
    constructor() {
        super();
        this.head = null;
        this.body = null;
        this.tail = null;
        this.appendix = null;
        this.typname = null;
        this.number = null;
        this.typ = UnitextDocblockType.UNDEFINED;
        this.expired = false;
        this.extBlockId = null;
        this.m_IsInline = false;
    }
    
    toString() {
        let res = new StringBuilder();
        if (this.typname !== null) 
            res.append(this.typname).append(" ");
        if (this.number !== null) 
            res.append(this.number).append(" ");
        if (this.typ !== UnitextDocblockType.UNDEFINED) 
            res.append("Typ:").append(this.typ.toString()).append(" ");
        return res.toString().trim();
    }
    
    clone() {
        let res = new UnitextDocblock();
        res._cloneFrom(this);
        if (this.head !== null) 
            res.head = Utils.as(this.head.clone(), UnitextContainer);
        if (this.body !== null) 
            res.body = this.body.clone();
        if (this.tail !== null) 
            res.tail = Utils.as(this.tail.clone(), UnitextContainer);
        if (this.appendix !== null) 
            res.appendix = this.appendix.clone();
        res.extBlockId = this.extBlockId;
        res.typ = this.typ;
        res.typname = this.typname;
        res.number = this.number;
        res.expired = this.expired;
        return res;
    }
    
    get isInline() {
        return this.m_IsInline;
    }
    set isInline(value) {
        this.m_IsInline = value;
        return value;
    }
    
    get startsOnNewline() {
        return true;
    }
    
    get innerTag() {
        return "docblk";
    }
    
    findById(_id) {
        if (this.id === _id) 
            return this;
        let res = null;
        if (this.head !== null) {
            if ((((res = this.head.findById(_id)))) !== null) 
                return res;
        }
        if (this.tail !== null) {
            if ((((res = this.tail.findById(_id)))) !== null) 
                return res;
        }
        if (this.body !== null) {
            if ((((res = this.body.findById(_id)))) !== null) 
                return res;
        }
        if (this.appendix !== null) {
            if ((((res = this.appendix.findById(_id)))) !== null) 
                return res;
        }
        return null;
    }
    
    getPlaintext(res, pars) {
        if (pars !== null && pars.setPositions) 
            this.beginChar = res.length;
        if (this.head !== null) 
            this.head.getPlaintext(res, pars);
        if (this.body !== null) 
            this.body.getPlaintext(res, pars);
        if (this.tail !== null) 
            this.tail.getPlaintext(res, pars);
        if (this.appendix !== null) 
            this.appendix.getPlaintext(res, pars);
        if (pars !== null && pars.setPositions) 
            this.endChar = res.length - 1;
    }
    
    getHtml(res, par) {
        if (!par.callBefore(this, res)) 
            return;
        if (Utils.compareStrings((this.typname != null ? this.typname : ""), "Footnote", true) === 0) 
            return;
        let _tag = "div";
        if (this.isInline) 
            _tag = "span";
        else if (Utils.compareStrings((this.typname != null ? this.typname : ""), "Indention", true) === 0 && (this.parent instanceof UnitextContainer) && this.parent.children[0] === this) {
            let blk = Utils.as(this.parent.parent, UnitextDocblock);
            if (blk !== null && blk.head !== null && blk.head.isInline) 
                _tag = "span";
        }
        if (Utils.compareStrings((this.typname != null ? this.typname : ""), "Part", true) === 0 && this.head === null && this.number !== "1") 
            res.append("\r\n<BR/>");
        res.append("\r\n<").append(_tag);
        if (this.htmlTitle !== null) {
            res.append(" title=\"");
            MiscHelper.correctHtmlValue(res, this.htmlTitle, true, false, false);
            res.append("\"");
        }
        let margleft = 0;
        if (this.typname === "ITEM" || this.typname === "SUBITEM") {
            for (let p = this.parent; p !== null; p = p.parent) {
                if (p instanceof UnitextDocblock) {
                    let pb = Utils.as(p, UnitextDocblock);
                    if (pb.typname === "ITEM" || pb.typname === "SUBITEM" || pb.typname === "CLAUSEPART") 
                        margleft += 10;
                }
            }
        }
        if (Utils.compareStrings((this.typname != null ? this.typname : ""), "Footnote", true) === 0) 
            res.append(" style=\"margin-left:").append((30 + margleft)).append("pt;margin-top:10pt;margin-bottom:10pt;font-size:smaller;text-align:left;font-weight:normal\"");
        else if (Utils.compareStrings((this.typname != null ? this.typname : ""), "Index", true) === 0) 
            res.append(" style=\"border:1pt solid black; background:lightgray; text-align:left;font-weight:normal;font-style:italic\"");
        else if (this.typname !== null) {
            let margtop = 0;
            if (Utils.compareStrings(this.typname, "Chapter", true) === 0 || Utils.compareStrings(this.typname, "Section", true) === 0) 
                margtop = 20;
            else if (Utils.compareStrings(this.typname, "Paragraph", true) === 0 || Utils.compareStrings(this.typname, "Subparagraph", true) === 0) 
                margtop = 15;
            else if (Utils.compareStrings(this.typname, "Clause", true) === 0 || Utils.compareStrings(this.typname, "Subsection", true) === 0) 
                margtop = 10;
            if (margtop > 0 || this.expired || margleft > 0) {
                res.append(" style=\"");
                if (margtop > 0) 
                    res.append("margin-top:").append(margtop).append("pt;");
                if (margleft > 0) 
                    res.append("margin-left:").append(margleft).append("pt;");
                if (this.expired) 
                    res.append("background-color:lightgray;");
                res.append("\"");
            }
        }
        if (this.id !== null) 
            res.append(" id=\"").append(this.id).append("\"");
        res.append(">");
        if (this.head !== null) {
            if (Utils.compareStrings((this.typname != null ? this.typname : ""), "Appendix", true) === 0) {
                let i = 0;
                for (i = 0; i < this.head.children.length; i++) {
                    if ((this.head.children[i] instanceof UnitextContainer) && this.head.children[i].typ === UnitextContainerType.NAME) 
                        break;
                }
                if (i > 0) {
                    res.append("\r\n<div style=\"text-align:right;font-style:italic\">");
                    for (let j = 0; j < i; j++) {
                        this.head.children[j].getHtml(res, par);
                    }
                    res.append("</div>");
                }
                if (i < this.head.children.length) {
                    res.append("\r\n<div style=\"text-align:center;font-weight:bold;font-style:normal\">");
                    for (; i < this.head.children.length; i++) {
                        this.head.children[i].getHtml(res, par);
                    }
                    res.append("</div>");
                }
                res.append("<div style=\"margin-bottom:20pt\"> </div>");
            }
            else {
                if (Utils.compareStrings((this.typname != null ? this.typname : ""), "Mail", true) !== 0) 
                    res.append("<b>");
                else 
                    res.append("<i>");
                this.head.getHtml(res, par);
                if (Utils.compareStrings((this.typname != null ? this.typname : ""), "Mail", true) !== 0) 
                    res.append("</b>");
                else 
                    res.append("</i>");
            }
            if (par !== null) 
                par._outFootnotes(res);
        }
        if (this.body !== null) {
            this.body.getHtml(res, par);
            if (par !== null) 
                par._outFootnotes(res);
        }
        if (this.tail !== null) {
            res.append("<i>");
            this.tail.getHtml(res, par);
            res.append("</i>");
            if (par !== null) 
                par._outFootnotes(res);
        }
        if (this.appendix !== null) {
            this.appendix.getHtml(res, par);
            if (par !== null) 
                par._outFootnotes(res);
        }
        res.append("</").append(_tag).append(">");
        par.callAfter(this, res);
    }
    
    getXml(xml) {
        xml.writeStartElement("docblock");
        this._writeXmlAttrs(xml);
        if (this.typname !== null) 
            xml.writeAttributeString("typname", this.typname);
        if (this.number !== null) 
            xml.writeAttributeString("num", MiscHelper.correctXmlValue(this.number));
        if (this.typ !== UnitextDocblockType.UNDEFINED) 
            xml.writeAttributeString("typ", this.typ.toString().toLowerCase());
        if (this.m_IsInline) 
            xml.writeAttributeString("inline", "true");
        if (this.extBlockId !== null) 
            xml.writeAttributeString("extblockid", this.extBlockId);
        if (this.expired) 
            xml.writeAttributeString("expired", "true");
        if (this.head !== null) {
            xml.writeStartElement("head");
            this.head.getXml(xml);
            xml.writeEndElement();
        }
        if (this.body !== null) {
            xml.writeStartElement("body");
            this.body.getXml(xml);
            xml.writeEndElement();
        }
        if (this.tail !== null) {
            xml.writeStartElement("tail");
            this.tail.getXml(xml);
            xml.writeEndElement();
        }
        if (this.appendix !== null) {
            xml.writeStartElement("appendix");
            this.appendix.getXml(xml);
            xml.writeEndElement();
        }
        xml.writeEndElement();
    }
    
    fromXml(xml) {
        const UnitextHelper = require("./internal/uni/UnitextHelper");
        super.fromXml(xml);
        if (xml.attributes !== null) {
            for (const a of xml.attributes) {
                if (a.local_name === "typname") 
                    this.typname = a.value;
                else if (a.local_name === "num") 
                    this.number = a.value;
                else if (a.local_name === "extblockid") 
                    this.extBlockId = a.value;
                else if (a.local_name === "expired") 
                    this.expired = a.value === "true";
                else if (a.local_name === "inline") 
                    this.m_IsInline = a.value === "true";
                else if (a.local_name === "typ") {
                    try {
                        this.typ = UnitextDocblockType.of(a.value);
                    } catch (ex589) {
                    }
                }
            }
        }
        for (const x of xml.child_nodes) {
            if (x.local_name === "head") {
                for (const xx of x.child_nodes) {
                    this.head = Utils.as(UnitextHelper.createItem(xx, this), UnitextContainer);
                    if (this.head !== null) 
                        this.head.typ = UnitextContainerType.HEAD;
                    break;
                }
            }
            else if (x.local_name === "body") {
                for (const xx of x.child_nodes) {
                    this.body = UnitextHelper.createItem(xx, this);
                    break;
                }
            }
            else if (x.local_name === "appendix") {
                for (const xx of x.child_nodes) {
                    this.appendix = UnitextHelper.createItem(xx, this);
                    break;
                }
            }
            else if (x.local_name === "tail") {
                for (const xx of x.child_nodes) {
                    this.tail = Utils.as(UnitextHelper.createItem(xx, this), UnitextContainer);
                    if (this.tail !== null) 
                        this.tail.typ = UnitextContainerType.TAIL;
                    break;
                }
            }
        }
    }
    
    get isWhitespaces() {
        return false;
    }
    
    getAllItems(res, lev) {
        if (res !== null) 
            res.push(this);
        if (this.head !== null) {
            if (this.head.children.includes(this.head)) {
            }
            else if (this.head.children.includes(this)) {
            }
            else {
                this.head.parent = this;
                this.head.getAllItems(res, lev + 1);
            }
        }
        if (this.body !== null) {
            this.body.parent = this;
            this.body.getAllItems(res, lev + 1);
        }
        if (this.tail !== null) {
            this.tail.parent = this;
            this.tail.getAllItems(res, lev + 1);
        }
        if (this.appendix !== null) {
            this.appendix.parent = this;
            this.appendix.getAllItems(res, lev + 1);
        }
    }
    
    addPlainTextPos(d) {
        super.addPlainTextPos(d);
        if (this.head !== null) 
            this.head.addPlainTextPos(d);
        if (this.body !== null) 
            this.body.addPlainTextPos(d);
        if (this.tail !== null) 
            this.tail.addPlainTextPos(d);
        if (this.appendix !== null) 
            this.appendix.addPlainTextPos(d);
    }
    
    correct(_typ, data) {
        if (this.head !== null) 
            this.head.correct(_typ, data);
        if (this.body !== null) 
            this.body.correct(_typ, data);
        if (this.tail !== null) 
            this.tail.correct(_typ, data);
        if (this.appendix !== null) 
            this.appendix.correct(_typ, data);
    }
    
    setDefaultTextPos(cp, res) {
        this.beginChar = cp.value;
        if (this.head !== null) {
            this.head.setDefaultTextPos(cp, res);
            this.head.parent = this;
        }
        if (this.body !== null) {
            this.body.setDefaultTextPos(cp, res);
            this.body.parent = this;
        }
        if (this.tail !== null) {
            this.tail.setDefaultTextPos(cp, res);
            this.tail.parent = this;
        }
        if (this.appendix !== null) {
            this.appendix.setDefaultTextPos(cp, res);
            this.appendix.parent = this;
        }
        this.endChar = cp.value - 1;
    }
    
    optimize(isContent, pars) {
        if (this.head !== null) {
            if (this.head.children.includes(this.head)) {
            }
            this.head = Utils.as(this.head.optimize(false, pars), UnitextContainer);
        }
        if (this.body !== null) 
            this.body = this.body.optimize(true, pars);
        if (this.tail !== null) 
            this.tail = Utils.as(this.tail.optimize(false, pars), UnitextContainer);
        if (this.appendix !== null) 
            this.appendix = this.appendix.optimize(true, pars);
        return this;
    }
    
    _appendChild(it) {
        if (this.appendix !== null) {
            let cnt = Utils.as(this.appendix, UnitextContainer);
            if (cnt === null) {
                cnt = UnitextContainer._new590(this.body.beginChar);
                cnt.children.push(this.body);
                this.appendix = cnt;
            }
            cnt.children.push(it);
            this.endChar = (this.body.endChar = it.endChar);
            return true;
        }
        if (this.tail !== null) {
            this.tail.children.push(it);
            this.endChar = (this.tail.endChar = it.endChar);
            return true;
        }
        if (this.body !== null) {
            let cnt = Utils.as(this.body, UnitextContainer);
            if (cnt === null) {
                cnt = UnitextContainer._new590(this.body.beginChar);
                cnt.children.push(this.body);
                this.body = cnt;
            }
            cnt.children.push(it);
            this.endChar = (this.body.endChar = it.endChar);
            return true;
        }
        if (this.head !== null) {
            this.head.children.push(it);
            this.endChar = (this.head.endChar = it.endChar);
            return true;
        }
        return false;
    }
    
    static _new38(_arg1) {
        let res = new UnitextDocblock();
        res.typname = _arg1;
        return res;
    }
    
    static _new402(_arg1, _arg2) {
        let res = new UnitextDocblock();
        res.beginChar = _arg1;
        res.endChar = _arg2;
        return res;
    }
}


module.exports = UnitextDocblock