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

const PdfMiscInfo = require("./PdfMiscInfo");
const PdfName = require("./PdfName");
const PdfBoolValue = require("./PdfBoolValue");
const PdfRect = require("./PdfRect");
const PdfText = require("./PdfText");
const PdfArray = require("./PdfArray");
const IPdfDictionaryWrapper = require("./IPdfDictionaryWrapper");
const PdfImage = require("./PdfImage");
const PdfStream = require("./PdfStream");
const PdfPathState = require("./PdfPathState");
const Matrix = require("./Matrix");
const PdfFont = require("./PdfFont");
const PdfTextState = require("./PdfTextState");

class PdfPage extends PdfRect {
    
    get dic() {
        return this._dic;
    }
    set dic(value) {
        this._dic = value;
        return this._dic;
    }
    
    constructor(__dic, state0 = null, storeLexems = false, ignoreImages = false) {
        super();
        this._dic = null;
        this.lexems = null;
        this.subpages = null;
        this.lexemContent = null;
        this.items = new Array();
        this.imgs = new Array();
        this.beginPos = 0;
        this.endPos = 0;
        this.dic = __dic;
        __dic.obj = this;
        let crop = Utils.as(__dic.getObject("CropBox", false), PdfArray);
        if (crop === null) 
            crop = Utils.as(__dic.getObject("TrimBox", false), PdfArray);
        if (crop === null) 
            crop = Utils.as(__dic.getObject("MediaBox", false), PdfArray);
        if (crop === null) 
            crop = Utils.as(__dic.getObject("BBox", false), PdfArray);
        if (crop === null) {
            if (__dic.sourceFile.rootObject !== null) {
                let pages = __dic.sourceFile.rootObject.getDictionary("Pages", null);
                if (pages !== null) {
                    crop = Utils.as(pages.getObject("MediaBox", false), PdfArray);
                    if (crop === null) 
                        crop = Utils.as(pages.getObject("TrimBox", false), PdfArray);
                    if (crop === null) 
                        crop = Utils.as(pages.getObject("CropBox", false), PdfArray);
                }
            }
        }
        if (crop !== null && crop.itemsCount === 4) {
            this.x2 = crop.getItem(2, false).getDouble();
            this.y2 = crop.getItem(3, false).getDouble();
            let rot = __dic.getObject("Rotate", false);
            if (rot !== null && ((rot.getDouble() === 90 || rot.getDouble() === 270))) {
                let xx = this.x2;
                this.x2 = this.y2;
                this.y2 = xx;
            }
        }
        let res = this.dic.getDictionary("Resources", null);
        let fnts = (res === null ? null : res.getDictionary("Font", null));
        let _imgs = (res === null ? null : res.getDictionary("XObject", null));
        let val = this.dic.getTotalDataStream("Contents");
        if (val === null && ((state0 !== null || this.dic.isTypeItem("XObject")))) 
            val = this.dic.extractData();
        if (val === null || (val.length < 1)) 
            return;
        let lex = null;
        let pstr = new PdfStream(null, val); 
        try {
            lex = pstr.parseContent();
        }
        finally {
            pstr.close();
        }
        if (storeLexems) {
            this.lexems = lex;
            this.lexemContent = val;
        }
        let allFonts = new Hashtable();
        let state = Utils.as(state0, PdfTextState);
        if (state === null) {
            state = new PdfTextState();
            state.boxHeight = this.y2;
        }
        else {
            let mat = Utils.as(__dic.getObject("Matrix", false), PdfArray);
            if (mat !== null && mat.itemsCount === 6) {
                let m = new Matrix();
                m.set(mat.getItem(0, false).getDouble(), mat.getItem(1, false).getDouble(), mat.getItem(2, false).getDouble(), mat.getItem(3, false).getDouble(), mat.getItem(4, false).getDouble(), mat.getItem(5, false).getDouble());
                if (state.ctmStack.length > 0) {
                    m.multiply(state.ctmStack[0]);
                    state.ctmStack[0] = m;
                }
            }
        }
        let textRegime = false;
        let buf = new StringBuilder();
        let path = new PdfPathState(this);
        for (let i = 0; i < lex.length; i++) {
            if (!(lex[i] instanceof PdfName)) 
                continue;
            let nam = lex[i].name;
            if (nam === "ET") {
                textRegime = false;
                continue;
            }
            if (nam === "BT") {
                textRegime = true;
                state.tm.init();
                state.tlm.init();
                continue;
            }
            if (nam === "Do" && (lex[i - 1] instanceof PdfName)) {
                nam = lex[i - 1].name;
                let xobjs = (res === null ? null : res.getDictionary("XObject", null));
                let xobj = (xobjs === null ? null : xobjs.getDictionary(nam, null));
                if (xobj === null) {
                    for (const rr of __dic.sourceFile.allResources) {
                        if (rr.getStringItem("Name") === nam) {
                            xobj = rr;
                            break;
                        }
                    }
                }
                if (xobj !== null) {
                    let sub = Utils.as(xobj.getObject("Subtype", false), PdfName);
                    if (sub !== null && sub.name === "Image") {
                        lex[i].tag = xobj;
                        this.imgs.push(PdfMiscInfo._new232(xobj, lex[i - 1].readPos, ((lex[i].readPos) + lex[i].readLen) - 1, nam));
                        let im = Utils.as(xobj.getObject("ImageMask", false), PdfBoolValue);
                        if (im !== null && im.val) {
                        }
                        else {
                            let img = new PdfImage(xobj, false, (state === null ? null : state.fillColor), ignoreImages);
                            lex[i].tag = img;
                            if (state.ctmStack.length > 0) {
                                img.x1 = (img.x2 = state.ctmStack[0].E);
                                img.x2 += state.ctmStack[0].A;
                                img.y1 = (img.y2 = state.boxHeight - state.ctmStack[0].F);
                                img.y1 -= state.ctmStack[0].D;
                                if (((img.y1 < -0.1) || img.y2 > this.y2 || (img.x1 < -0.1)) || img.x2 > this.x2) {
                                }
                            }
                            this.items.push(img);
                            if (storeLexems) 
                                this.imgs[this.imgs.length - 1].tag = img;
                        }
                    }
                    else {
                        let ppp = new PdfPage(xobj, state, storeLexems, ignoreImages);
                        if (ppp.items.length === 1 && (ppp.items[0] instanceof PdfImage)) {
                            let img = Utils.as(ppp.items[0], PdfImage);
                            lex[i].tag = img;
                            this.items.push(img);
                            if (storeLexems && ppp.imgs.length === 1) {
                                this.imgs.push(ppp.imgs[0]);
                                this.imgs[this.imgs.length - 1].tag = img;
                            }
                        }
                        else {
                            this.items.splice(this.items.length, 0, ...ppp.items);
                            if (this.subpages === null) 
                                this.subpages = new Array();
                            this.subpages.push(ppp);
                            lex[i].tag = ppp;
                        }
                    }
                }
                continue;
            }
            if (state.parseOne(lex, i)) 
                continue;
            if (path.parseOne(lex, i)) 
                continue;
            if (nam === "Tf" && (lex[i - 2] instanceof PdfName)) {
                state.fontSize = lex[i - 1].getDouble();
                let fnam = lex[i - 2].name;
                if (!allFonts.containsKey(fnam)) {
                    let fff = null;
                    if (fnts !== null) 
                        fff = fnts.getDictionary(fnam, null);
                    if (fff !== null) {
                        if (fff.obj instanceof PdfFont) 
                            state.font = Utils.as(fff.obj, PdfFont);
                        else {
                            state.font = new PdfFont(fff);
                            state.font.alias = fnam;
                        }
                        fff.obj = state.font;
                        allFonts.put(fnam, state.font);
                    }
                }
                else 
                    state.font = allFonts.get(fnam);
                continue;
            }
            if (textRegime && (((nam === "Tj" || nam === "TJ" || nam === "\"") || nam === "'"))) {
                if (state.font === null) 
                    continue;
                if (nam === "\"") {
                    state.charSpace = lex[i - 2].getDouble();
                    state.wordSpace = lex[i - 3].getDouble();
                }
                if (nam === "\"" || nam === "'") 
                    state.newline();
                let txt = state.font.extractText(lex[i - 1], state);
                if (txt !== null) {
                    this.items.push(txt);
                    lex[i].tag = txt;
                }
                continue;
            }
        }
        if (this.y2 > 0) {
            for (const it of this.items) {
                for (let k = 0; (k < 1000) && it.y1 > this.y2; k++) {
                    it.y1 -= this.y2;
                    it.y2 -= this.y2;
                }
            }
        }
        if (!storeLexems) {
            for (let i = 0; i < (this.items.length - 1); i++) {
                if ((this.items[i] instanceof PdfText) && (this.items[i + 1] instanceof PdfText)) {
                    if (this.items[i].canBeMergedWith(Utils.as(this.items[i + 1], PdfText))) {
                        this.items[i].mergeWith(Utils.as(this.items[i + 1], PdfText));
                        this.items.splice(i + 1, 1);
                        i--;
                    }
                }
            }
        }
        let maxx = 0;
        for (const it of this.items) {
            if (it.right > maxx) 
                maxx = it.right;
        }
        if (maxx > this.x2) {
            let ratio = ((this.x2 - (3))) / maxx;
            for (const it of this.items) {
                it.x1 *= ratio;
                it.x2 *= ratio;
            }
        }
    }
    
    getDataContent() {
        let val = this.dic.getTotalDataStream("Contents");
        if (val === null) 
            val = this.dic.extractData();
        if (val === null || (val.length < 1)) 
            return null;
        return val;
    }
    
    clearDataContents() {
        this.dic.clearTotalDataStream("Contents");
        this.dic.setData(null);
    }
    
    close() {
        this.items.splice(0, this.items.length);
        this.imgs.splice(0, this.imgs.length);
        if (this.lexems !== null) {
            this.lexems.splice(0, this.lexems.length);
            this.lexems = null;
        }
        if (this.subpages !== null) {
            for (const sp of this.subpages) {
                sp.close();
            }
            this.subpages.splice(0, this.subpages.length);
            this.subpages = null;
        }
    }
}


module.exports = PdfPage