/*
 * 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 UnitextItem = require("./../../UnitextItem");
const UnitextTable = require("./../../UnitextTable");
const UnitextContainerType = require("./../../UnitextContainerType");
const UnitextStyledFragmentType = require("./../../UnitextStyledFragmentType");
const UnitextStyledFragment = require("./../../UnitextStyledFragment");
const UnitextStyle = require("./../../UnitextStyle");
const DocTableRow = require("./DocTableRow");
const DocTableCell = require("./DocTableCell");
const UnitextContainer = require("./../../UnitextContainer");

class DocTable {
    
    constructor() {
        this.cols = 0;
        this.rows = new Array();
        this.colWidth = new Array();
        this.hideBorders = false;
        this.tabHeaderPaginate = false;
        this.m_Style = null;
    }
    
    read(own, sfrag, stackNodes) {
        if (sfrag !== null) {
            this.m_Style = UnitextStyledFragment._new448(UnitextStyledFragmentType.TABLE, sfrag);
            sfrag.children.push(this.m_Style);
        }
        let xml = stackNodes[stackNodes.length - 1];
        for (const x of xml.child_nodes) {
            if (x.local_name === "tblGrid") {
                for (const xx of x.child_nodes) {
                    if (xx.local_name === "gridCol") {
                        this.cols++;
                        if (xx.attributes !== null) {
                            for (const a of xx.attributes) {
                                if (a.local_name === "w") {
                                    let n = 0;
                                    let wrapn449 = new RefOutArgWrapper();
                                    let inoutres450 = Utils.tryParseInt(Utils.notNull(a.value, ""), wrapn449);
                                    n = wrapn449.value;
                                    if (inoutres450) 
                                        this.colWidth.push(n);
                                }
                            }
                        }
                    }
                }
            }
            else if (x.local_name === "tblPr") {
                if (this.m_Style !== null) {
                    let st0 = new UnitextStyle();
                    own.m_Styles.readUnitextStyle(x, st0, false);
                    st0.removeInheritAttrs(this.m_Style);
                    this.m_Style.style = own.m_Styles.registerStyle(st0);
                }
                let cou = 0;
                for (const xx of x.child_nodes) {
                    if (xx.local_name === "tblBorders") {
                        for (const xxx of xx.child_nodes) {
                            if (((xxx.local_name === "top" || xxx.local_name === "left" || xxx.local_name === "right") || xxx.local_name === "bottom" || xxx.local_name === "start") || xxx.local_name === "end") {
                                if (xxx.attributes !== null) {
                                    for (const a of xxx.attributes) {
                                        if (a.local_name === "color") {
                                            if (a.value === "FFFFFF") 
                                                cou++;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                if (cou === 4) 
                    this.hideBorders = true;
            }
            else if (x.local_name === "tr") {
                let tr = new DocTableRow();
                this.rows.push(tr);
                let firstSpan = 0;
                for (const xx of x.child_nodes) {
                    if (xx.local_name === "tc") {
                        let tc = new DocTableCell();
                        tr.cells.push(tc);
                        stackNodes.push(xx);
                        tc.read(own, this.m_Style, stackNodes);
                        stackNodes.splice(stackNodes.length - 1, 1);
                        if (firstSpan > 0) {
                            tc.colSpan += firstSpan;
                            firstSpan = 0;
                        }
                    }
                    else if (xx.local_name === "sdt") {
                        for (const xxx of xx.child_nodes) {
                            if (xxx.local_name === "sdtContent") {
                                for (const xxxx of xxx.child_nodes) {
                                    if (xxxx.local_name === "tc") {
                                        let tc = new DocTableCell();
                                        tr.cells.push(tc);
                                        stackNodes.push(xxxx);
                                        tc.read(own, this.m_Style, stackNodes);
                                        stackNodes.splice(stackNodes.length - 1, 1);
                                        if (firstSpan > 0) {
                                            tc.colSpan += firstSpan;
                                            firstSpan = 0;
                                        }
                                        if (tc.uni instanceof UnitextContainer) 
                                            tc.uni.typ = UnitextContainerType.CONTENTCONTROL;
                                        else {
                                            let ccc = UnitextContainer._new451(UnitextContainerType.CONTENTCONTROL, this.m_Style);
                                            ccc.children.push(tc.uni);
                                            tc.uni.parent = ccc;
                                            tc.uni = ccc;
                                        }
                                    }
                                }
                            }
                        }
                    }
                    else if (xx.local_name === "trPr") {
                        for (const xxx of xx.child_nodes) {
                            if (xxx.local_name === "gridBefore" && xxx.attributes !== null && xxx.attributes.length === 1) {
                                let cou = 0;
                                let wrapcou452 = new RefOutArgWrapper();
                                let inoutres453 = Utils.tryParseInt(xxx.attributes[0].value, wrapcou452);
                                cou = wrapcou452.value;
                                if (inoutres453) {
                                    if (cou > 0) 
                                        firstSpan = cou;
                                }
                            }
                            else if (xxx.local_name === "tblHeader") 
                                this.tabHeaderPaginate = true;
                        }
                    }
                }
            }
        }
        if (this.colWidth.length === this.cols) {
            let nn = 0;
            for (const w of this.colWidth) {
                nn += w;
            }
            if (nn > 0) {
                for (let ii = 0; ii < this.colWidth.length; ii++) {
                    this.colWidth[ii] = Utils.intDiv(this.colWidth[ii] * 100, nn);
                    if (this.colWidth[ii] === 0) 
                        this.colWidth[ii] = 1;
                }
            }
            else 
                this.colWidth.splice(0, this.colWidth.length);
        }
        else 
            this.colWidth.splice(0, this.colWidth.length);
        for (let i = 0; i < this.rows.length; i++) {
            let r = this.rows[i];
            let grNum = 1;
            for (let j = 0; j < r.cells.length; j++) {
                let c = r.cells[j];
                c.gridNum = grNum;
                grNum += c.colSpan;
                if (c.mergeVert !== 1) 
                    continue;
                let spanCell = null;
                for (let ii = i - 1; ii >= 0; ii--) {
                    let rr = this.rows[ii];
                    let grrNum = 1;
                    for (let jj = 0; jj < rr.cells.length; jj++) {
                        let cc = rr.cells[jj];
                        if (cc.mergeVert === 2 && ((c.gridNum === cc.gridNum || c.gridNum === grrNum))) {
                            cc.rowSpan++;
                            spanCell = cc;
                            break;
                        }
                        grrNum += cc.colSpan;
                    }
                    if (spanCell !== null) 
                        break;
                }
                if (spanCell === null) {
                }
            }
        }
    }
    
    createUni(maxRows) {
        if (this.rows.length === 0) 
            return null;
        let tab = new UnitextTable();
        tab.m_StyledFrag = this.m_Style;
        tab.hideBorders = this.hideBorders;
        tab.tableHeaderPaginate = this.tabHeaderPaginate;
        for (let ii = 0; ii < this.colWidth.length; ii++) {
            tab.setColWidth(ii, (String(this.colWidth[ii]) + "%"));
        }
        let rn = 0;
        for (const r of this.rows) {
            let cn = 0;
            for (const c of r.cells) {
                if (c.mergeVert === 1) 
                    continue;
                for (; ; cn++) {
                    if (tab.getCell(rn, cn) === null) 
                        break;
                }
                let cel = tab.addCell(rn, (rn + c.rowSpan) - 1, cn, (cn + c.colSpan) - 1, c.uni, false);
                cel.m_StyledFrag = c.frag;
                if (c.uni !== null && c.uni.m_StyledFrag === c.frag) 
                    c.uni.m_StyledFrag = null;
                cn += c.colSpan;
            }
            rn++;
            if (maxRows > 0 && tab.rowsCount >= maxRows) 
                break;
        }
        return tab;
    }
}


module.exports = DocTable