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

const StructExpressLine = require("./StructExpressLine");

class StructExpressBlock {
    
    constructor() {
        this.lines = new Array();
        this.isApp = false;
        this.hasStructure = false;
    }
    
    get beginChar() {
        if (this.lines.length > 0) 
            return this.lines[0].beginChar;
        return 0;
    }
    
    get endChar() {
        if (this.lines.length > 0) 
            return this.lines[this.lines.length - 1].endChar;
        return 0;
    }
    
    toString() {
        let res = new StringBuilder();
        res.append("[").append(this.beginChar).append("..").append(this.endChar).append("]");
        if (this.isApp) 
            res.append(" Appendix");
        if (this.hasStructure) 
            res.append(" Structured");
        return res.toString();
    }
    
    static parse(text) {
        let _lines = new Array();
        for (let i = 0; i < text.length; ) {
            let wrapi670 = new RefOutArgWrapper(i);
            let li = StructExpressLine.tryParse(text, wrapi670);
            i = wrapi670.value;
            if (li === null) 
                break;
            _lines.push(li);
        }
        if (_lines.length === 0) 
            return null;
        for (let i = 0; i < _lines.length; i++) {
            if (_lines[i].isStartOfApp && _lines[i + 1].isStartOfApp) {
                for (; i < _lines.length; i++) {
                    if (_lines[i].isStartOfApp) 
                        _lines[i].isStartOfApp = false;
                    else 
                        break;
                }
            }
        }
        let res = new Array();
        let cur = new StructExpressBlock();
        res.push(cur);
        for (let i = 0; i < _lines.length; i++) {
            let li = _lines[i];
            if (li.isStartOfApp) {
                if (cur.lines.length > 0) {
                    cur = new StructExpressBlock();
                    res.push(cur);
                }
                cur.isApp = true;
            }
            cur.lines.push(li);
        }
        for (const b of res) {
            b._analyze();
        }
        return res;
    }
    
    _analyze() {
        let clauses = 0;
        let numbered = 0;
        let illegals = 0;
        for (const li of this.lines) {
            if (li.keyword === "СТАТЬЯ" || li.keyword === "СТАТТЯ" || li.keyword === "ГЛАВА") 
                clauses++;
            if (li.number !== null) 
                numbered++;
            if (li.illegalChars >= 2) 
                illegals++;
        }
        if (clauses > 1) 
            this.hasStructure = true;
        else if (clauses === 1 && numbered > 3) 
            this.hasStructure = true;
        else if (numbered > 5 && numbered > (Utils.intDiv(this.lines.length, 3)) && (illegals < 2)) 
            this.hasStructure = true;
        else if (numbered > 20 && numbered > (Utils.intDiv(this.lines.length, 10))) 
            this.hasStructure = true;
    }
}


module.exports = StructExpressBlock