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

const PdfImage = require("./PdfImage");
const PdfText = require("./PdfText");
const UnitextContainer = require("./../../UnitextContainer");
const UnitextPagebreak = require("./../../UnitextPagebreak");
const UnitextPlaintext = require("./../../UnitextPlaintext");
const UnitextNewline = require("./../../UnitextNewline");
const UnilayoutHelper = require("./../uni/UnilayoutHelper");
const UnitextDocument = require("./../../UnitextDocument");
const PdfFile = require("./PdfFile");
const FileFormat = require("./../../FileFormat");
const PdfFig = require("./PdfFig");
const UnilayRectangle = require("./../../UnilayRectangle");
const UnilayPage = require("./../../UnilayPage");
const PdfPage = require("./PdfPage");

/**
 * Работа с PDF
 */
class PdfHelper {
    
    static createUni(pdfFileName, fileContent, pars) {
        let pages = new Array();
        let doc = UnitextDocument._new47(FileFormat.PDF);
        try {
            let file = new PdfFile(); 
            try {
                file.open(pdfFileName, fileContent);
                if (file.encrypt !== null) 
                    doc.errorMessage = "Can't extract pages from encrypted pdf";
                if (file.rootObject !== null) {
                    let mt = file.rootObject.getDictionary("Metadata", null);
                    if (mt !== null) {
                        let dat = mt.extractData();
                        if (dat !== null) {
                            try {
                                let str = Utils.decodeString("UTF-8", dat, 0, -1);
                                let i = str.indexOf("?>");
                                if (i > 0) 
                                    str = str.substring(i + 2).trim();
                                let xml = new XmlDocument();
                                xml.loadXml(str);
                                PdfHelper._readMetadata0(doc, xml.document_element, null);
                            } catch (ex227) {
                            }
                        }
                    }
                }
                if (file.info !== null) {
                    let str = file.info.getStringItem("Title");
                    if (!Utils.isNullOrEmpty(str) && !doc.attrs.containsKey("title")) 
                        doc.attrs.put("title", str);
                    str = file.info.getStringItem("Author");
                    if (!Utils.isNullOrEmpty(str) && !doc.attrs.containsKey("author")) 
                        doc.attrs.put("author", str);
                }
                for (let ii = 0; ii < file.pages.length; ii++) {
                    if (pars !== null) 
                        pars.progress(Utils.intDiv(ii * 100, file.pages.length));
                    let pdic = file.pages[ii];
                    let pPage = new PdfPage(pdic);
                    let up = new UnilayPage();
                    up.width = Math.floor(pPage.width);
                    up.height = Math.floor(pPage.height);
                    pages.push(up);
                    up.number = pages.length;
                    let imgs = new Array();
                    for (const it of pPage.items) {
                        if (it instanceof PdfFig) 
                            continue;
                        let r = new UnilayRectangle();
                        r.left = it.left;
                        r.top = it.top;
                        r.right = it.right;
                        r.bottom = it.bottom;
                        r.page = up;
                        if (it instanceof PdfText) 
                            r.text = it.text;
                        else if (it instanceof PdfImage) {
                            r.imageContent = it.content;
                            r.tag = it;
                            imgs.push(r);
                        }
                        up.rects.push(r);
                    }
                    if (up.imageContent === null && imgs.length > 0 && imgs[0].imageContent !== null) {
                        let ok = up.rects.length === 1;
                        if (!ok || imgs.length > 1) {
                            if (Math.abs((((imgs[0].right - imgs[0].left - (up.width))) / (up.width))) < 0.2) 
                                ok = true;
                        }
                        if (ok) {
                            up.imageContent = imgs[0].imageContent;
                            Utils.removeItem(up.rects, imgs[0]);
                        }
                    }
                }
            }
            finally {
                file.close();
            }
        } catch (ex) {
            doc.errorMessage = ex.message;
            return doc;
        }
        if (pages === null || pages.length === 0 || doc.errorMessage !== null) {
            if (doc.errorMessage === null) 
                doc.errorMessage = "Can't extract pages from pdf-file";
            return doc;
        }
        doc.pages = pages;
        UnilayoutHelper.createContentFromPages(doc, false);
        let cnt = Utils.as(doc.content, UnitextContainer);
        if (cnt === null) 
            return doc;
        for (let i = 0; i < cnt.children.length; i++) {
            let pt = Utils.as(cnt.children[i], UnitextPlaintext);
            if (pt === null) 
                continue;
            if (!pt.isWhitespaces) 
                continue;
            if (i === 0 || (cnt.children[i - 1] instanceof UnitextNewline) || (cnt.children[i - 1] instanceof UnitextPagebreak)) {
            }
            else 
                continue;
            if ((i + 1) === cnt.children.length || (cnt.children[i + 1] instanceof UnitextNewline) || (cnt.children[i + 1] instanceof UnitextPagebreak)) {
            }
            else 
                continue;
            cnt.children.splice(i, 1);
            i--;
        }
        doc.content = doc.content.optimize(true, null);
        return doc;
    }
    
    static _readMetadata0(doc, xml, typ) {
        for (const x of xml.child_nodes) {
            if (x.local_name === "title") 
                PdfHelper._readMetadata0(doc, x, "title");
            else if (x.local_name === "creator") 
                PdfHelper._readMetadata0(doc, x, "author");
            else if (x.local_name === "subject") 
                PdfHelper._readMetadata0(doc, x, "subject");
            else if (x.local_name === "Keywords") {
                let val = x.inner_text;
                if (!Utils.isNullOrEmpty(val) && !doc.attrs.containsKey("keywords")) 
                    doc.attrs.put("keywords", val);
            }
            else if (typ !== null && x.local_name === "li" && !Utils.isNullOrEmpty(x.inner_text)) {
                let txt = x.inner_text;
                if (!doc.attrs.containsKey(typ)) 
                    doc.attrs.put(typ, txt);
                else 
                    doc.attrs.put(typ, (doc.attrs.get(typ) + "; " + txt));
            }
            else 
                PdfHelper._readMetadata0(doc, x, typ);
        }
    }
}


module.exports = PdfHelper