/*
 * 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
 */

package com.pullenti.unitext;

/**
 * Страница тексто-графического слоя
 */
public class UnilayPage {

    /**
     * Порядковый номер (от 1)
     */
    public int number;

    /**
     * Ширина в условных единицах
     */
    public int width;

    /**
     * Высота в условных единицах
     */
    public int height;

    /**
     * Содержимое картинки всей страницы (если есть)
     */
    public byte[] imageContent;

    /**
     * Прямоугольники с текстами и картинками - список UnilayRectangle.
     */
    public java.util.ArrayList<UnilayRectangle> rects = new java.util.ArrayList<UnilayRectangle>();

    /**
     * Номер с верхнего колонтитула (если есть)
     */
    public int topNumber;

    /**
     * Номер с нижнего колонтитула (если есть)
     */
    public int bottomNumber;

    /**
     * Заголовок (не выделяется из документа, а устанавливается программно - для красоты)
     */
    public String pageTitle;

    /**
     * Используется произвольным образом
     */
    public Object tag;

    @Override
    public String toString() {
        return ("Page " + number + " (" + width + "x" + height + ")" + (imageContent == null ? "" : " has image"));
    }

    public void getXml(com.pullenti.unisharp.XmlWriterWrapper xml) throws javax.xml.stream.XMLStreamException {
        xml.wr.writeStartElement("page");
        if (number > 0) 
            xml.wr.writeAttribute("number", ((Integer)number).toString());
        if (topNumber > 0) 
            xml.wr.writeAttribute("topnumber", ((Integer)topNumber).toString());
        if (bottomNumber > 0) 
            xml.wr.writeAttribute("bottomnumber", ((Integer)bottomNumber).toString());
        if (width > 0) 
            xml.wr.writeAttribute("width", ((Integer)width).toString());
        if (height > 0) 
            xml.wr.writeAttribute("height", ((Integer)height).toString());
        if (imageContent != null) 
            xml.writeElementString("image", new String(java.util.Base64.getEncoder().encode(imageContent)));
        for (UnilayRectangle r : rects) {
            r.getXml(xml);
        }
        xml.wr.writeEndElement();
    }

    public void restore(org.w3c.dom.Node xml) {
        double d;
        if (xml.getAttributes() != null) {
            for (org.w3c.dom.Node a : (new com.pullenti.unisharp.XmlAttrListWrapper(xml.getAttributes())).arr) {
                if (com.pullenti.unisharp.Utils.stringsEq(com.pullenti.unisharp.Utils.getXmlLocalName(a), "number")) {
                    int i;
                    com.pullenti.unisharp.Outargwrapper<Integer> wrapi566 = new com.pullenti.unisharp.Outargwrapper<Integer>();
                    boolean inoutres567 = com.pullenti.unisharp.Utils.parseInteger(a.getNodeValue(), 0, null, wrapi566);
                    i = (wrapi566.value != null ? wrapi566.value : 0);
                    if (inoutres567) 
                        number = i;
                }
                else if (com.pullenti.unisharp.Utils.stringsEq(com.pullenti.unisharp.Utils.getXmlLocalName(a), "topnumber")) {
                    int i;
                    com.pullenti.unisharp.Outargwrapper<Integer> wrapi568 = new com.pullenti.unisharp.Outargwrapper<Integer>();
                    boolean inoutres569 = com.pullenti.unisharp.Utils.parseInteger(a.getNodeValue(), 0, null, wrapi568);
                    i = (wrapi568.value != null ? wrapi568.value : 0);
                    if (inoutres569) 
                        topNumber = i;
                }
                else if (com.pullenti.unisharp.Utils.stringsEq(com.pullenti.unisharp.Utils.getXmlLocalName(a), "bottomnumber")) {
                    int i;
                    com.pullenti.unisharp.Outargwrapper<Integer> wrapi570 = new com.pullenti.unisharp.Outargwrapper<Integer>();
                    boolean inoutres571 = com.pullenti.unisharp.Utils.parseInteger(a.getNodeValue(), 0, null, wrapi570);
                    i = (wrapi570.value != null ? wrapi570.value : 0);
                    if (inoutres571) 
                        bottomNumber = i;
                }
                else if (com.pullenti.unisharp.Utils.stringsEq(com.pullenti.unisharp.Utils.getXmlLocalName(a), "width")) {
                    int i;
                    com.pullenti.unisharp.Outargwrapper<Integer> wrapi572 = new com.pullenti.unisharp.Outargwrapper<Integer>();
                    boolean inoutres573 = com.pullenti.unisharp.Utils.parseInteger(a.getNodeValue(), 0, null, wrapi572);
                    i = (wrapi572.value != null ? wrapi572.value : 0);
                    if (inoutres573) 
                        width = i;
                }
                else if (com.pullenti.unisharp.Utils.stringsEq(com.pullenti.unisharp.Utils.getXmlLocalName(a), "height")) {
                    int i;
                    com.pullenti.unisharp.Outargwrapper<Integer> wrapi574 = new com.pullenti.unisharp.Outargwrapper<Integer>();
                    boolean inoutres575 = com.pullenti.unisharp.Utils.parseInteger(a.getNodeValue(), 0, null, wrapi574);
                    i = (wrapi574.value != null ? wrapi574.value : 0);
                    if (inoutres575) 
                        height = i;
                }
            }
        }
        for (org.w3c.dom.Node x : (new com.pullenti.unisharp.XmlNodeListWrapper(xml.getChildNodes())).arr) {
            if (com.pullenti.unisharp.Utils.stringsEq(com.pullenti.unisharp.Utils.getXmlLocalName(x), "rect")) {
                UnilayRectangle r = UnilayRectangle._new576(this);
                r.restore(x);
                rects.add(r);
            }
            else if (com.pullenti.unisharp.Utils.stringsEq(com.pullenti.unisharp.Utils.getXmlLocalName(x), "image")) 
                imageContent = java.util.Base64.getDecoder().decode((x.getTextContent()).replace("\r", "").replace("\n", ""));
        }
    }

    /**
     * Найти по координате накрывающий её прямоугольник
     * @param x 
     * @param y 
     * @return 
     */
    public UnilayRectangle findRect(double x, double y) {
        for (UnilayRectangle r : rects) {
            if ((r.left <= x && x <= r.right && r.top <= y) && y <= r.bottom) 
                return r;
        }
        return null;
    }

    // Объединить результат распознавания с распознаванием страницы другим движком,
    // взяв наилучшие Rects по их качеству Quality.
    // page - страница с таким же изображением</param>
    public void mergeRectsByQuality(UnilayPage page) {
        for (UnilayRectangle r : page.rects) {
            r.tag = null;
        }
        int maxLine = 0;
        for (UnilayRectangle r : rects) {
            if (r.lineNumber > maxLine) 
                maxLine = r.lineNumber;
            UnilayRectangle rr = page.findRect(((r.left + r.right)) / (2.0), ((r.top + r.bottom)) / (2.0));
            if (rr == null) 
                continue;
            rr.tag = r;
            if ((r.quality.value()) >= (rr.quality.value())) 
                continue;
            r.text = rr.text;
            r.quality = rr.quality;
            r.left = rr.left;
            r.top = rr.top;
            r.right = rr.right;
            r.bottom = rr.bottom;
        }
    }

    public static UnilayPage _new158(byte[] _arg1) {
        UnilayPage res = new UnilayPage();
        res.imageContent = _arg1;
        return res;
    }
    public UnilayPage() {
    }
}
