/*
 * 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 MiscHelper = require("./../../../util/MiscHelper");
const PdfObject = require("./PdfObject");
const PdfReference = require("./PdfReference");

class PdfArray extends PdfObject {
    
    constructor() {
        super();
        this.m_Items = new Array();
    }
    
    get itemsCount() {
        return this.m_Items.length;
    }
    
    getItem(ind, keepRef = false) {
        if ((ind < 0) || ind >= this.m_Items.length) 
            return null;
        if ((this.m_Items[ind] instanceof PdfReference) && !keepRef) {
            let obj = this.sourceFile.getObject(this.m_Items[ind].id);
            if (obj === null) 
                return null;
            this.m_Items[ind] = obj;
        }
        return this.m_Items[ind];
    }
    
    removeItem(ind) {
        if (ind >= 0 && (ind < this.m_Items.length)) 
            this.m_Items.splice(ind, 1);
    }
    
    isSimple(lev) {
        if (this.m_Items.length > 10 || lev > 5) 
            return false;
        for (let i = 0; i < this.m_Items.length; i++) {
            let it = this.getItem(i, false);
            if (it !== null && !it.isSimple(lev + 1)) 
                return false;
        }
        return true;
    }
    
    add(obj) {
        this.m_Items.push(obj);
    }
    
    clear() {
        this.m_Items.splice(0, this.m_Items.length);
    }
    
    toStringEx(lev) {
        if (lev > 10) 
            return ("[..." + this.itemsCount + "]");
        let res = new StringBuilder();
        res.append("[");
        let i = 0;
        for (i = 0; i < this.m_Items.length; i++) {
            if (i > 0) 
                res.append(", ");
            if (res.length > 100) 
                break;
            let it = this.getItem(i, false);
            if (it === null) 
                res.append("NULL");
            else if (!it.isSimple(lev + 1)) 
                break;
            else {
                let str = it.toStringEx(lev + 1);
                if (str.length < 20) {
                    res.append(str);
                    continue;
                }
                else 
                    break;
            }
        }
        if (i < this.m_Items.length) 
            res.append("... ").append(this.m_Items.length);
        res.append("]");
        return res.toString();
    }
    
    outHtml(res) {
        const PdfDictionary = require("./PdfDictionary");
        res.append("<b>[</b> ");
        for (let i = 0; i < this.itemsCount; i++) {
            let o = this.getItem(i, false);
            if (o === null) {
                res.append("null");
                continue;
            }
            if (o.id > 0) 
                res.append("<a href=\"obj").append(o.id).append("\">");
            MiscHelper.correctHtmlValue(res, o.toString(), false, false, false);
            if (o.id > 0) 
                res.append("</a>");
            if ((i + 1) < this.itemsCount) {
                res.append(", ");
                if ((o instanceof PdfDictionary) || (o instanceof PdfArray)) 
                    res.append("<br/>");
            }
        }
        res.append("<b> ]</b>");
        this._outHtmlRefs(res);
    }
    
    postParse(stream) {
        this.m_Items.splice(0, this.m_Items.length);
        let p0 = stream.position;
        let ch = stream.readByte();
        if ((String.fromCharCode(ch)) !== '[') 
            return;
        while (true) {
            let i = stream.peekSolidByte();
            if (i < 0) 
                break;
            ch = i;
            if ((String.fromCharCode(ch)) === ']') {
                stream.position = stream.position + 1;
                return;
            }
            let obj = stream.parseObject(this.sourceFile, false);
            if (obj === null) 
                break;
            this.m_Items.push(obj);
        }
    }
    
    getDouble() {
        if (this.m_Items.length < 1) 
            return 0;
        let it = this.getItem(0, false);
        if (it === null) 
            return 0;
        return it.getDouble();
    }
    
    write(s) {
        s.writeByte('['.charCodeAt(0));
        for (let i = 0; i < this.m_Items.length; i++) {
            if (i > 0) 
                s.writeByte(' '.charCodeAt(0));
            let it = this.getItem(i, false);
            if (it === null) 
                continue;
            if (it.deleted) 
                continue;
            if (it.id === 0) 
                it.write(s);
            else {
                let buf = Utils.encodeString("ASCII", (String(it.writeId) + " 0 R"));
                s.write(buf, 0, buf.length);
            }
        }
        s.writeByte(']'.charCodeAt(0));
    }
    
    getAllReferences(refs, ids) {
        if (this.id > 0) {
            if (ids.includes(this.id)) 
                return;
            ids.push(this.id);
        }
        for (let i = 0; i < this.itemsCount; i++) {
            let o = this.getItem(i, true);
            if (o !== null) 
                o.getAllReferences(refs, ids);
        }
        if (this.id > 0) 
            Utils.removeItem(ids, this.id);
    }
    
    getAllWhoRefObject(objId, cur, res, ids) {
        if (this.id > 0) {
            if (ids.includes(this.id)) 
                return;
            ids.push(this.id);
            cur = this;
        }
        for (let i = 0; i < this.itemsCount; i++) {
            let o = this.getItem(i, true);
            if (o !== null && o.id === objId) {
                if (!res.includes(cur)) 
                    res.push(cur);
            }
            else if (o !== null && o.id === 0) 
                o.getAllWhoRefObject(objId, cur, res, ids);
        }
        if (this.id > 0) 
            Utils.removeItem(ids, this.id);
    }
}


module.exports = PdfArray