/*
 * 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
 */

package com.pullenti.unitext.internal.misc;

public class ExcelHelper {

    private static int _getColNum(String v) {
        if (v != null && v.length() >= 2) {
            int num = (((int)v.charAt(0)) - ((int)'A'));
            if (v.length() > 2 && Character.isLetter(v.charAt(1))) 
                num = (((num + 1)) * 26) + ((((int)v.charAt(1)) - ((int)'A')));
            return num;
        }
        return -1;
    }

    private static int _getRowNum(String v) {
        if (v != null && v.length() >= 2) {
            int ii = 1;
            if (v.length() > 2 && Character.isLetter(v.charAt(1))) 
                ii = 2;
            int num;
            com.pullenti.unisharp.Outargwrapper<Integer> wrapnum71 = new com.pullenti.unisharp.Outargwrapper<Integer>();
            boolean inoutres72 = com.pullenti.unisharp.Utils.parseInteger(v.substring(ii), 0, null, wrapnum71);
            num = (wrapnum71.value != null ? wrapnum71.value : 0);
            if (inoutres72) 
                return num;
        }
        return -1;
    }

    private static String _getColMnem(int n) {
        if (n < 0) 
            return "?";
        int n0 = n / 26;
        int n1 = n % 26;
        if (n0 == 0) 
            return ((String.valueOf((char)((n1 + ((int)'A'))))));
        return ((String.valueOf((char)(((n0 - 1) + ((int)'A'))))) + ((char)((n1 + ((int)'A')))));
    }

