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

const MiscHelper = require("./../../../util/MiscHelper");
const UnitextService = require("./../../UnitextService");
const CompoundFileSystem = require("./CompoundFileSystem");
const FileFormat = require("./../../FileFormat");
const UnitextDocument = require("./../../UnitextDocument");

class MSOfficeHelper {
    
    static checkExtension(fileName) {
        let ext = path.extname(fileName).toUpperCase();
        return (ext === ".DOC" || ext === ".DOCX" || ext === ".PPTX") || ext === ".XLSX";
    }
    
    static _uniFromWord97(cf) {
        const WordDocument = require("./WordDocument");
        let _word = new WordDocument();
        let doc = UnitextDocument._new47(FileFormat.DOC);
        _word.load(cf, doc);
        return doc;
    }
    
    static _uniFromWord97Arr(data) {
        if (data.length > 0x300 && data[0] === (0xD0) && data[1] === (0xCF)) {
            let i0 = 0x50;
            for (; i0 < data.length; i0++) {
                if (data[i0] !== (0xFF)) 
                    break;
            }
            if ((i0 + 0x200) <= data.length && data[i0 + 1] === (0xA5) && data[i0] === (0xDC)) {
                let buf = new Uint8Array(data.length - i0);
                for (let i = 0; i < buf.length; i++) {
                    buf[i] = data[i0 + i];
                }
                let doc = MSOfficeHelper._uniFromWord6orEarly(buf);
                if (doc !== null) {
                    doc.sourceFormat = FileFormat.DOC;
                    doc.attrs.put("word", "6");
                }
                return doc;
            }
        }
        let cf = new CompoundFileSystem(null, data); 
        try {
            return MSOfficeHelper._uniFromWord97(cf);
        }
        finally {
            cf.close();
        }
    }
    
    static _uniFromWord6orEarly(buf) {
        let pos0 = Utils.bytesToObject(buf, 0x18, 'int', 4);
        let pos1 = Utils.bytesToObject(buf, 0x1C, 'int', 4);
        if (pos1 <= buf.length && pos0 >= 0x20 && pos1 > pos0) {
        }
        else 
            return null;
        let v0 = 0;
        let v1 = 0;
        for (let i = pos0; i < pos1; i++) {
            if (buf[i] === (0) || buf[i] === (4)) {
                if (((((i - pos0)) & 1)) === 0) 
                    v1++;
                else 
                    v0++;
            }
        }
        let str = null;
        if (v0 > (v1 * 3)) 
            str = MiscHelper.decodeStringUnicode(buf, pos0, pos1 - pos0);
        else 
            str = MiscHelper.decodeString1251(buf, pos0, pos1 - pos0);
        let ddd = UnitextService.createDocumentFromText(str);
        return ddd;
    }
    
    static _uniFromWord97File(fileName) {
        let cf = new CompoundFileSystem(fileName, null); 
        try {
            return MSOfficeHelper._uniFromWord97(cf);
        }
        finally {
            cf.close();
        }
    }
    
    static _correctContent(txt) {
        let res = new StringBuilder();
        let off = 0;
        let lf = 0;
        let offTmp = new StringBuilder();
        for (let j = 0; j < txt.length; j++) {
            let ch = txt.charAt(j);
            if (ch === ':') {
            }
            if ((ch.charCodeAt(0)) === 127) 
                ch = ' ';
            if (off > 0) {
                if ((ch.charCodeAt(0)) === 0x15) {
                    if ((--off) === 0) {
                        let ttt = MSOfficeHelper.extractSpecText(offTmp.toString().trim());
                        if (ttt !== null) 
                            res.append(ttt);
                        offTmp.length = 0;
                    }
                    else 
                        offTmp.append(ch);
                }
                else {
                    offTmp.append(ch);
                    if ((ch.charCodeAt(0)) === 0x13) 
                        off++;
                }
                continue;
            }
            if ((ch.charCodeAt(0)) === 0x13) {
                if (off === 0) 
                    offTmp.length = 0;
                off++;
            }
            else if ((ch.charCodeAt(0)) === 0xD || ch === '\v') {
                res.append("\r\n");
                lf++;
            }
            else if ((ch.charCodeAt(0)) === 0xC) {
                res.append("\r\n\r\n\r\n");
                lf += 3;
            }
            else if (Utils.isWhitespace(ch) || (ch.charCodeAt(0)) > 0x20 || (ch.charCodeAt(0)) === 7) {
                if (ch === '\n') {
                    if (res.length === 0 || res.charAt(res.length - 1) !== '\r') 
                        res.append('\r');
                }
                res.append(ch);
                if (!Utils.isWhitespace(ch)) 
                    lf = 0;
            }
            else if ((ch.charCodeAt(0)) === 3 || (ch.charCodeAt(0)) === 4) 
                break;
            else {
            }
        }
        return res.toString();
    }
    
    static extractSpecText(txt) {
        txt = Utils.trimStartString(txt);
        if (txt.startsWith("HYPERLINK")) {
            let i1 = txt.indexOf("PAGEREF");
            if (i1 > 0) {
                for (let ii = i1 - 1; ii >= 0; ii--) {
                    if ((txt.charCodeAt(ii)) === 0x14 || (txt.charCodeAt(ii)) === 0x1) {
                        txt = txt.substring(ii + 1, ii + 1 + i1 - ii - 1).trim();
                        return txt + "\n";
                    }
                }
            }
            let i = txt.lastIndexOf(String.fromCharCode(0x14));
            if (i < 0) 
                i = txt.lastIndexOf(String.fromCharCode(0x1));
            if (i > 0 && (i < txt.length)) {
                txt = txt.substring(i + 1);
                return txt;
            }
            return null;
        }
        if (txt.startsWith("TOC")) {
            let ii = txt.indexOf("HYPERLINK");
            if (ii > 0) 
                return MSOfficeHelper.extractSpecText(txt.substring(ii));
            let res = new StringBuilder();
            let treg = false;
            for (const ch of txt) {
                if ((ch.charCodeAt(0)) === 0x14 || (ch.charCodeAt(0)) === 0x15) 
                    treg = true;
                else if ((ch.charCodeAt(0)) === 0x13) 
                    treg = false;
                else if (treg) {
                    if ((ch.charCodeAt(0)) === 0xD) 
                        res.append("\r\n");
                    else if (ch === '\v' || (ch.charCodeAt(0)) === 7) 
                        res.append("  ");
                    else 
                        res.append(ch);
                }
            }
            return res.toString();
        }
        return null;
    }
}


module.exports = MSOfficeHelper