/*
 * 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 UnitextItem = require("./../../UnitextItem");
const UnitextTable = require("./../../UnitextTable");
const FileFormat = require("./../../FileFormat");
const UnitextGen = require("./../uni/UnitextGen");
const UnitextDocument = require("./../../UnitextDocument");

class CsvHelper {
    
    static checkDelim(text) {
        let delims = [',', ';', ' ', '\t', '|'];
        let stat = new Int32Array(delims.length);
        let rows = new Int32Array(delims.length);
        let columns = new Int32Array(delims.length);
        let cells = new Array();
        let tmp = new StringBuilder();
        for (let i = 0; (i < delims.length) && (i < 100000); i++) {
            rows[i] = 0;
            let cols = 0;
            for (let j = 0; j < text.length; ) {
                cells.splice(0, cells.length);
                let jj = CsvHelper.readRecord(text, j, delims[i], cells, null);
                if (jj < 0) 
                    break;
                if (cells.length > 1) {
                    if (cols === 0) 
                        cols = cells.length;
                    else if (cols === cells.length) 
                        stat[i]++;
                    else 
                        stat[i]--;
                    rows[i]++;
                }
                if (jj > j) 
                    j = jj;
                else 
                    break;
            }
            columns[i] = cols;
        }
        let delim = String.fromCharCode(0);
        let bestcou = 0;
        let bestrows = 0;
        for (let i = 0; i < delims.length; i++) {
            if (stat[i] > 0 && (stat[i] + 1) >= (Math.floor(((rows[i]) * 0.96)))) {
                if (bestcou === 0 || columns[i] > bestcou || ((columns[i] === bestcou && rows[i] > (Math.floor(((bestrows) * 1.5)))))) {
                    bestcou = columns[i];
                    delim = delims[i];
                    bestrows = rows[i];
                }
            }
        }
        return delim;
    }
    
    static create(text) {
        let delim = CsvHelper.checkDelim(text);
        let cells = new Array();
        let tmp = new StringBuilder();
        let doc = UnitextDocument._new47(FileFormat.CSV);
        let tab = new UnitextTable();
        let gen = new UnitextGen();
        doc.content = tab;
        let row = 0;
        for (let j = 0; j < text.length; ) {
            cells.splice(0, cells.length);
            let jj = CsvHelper.readRecord(text, j, delim, cells, tmp);
            if (jj < 0) 
                break;
            if (cells.length > 0) {
                for (let i = 0; i < cells.length; i++) {
                    let cel = tab.addCell(row, row, i, i, null, false);
                    let val = cells[i];
                    if (Utils.isNullOrEmpty(val)) 
                        continue;
                    gen.clearAll();
                    gen.appendText(val, false);
                    cel.content = gen.finish(true, null);
                }
                row++;
            }
            if (jj > j) 
                j = jj;
            else 
                break;
        }
        let r = 0;
        for (r = 0; r < tab.rowsCount; r++) {
            let cel = tab.getCell(r, tab.colsCount - 1);
            if (cel !== null && cel.content !== null) 
                break;
        }
        if (r >= tab.rowsCount) 
            tab.removeLastColumn();
        return doc;
    }
    
    static readRecord(text, pos, delim, res, tmp) {
        if (pos >= text.length) 
            return -1;
        if (tmp !== null) 
            tmp.length = 0;
        let isQu = false;
        let newCell = false;
        let len = 0;
        let i = 0;
        for (i = pos; i < text.length; i++) {
            let ch = text[i];
            if (isQu) {
                if (ch === '"') {
                    if (((i + 1) < text.length) && text[i + 1] === '"') {
                        if (tmp !== null) 
                            tmp.append('"');
                        i++;
                        len++;
                        continue;
                    }
                    isQu = false;
                    continue;
                }
                if (tmp !== null) 
                    tmp.append(ch);
                len++;
                continue;
            }
            if (ch === delim && (delim.charCodeAt(0)) !== 0) {
                if (tmp !== null) {
                    res.push(tmp.toString().trim());
                    tmp.length = 0;
                }
                else 
                    res.push(null);
                newCell = true;
                len = 0;
                continue;
            }
            if ((ch.charCodeAt(0)) === 0xD || (ch.charCodeAt(0)) === 0xA) {
                i++;
                if (i < text.length) {
                    ch = text[i];
                    if ((ch.charCodeAt(0)) === 0xD || (ch.charCodeAt(0)) === 0xA) 
                        i++;
                }
                break;
            }
            if (ch === '"' && len === 0) {
                if (((i + 1) < text.length) && text[i + 1] === '"') 
                    i++;
                else 
                    isQu = true;
            }
            else {
                if (tmp !== null) 
                    tmp.append(ch);
                len++;
            }
        }
        if (len > 0 || newCell) {
            if (tmp !== null) 
                res.push(tmp.toString().trim());
            else 
                res.push(null);
        }
        return i;
    }
}


module.exports = CsvHelper