    private static java.util.ArrayList<java.util.ArrayList<com.pullenti.unitext.UnitextTablecell>> _getRows(MyXmlReader xml, java.util.ArrayList<com.pullenti.unitext.UnitextItem> sharedStrings, java.util.ArrayList<Integer> hiddenCols, com.pullenti.unitext.internal.word.DocTextStyles styles, int maxRows, com.pullenti.unisharp.Outargwrapper<Integer> rnum0) {
        rnum0.value = 0;
        java.util.ArrayList<java.util.ArrayList<com.pullenti.unitext.UnitextTablecell>> rows = new java.util.ArrayList<java.util.ArrayList<com.pullenti.unitext.UnitextTablecell>>();
        int cols = 0;
        int allCols = 0;
        while (xml.read()) {
            if (xml.nodeType != MyXmlNodeType.ELEMENT) 
                continue;
            if (com.pullenti.unisharp.Utils.stringsEq(xml.localName, "col") || com.pullenti.unisharp.Utils.stringsEq(xml.localName, "Column")) {
                if (com.pullenti.unisharp.Utils.stringsEq(xml.getAttribute("hidden"), "1")) 
                    hiddenCols.add(allCols);
                allCols++;
                continue;
            }
            if (com.pullenti.unisharp.Utils.stringsCompare(xml.localName, "row", true) == 0) {
                int rn = rows.size();
                int nnn;
                com.pullenti.unisharp.Outargwrapper<Integer> wrapnnn84 = new com.pullenti.unisharp.Outargwrapper<Integer>();
                boolean inoutres85 = com.pullenti.unisharp.Utils.parseInteger((String)com.pullenti.unisharp.Utils.notnull(xml.getAttribute("r"), ""), 0, null, wrapnnn84);
                nnn = (wrapnnn84.value != null ? wrapnnn84.value : 0);
                if (inoutres85) {
                    rn = nnn - 1;
                    if (rnum0.value == 0) 
                        rnum0.value = nnn;
                }
                while (rows.size() <= rn) {
                    rows.add(new java.util.ArrayList<com.pullenti.unitext.UnitextTablecell>());
                }
                java.util.ArrayList<com.pullenti.unitext.UnitextTablecell> row = rows.get(rn);
                if (xml.isEmptyElement) 
                    continue;
                while (xml.read()) {
                    if (xml.nodeType == MyXmlNodeType.ENDELEMENT && com.pullenti.unisharp.Utils.stringsCompare(xml.localName, "row", true) == 0) 
                        break;
                    if (xml.nodeType == MyXmlNodeType.ELEMENT && ((com.pullenti.unisharp.Utils.stringsEq(xml.localName, "c") || com.pullenti.unisharp.Utils.stringsEq(xml.localName, "Cell")))) {
                        int num = -1;
                        boolean isExt = false;
                        boolean inlineStr = false;
                        com.pullenti.unitext.UnitextItem val = null;
                        String v = xml.getAttribute("r");
                        if (v != null && v.length() >= 2) 
                            num = _getColNum(v);
                        else if ((((v = xml.getAttribute("ss:Index")))) != null) {
                            com.pullenti.unisharp.Outargwrapper<Integer> wrapnum73 = new com.pullenti.unisharp.Outargwrapper<Integer>();
                            boolean inoutres74 = com.pullenti.unisharp.Utils.parseInteger(v, 0, null, wrapnum73);
                            num = (wrapnum73.value != null ? wrapnum73.value : 0);
                            if (inoutres74) 
                                num--;
                        }
                        v = xml.getAttribute("t");
                        if (com.pullenti.unisharp.Utils.stringsEq(v, "s")) 
                            isExt = true;
                        else if (com.pullenti.unisharp.Utils.stringsEq(v, "inlineStr")) 
                            inlineStr = true;
                        com.pullenti.unitext.internal.word.DocTextStyle style = null;
                        if ((((v = xml.getAttribute("s")))) != null) {
                            if (styles != null) 
                                style = styles.getStyleById(v);
                        }
                        int mergeAcross = -1;
                        int mergeDown = -1;
                        if ((((v = xml.getAttribute("ss:MergeAcross")))) != null) {
                            com.pullenti.unisharp.Outargwrapper<Integer> wrapmergeAcross75 = new com.pullenti.unisharp.Outargwrapper<Integer>();
                            com.pullenti.unisharp.Utils.parseInteger(v, 0, null, wrapmergeAcross75);
                            mergeAcross = (wrapmergeAcross75.value != null ? wrapmergeAcross75.value : 0);
                        }
                        if ((((v = xml.getAttribute("ss:MergeDown")))) != null) {
                            com.pullenti.unisharp.Outargwrapper<Integer> wrapmergeDown76 = new com.pullenti.unisharp.Outargwrapper<Integer>();
                            com.pullenti.unisharp.Utils.parseInteger(v, 0, null, wrapmergeDown76);
                            mergeDown = (wrapmergeDown76.value != null ? wrapmergeDown76.value : 0);
                        }
                        if (!xml.isEmptyElement) {
                            while (xml.read()) {
                                if (xml.nodeType == MyXmlNodeType.ELEMENT && com.pullenti.unisharp.Utils.stringsEq(xml.localName, "v")) {
                                    if (xml.isEmptyElement) 
                                        break;
                                    if (!xml.read()) 
                                        break;
                                    if (xml.nodeType == MyXmlNodeType.TEXT) {
                                        if (!isExt) {
                                            val = com.pullenti.unitext.UnitextPlaintext._new57(xml.value);
                                            continue;
                                        }
                                        int nu;
                                        com.pullenti.unisharp.Outargwrapper<Integer> wrapnu79 = new com.pullenti.unisharp.Outargwrapper<Integer>();
                                        boolean inoutres80 = com.pullenti.unisharp.Utils.parseInteger(xml.value, 0, null, wrapnu79);
                                        nu = (wrapnu79.value != null ? wrapnu79.value : 0);
                                        if (inoutres80) {
                                            if (nu >= 0 && (nu < sharedStrings.size())) {
                                                com.pullenti.unitext.UnitextItem ss = sharedStrings.get(nu);
                                                if (ss instanceof com.pullenti.unitext.UnitextPlaintext) 
                                                    val = com.pullenti.unitext.UnitextPlaintext._new57(((com.pullenti.unitext.UnitextPlaintext)com.pullenti.unisharp.Utils.cast(ss, com.pullenti.unitext.UnitextPlaintext.class)).text);
                                                else if (ss != null) 
                                                    val = ss.clone();
                                            }
                                        }
                                    }
                                }
                                else if (xml.nodeType == MyXmlNodeType.ELEMENT && com.pullenti.unisharp.Utils.stringsEq(xml.localName, "Data")) {
                                    if (!xml.isEmptyElement) {
                                        xml.read();
                                        try {
                                            if (xml.nodeType == MyXmlNodeType.TEXT) 
                                                val = com.pullenti.unitext.UnitextPlaintext._new57(xml.value);
                                        } catch (Exception eee) {
                                            break;
                                        }
                                    }
                                }
                                else if (xml.nodeType == MyXmlNodeType.ELEMENT && com.pullenti.unisharp.Utils.stringsEq(xml.localName, "is")) {
                                    xml.read();
                                    if (xml.nodeType == MyXmlNodeType.ELEMENT && com.pullenti.unisharp.Utils.stringsEq(xml.localName, "t") && !xml.isEmptyElement) {
                                        xml.read();
                                        if (xml.nodeType == MyXmlNodeType.TEXT) 
                                            val = com.pullenti.unitext.UnitextPlaintext._new57(xml.value);
                                    }
                                }
                                if (xml.nodeType == MyXmlNodeType.ENDELEMENT && ((com.pullenti.unisharp.Utils.stringsEq(xml.localName, "c") || com.pullenti.unisharp.Utils.stringsEq(xml.localName, "Cell")))) 
                                    break;
                            }
                        }
                        if (num < 0) 
                            num = row.size();
                        if ((num + 1) > cols) 
                            cols = num + 1;
                        while (row.size() <= num) {
                            row.add(null);
                        }
                        com.pullenti.unisharp.Utils.putArrayValue(row, num, com.pullenti.unitext.UnitextTablecell._new83(num, num, rn, rn, (style == null ? null : style.xlsBorder)));
                        if (val != null) {
                            if (style != null && style.xlsFormat != null) {
                                com.pullenti.unitext.UnitextPlaintext pt = (com.pullenti.unitext.UnitextPlaintext)com.pullenti.unisharp.Utils.cast(val, com.pullenti.unitext.UnitextPlaintext.class);
                                if (pt == null && (val instanceof com.pullenti.unitext.UnitextContainer) && ((com.pullenti.unitext.UnitextContainer)com.pullenti.unisharp.Utils.cast(val, com.pullenti.unitext.UnitextContainer.class)).children.size() == 1) 
                                    pt = (com.pullenti.unitext.UnitextPlaintext)com.pullenti.unisharp.Utils.cast(((com.pullenti.unitext.UnitextContainer)com.pullenti.unisharp.Utils.cast(val, com.pullenti.unitext.UnitextContainer.class)).children.get(0), com.pullenti.unitext.UnitextPlaintext.class);
                                if (pt != null) 
                                    pt.text = style.correctXlsText(pt.text);
                            }
                            row.get(num).content = val;
                        }
                        if (mergeAcross > 0) 
                            row.get(num).setColEnd(row.get(num).getColEnd() + mergeAcross);
                        if (mergeDown > 0) 
                            row.get(num).setRowEnd(row.get(num).getRowEnd() + mergeDown);
                    }
                }
            }
            else if (com.pullenti.unisharp.Utils.stringsEq(xml.localName, "mergeCell")) {
                String val = xml.getAttribute("ref");
                if (val == null) 
                    continue;
                int ii = val.indexOf(':');
                if (ii < 2) 
                    continue;
                String v1 = val.substring(0, 0 + ii);
                String v2 = val.substring(ii + 1);
                if (v2.length() < 2) 
                    continue;
                int col1 = _getColNum(v1);
                int col2 = _getColNum(v2);
                if (((col1 < 0) || (col2 < 0) || col1 >= cols) || col2 >= cols) 
                    continue;
                int row1 = _getRowNum(v1);
                int row2 = _getRowNum(v2);
                row1--;
                row2--;
                if (((row1 < 0) || (row2 < 0) || row1 >= rows.size()) || row2 >= rows.size()) 
                    continue;
                if (col2 > col1) {
                    if ((col1 < rows.get(row1).size()) && rows.get(row1).get(col1) != null) 
                        rows.get(row1).get(col1).setColEnd(col2);
                    for (int jj = row1; jj <= row2; jj++) {
                        for (ii = col1 + 1; ii <= col2 && (ii < rows.get(jj).size()); ii++) {
                            com.pullenti.unisharp.Utils.putArrayValue(rows.get(jj), ii, null);
                        }
                    }
                }
                if (row2 > row1) {
                    if ((col1 < rows.get(row1).size()) && rows.get(row1).get(col1) != null) 
                        rows.get(row1).get(col1).setRowEnd(row2);
                    for (int jj = row1 + 1; jj <= row2; jj++) {
                        for (int kk = col1; kk <= col2; kk++) {
                            if (kk < rows.get(jj).size()) 
                                com.pullenti.unisharp.Utils.putArrayValue(rows.get(jj), kk, null);
                        }
                    }
                }
            }
        }
        return rows;
    }

