/*
 * 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 Hashtable = require("./../../../unisharp/Hashtable");
const Stream = require("./../../../unisharp/Stream");
const MemoryStream = require("./../../../unisharp/MemoryStream");
const XmlDocument = require("./../../../unisharp/XmlDocument");

const UnitextImage = require("./../../UnitextImage");
const UnitextPagebreak = require("./../../UnitextPagebreak");
const CreateDocumentParam = require("./../../CreateDocumentParam");
const UnitextItem = require("./../../UnitextItem");
const FileFormat = require("./../../FileFormat");
const MyZipFile = require("./MyZipFile");
const UnitextContainer = require("./../../UnitextContainer");
const UnitextDocument = require("./../../UnitextDocument");
const UnitextPagesectionItem = require("./../../UnitextPagesectionItem");
const UnitextPagesection = require("./../../UnitextPagesection");
const HtmlHelper = require("./../html/HtmlHelper");

class EpubHelper {
    
    static createDoc(fileName, content, pars) {
        let zip = new MyZipFile(fileName, content);
        let doc = UnitextDocument._new69(fileName, FileFormat.EPUB);
        doc.content = new UnitextContainer();
        try {
            let textEntries = new Hashtable();
            let itemsOrder = new Array();
            let imagesEntries = new Hashtable();
            for (const entry of zip.entries) {
                if (Utils.endsWithString(entry.name, "content.opf", true)) {
                    let xml = new XmlDocument();
                    let dat = entry.getData();
                    if (dat === null) 
                        continue;
                    let documentXml = new MemoryStream(dat); 
                    try {
                        xml.preserve_whitespace = true;
                        xml.loadStream(documentXml);
                        documentXml.close();
                    }
                    finally {
                        documentXml.close();
                    }
                    for (const x of xml.document_element.child_nodes) {
                        if (x.local_name === "manifest") {
                            for (const xx of x.child_nodes) {
                                if (xx.local_name === "item") {
                                    let typ = null;
                                    let id = null;
                                    let href = null;
                                    if (xx.attributes !== null) {
                                        for (const a of xx.attributes) {
                                            if (a.local_name === "id") 
                                                id = a.value;
                                            else if (a.local_name === "href") 
                                                href = a.value;
                                            else if (a.local_name === "media-type") 
                                                typ = a.value;
                                        }
                                    }
                                    if (typ === null || href === null) 
                                        continue;
                                    if (typ.startsWith("application") && typ.includes("xhtml")) {
                                        if (!textEntries.containsKey(href)) 
                                            textEntries.put(href, null);
                                        itemsOrder.push(href);
                                    }
                                    else if (typ.startsWith("image/")) {
                                        if (!imagesEntries.containsKey(href)) 
                                            imagesEntries.put(href, null);
                                    }
                                }
                            }
                        }
                        else if (x.local_name === "metadata") {
                            for (const xxx of x.child_nodes) {
                                if (xxx.local_name === "title") {
                                    if (!doc.attrs.containsKey("title")) 
                                        doc.attrs.put("title", xxx.inner_text);
                                }
                                else if (xxx.local_name === "creator") {
                                    let isAuth = false;
                                    if (xxx.attributes !== null) {
                                        for (const a of xxx.attributes) {
                                            if (a.local_name === "role") {
                                                if (a.value === "aut") 
                                                    isAuth = true;
                                            }
                                        }
                                    }
                                    if (isAuth) {
                                        if (!doc.attrs.containsKey("author")) 
                                            doc.attrs.put("author", xxx.inner_text);
                                    }
                                }
                            }
                        }
                    }
                }
            }
            let buf = new Uint8Array(100000);
            for (const entry of zip.entries) {
                let txt = null;
                for (const kp of textEntries.entries) {
                    if (entry.name.endsWith(kp.key)) {
                        txt = kp.key;
                        break;
                    }
                }
                if (txt === null) 
                    continue;
                if (txt.includes("annotation") || txt.includes("about") || txt.includes("info")) 
                    continue;
                try {
                    let dat = entry.getData();
                    let nod = HtmlHelper.createNode(null, dat, null);
                    if (nod === null) 
                        continue;
                    let doc0 = HtmlHelper.create(nod, null, null, new CreateDocumentParam());
                    if (doc0 !== null && doc0.content !== null) {
                        if (txt.includes("title")) {
                            doc.sections.push(new UnitextPagesection());
                            doc.sections[0].items.push(UnitextPagesectionItem._new48(doc0.content));
                        }
                        else 
                            textEntries.put(txt, doc0.content);
                    }
                } catch (ex) {
                }
            }
            let cnt = Utils.as(doc.content, UnitextContainer);
            for (const key of itemsOrder) {
                if (textEntries.containsKey(key)) {
                    let ccc = textEntries.get(key);
                    if (ccc === null) 
                        continue;
                    if (Utils.endsWithString(key, "TOC.NCX", true)) 
                        continue;
                    if (key.toUpperCase().includes("CONTENT.")) 
                        continue;
                    if (cnt.children.length > 0) 
                        cnt.children.push(new UnitextPagebreak());
                    if (ccc instanceof UnitextContainer) 
                        cnt.children.splice(cnt.children.length, 0, ...ccc.children);
                    else 
                        cnt.children.push(ccc);
                }
            }
            let its = new Array();
            doc.getAllItems(its, 0);
            for (const entry of zip.entries) {
                if (pars.onlyForPureText) 
                    break;
                let img = null;
                for (const it of its) {
                    if (it instanceof UnitextImage) {
                        if (entry.name.endsWith(it.id)) {
                            img = Utils.as(it, UnitextImage);
                            break;
                        }
                    }
                }
                if (img === null) 
                    continue;
                img.content = entry.getData();
            }
        } finally {
            if (zip !== null) 
                zip.close();
        }
        doc.optimize(false, null);
        return doc;
    }
}


module.exports = EpubHelper