    public static com.pullenti.unitext.UnitextItem readSheet(MyXmlReader xml, java.util.ArrayList<com.pullenti.unitext.UnitextItem> sharedStrings, String sheetName, com.pullenti.unitext.internal.word.DocTextStyles styles, int maxRows) {
        java.util.ArrayList<Integer> hiddenCols = new java.util.ArrayList<Integer>();
        int rnum0 = 0;
        com.pullenti.unisharp.Outargwrapper<Integer> wraprnum086 = new com.pullenti.unisharp.Outargwrapper<Integer>();
        java.util.ArrayList<java.util.ArrayList<com.pullenti.unitext.UnitextTablecell>> rows = _getRows(xml, sharedStrings, hiddenCols, styles, maxRows, wraprnum086);
        rnum0 = (wraprnum086.value != null ? wraprnum086.value : 0);
        if (maxRows > 0 && rows.size() > maxRows) 
            for(int jjj = maxRows + rows.size() - maxRows - 1, mmm = maxRows; jjj >= mmm; jjj--) rows.remove(jjj);
        hiddenCols.clear();
        return createTable(rows, hiddenCols, sheetName, rnum0);
    }

    public static com.pullenti.unitext.UnitextItem createTable(java.util.ArrayList<java.util.ArrayList<com.pullenti.unitext.UnitextTablecell>> rows, java.util.ArrayList<Integer> hiddenCols, String sheetName, int rnum0) {
        com.pullenti.unitext.UnitextContainer cnt = new com.pullenti.unitext.UnitextContainer();
        com.pullenti.unitext.UnitextTable tab = null;
        int rnu = 0;
        int rnu0 = 0;
        int remptyMax = 0;
        boolean allRowsNoBorder = true;
        for (int rn = 0; rn < rows.size(); rn++) {
            java.util.ArrayList<com.pullenti.unitext.UnitextTablecell> row = new java.util.ArrayList<com.pullenti.unitext.UnitextTablecell>();
            for (int cn = 0; cn < rows.get(rn).size(); cn++) {
                if (rows.get(rn).get(cn) != null) {
                    if (hiddenCols.contains(cn)) 
                        continue;
                    com.pullenti.unitext.UnitextTablecell c = rows.get(rn).get(cn);
                    row.add(c);
                    if (c.tag instanceof BorderInfo) {
                        if (!((BorderInfo)com.pullenti.unisharp.Utils.cast(c.tag, BorderInfo.class)).isEmpty()) {
                            allRowsNoBorder = false;
                            break;
                        }
                    }
                }
            }
            if (!allRowsNoBorder) 
                break;
        }
        for (int rn = 0; rn < rows.size(); rn++) {
            java.util.ArrayList<com.pullenti.unitext.UnitextTablecell> row = new java.util.ArrayList<com.pullenti.unitext.UnitextTablecell>();
            boolean hasBorder = false;
            int hasData = 0;
            for (int cn = 0; cn < rows.get(rn).size(); cn++) {
                if (rows.get(rn).get(cn) != null) {
                    if (hiddenCols.contains(cn)) 
                        continue;
                    com.pullenti.unitext.UnitextTablecell c = rows.get(rn).get(cn);
                    row.add(c);
                    if (c.tag instanceof BorderInfo) {
                        if (!((BorderInfo)com.pullenti.unisharp.Utils.cast(c.tag, BorderInfo.class)).isEmpty()) 
                            hasBorder = true;
                    }
                    if (c.content != null) 
                        hasData++;
                }
            }
            if (hasData == 0) {
                if (rn <= remptyMax) 
                    continue;
                if (!hasBorder || tab == null) {
                    tab = null;
                    if (cnt.children.size() > 0 && (cnt.children.get(cnt.children.size() - 1) instanceof com.pullenti.unitext.UnitextNewline)) 
                        ((com.pullenti.unitext.UnitextNewline)com.pullenti.unisharp.Utils.cast(cnt.children.get(cnt.children.size() - 1), com.pullenti.unitext.UnitextNewline.class)).count++;
                    else 
                        cnt.children.add(new com.pullenti.unitext.UnitextNewline());
                    continue;
                }
                continue;
            }
            if (hasData == rows.get(rn).size() && hasData > 2) {
            }
            else if (!hasBorder && !allRowsNoBorder) {
                if ((row.size() < 3) || tab == null) {
                    tab = null;
                    boolean fi = true;
                    for (int cn = 0; cn < row.size(); cn++) {
                        if (row.get(cn) != null && row.get(cn).content != null && !hiddenCols.contains(cn)) {
                            if (fi) 
                                fi = false;
                            else 
                                cnt.children.add(com.pullenti.unitext.UnitextPlaintext._new57(" "));
                            cnt.children.add(row.get(cn).content);
                            row.get(cn).content.sourceInfo = ("XLS_CELL:" + cn + (rn + rnu0 + rnum0));
                        }
                    }
                    if (cnt.children.size() > 0 && (cnt.children.get(cnt.children.size() - 1) instanceof com.pullenti.unitext.UnitextNewline)) 
                        ((com.pullenti.unitext.UnitextNewline)com.pullenti.unisharp.Utils.cast(cnt.children.get(cnt.children.size() - 1), com.pullenti.unitext.UnitextNewline.class)).count++;
                    else 
                        cnt.children.add(new com.pullenti.unitext.UnitextNewline());
                    continue;
                }
            }
            if (tab == null) {
                cnt.children.add(new com.pullenti.unitext.UnitextNewline());
                tab = new com.pullenti.unitext.UnitextTable();
                cnt.children.add(tab);
                rnu = 0;
                rnu0 = rn;
                remptyMax = rn;
                tab.sourceInfo = ("XLS_SHEET:" + sheetName);
            }
            for (int cn = 0; cn < row.size(); cn++) {
                if (row.get(cn) != null && !hiddenCols.contains(cn)) {
                    com.pullenti.unitext.UnitextTablecell rr = row.get(cn);
                    if (rr.getRowEnd() > remptyMax) 
                        remptyMax = rr.getRowEnd();
                    rr.setRowBegin(rr.getRowBegin() - rnu0);
                    rr.setRowEnd(rr.getRowEnd() - rnu0);
                    com.pullenti.unitext.UnitextTablecell cc = tab.addCell(rr.getRowBegin(), rr.getRowEnd(), rr.getColBegin(), rr.getColEnd(), rr.content, false);
                    if (cc != null && cc.sourceInfo == null) {
                        cc.sourceInfo = ("XLS_CELL:" + _getColMnem(rr.getColBegin()) + (rr.getRowBegin() + rnu0 + rnum0));
                        if (rr.getColEnd() > rr.getColBegin() || rr.getRowEnd() > rr.getRowBegin()) 
                            cc.sourceInfo = (cc.sourceInfo + "-" + _getColMnem(rr.getColEnd()) + (rr.getRowEnd() + rnu0 + rnum0));
                        if (rr.content != null) 
                            rr.content.sourceInfo = cc.sourceInfo;
                    }
                }
            }
            rnu++;
        }
        return cnt.optimize(true, null);
    }

    public static com.pullenti.unitext.UnitextDocument createDocForXml(MyXmlReader xml, int maxRows) {
        com.pullenti.unitext.UnitextDocument res = com.pullenti.unitext.UnitextDocument._new47(com.pullenti.unitext.FileFormat.XLSX);
        com.pullenti.unitext.UnitextContainer cnt = new com.pullenti.unitext.UnitextContainer();
        java.util.HashMap<String, BorderInfo> borders = new java.util.HashMap<String, BorderInfo>();
        com.pullenti.unitext.internal.word.DocTextStyles styles = new com.pullenti.unitext.internal.word.DocTextStyles();
        String sheetName = null;
        while (xml.read()) {
            if (xml.nodeType != MyXmlNodeType.ELEMENT) 
                continue;
            if (com.pullenti.unisharp.Utils.stringsEq(xml.localName, "Worksheet")) {
                if (cnt.children.size() > 0) 
                    cnt.children.add(new com.pullenti.unitext.UnitextPagebreak());
                if (xml.attributes.size() > 0) {
                    for (java.util.Map.Entry<String, String> a : xml.attributes.entrySet()) {
                        String name = a.getValue();
                        sheetName = name;
                        cnt.children.add(com.pullenti.unitext.UnitextPlaintext._new89(name, "SheetName"));
                        cnt.children.add(new com.pullenti.unitext.UnitextNewline());
                        break;
                    }
                }
                continue;
            }
            if (com.pullenti.unisharp.Utils.stringsEq(xml.localName, "Table")) {
                com.pullenti.unitext.UnitextItem tab = readSheet(xml, null, sheetName, styles, maxRows);
                if (tab != null) 
                    cnt.children.add(tab);
            }
        }
        res.content = cnt;
        res.optimize(false, null);
        return res;
    }
    public ExcelHelper() {
    }
}
