/*
 * 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.util;

/**
 * Поддержка OCR (запросы к внешнему серверу OCR.Server.exe)
 */
public class OCRService {

    /**
     * Адрес сервера (необходимо устанавливать сначала)
     */
    public static String URI;

    /**
     * Запрос к серверу, жив ли он
     * @return null, если недоступен, иначе строка "C" (при поддержке CuneiForm) и + "M" (при поддержке Modi)
     */
    public static String checkServer() throws Exception {
        if (URI == null) 
            throw new Exception("Uri not defined");
        _corrUri();
        try {
            com.pullenti.unisharp.Webclient web = new com.pullenti.unisharp.Webclient();
            byte[] dat = web.downloadData(URI);
            if (dat != null) 
                return com.pullenti.unisharp.Utils.decodeCharset(java.nio.charset.Charset.forName("UTF-8"), dat, 0, -1);
        } catch (Exception ex) {
        }
        return null;
    }

    private static void _corrUri() {
        if (URI == null) 
            return;
        if (!URI.startsWith("http")) 
            URI = "http://" + URI;
        if (!URI.endsWith("/")) 
            URI += "/";
    }

    /**
     * Проверить, что страница нуждается в распознавании (содержит картинку и не содержит текста)
     * @param page страница с картинкой в page.ImageContent)
     * @return при true страница нуждается в распознавании
     */
    public static boolean checkPageNeedOCR(com.pullenti.unitext.UnilayPage page) {
        if (page == null) 
            return false;
        if (page.imageContent == null || (page.imageContent.length < 10)) 
            return false;
        if (page.rects.size() == 0) 
            return true;
        int chars = 0;
        int digs = 0;
        int punkts = 0;
        for (com.pullenti.unitext.UnilayRectangle r : page.rects) {
            if (r.text != null) {
                for (char ch : r.text.toCharArray()) {
                    if (Character.isLetter(ch)) 
                        chars++;
                    else if (Character.isDigit(ch)) 
                        digs++;
                    else if (!com.pullenti.unisharp.Utils.isWhitespace(ch)) 
                        punkts++;
                }
            }
        }
        if (punkts > chars) 
            return true;
        if (chars < 20) 
            return true;
        return false;
    }

    /**
     * Распознать текст с картинки страницы
     * @param page страница с картинкой в page.ImageContent)
     * @param rotate нужно ли вращать (по умолчанию, нет)
     * @param quick при true быстрый способ, но ниже качество (не задействуется второй движок)
     * @return при true результат запишется в page.Rects
     */
    public static boolean process(com.pullenti.unitext.UnilayPage page, boolean rotate, boolean quick) throws Exception, InterruptedException, javax.xml.stream.XMLStreamException, java.io.IOException, org.xml.sax.SAXException {
        if (URI == null) 
            throw new Exception("Uni not defined");
        if (page == null || page.imageContent == null || (page.imageContent.length < 10)) 
            throw new Exception("Page image not defined");
        _corrUri();
        com.pullenti.unisharp.Webclient web = new com.pullenti.unisharp.Webclient();
        byte[] dat = web.uploadData((URI + "?oper=start&rotate=" + (rotate ? "true" : "false") + "&quick=" + (quick ? "true" : "false")), page.imageContent);
        if (dat == null) 
            return false;
        String str = com.pullenti.unisharp.Utils.decodeCharset(java.nio.charset.Charset.forName("UTF-8"), dat, 0, -1);
        if (com.pullenti.unisharp.Utils.startsWithString(str, "ERROR:", true)) 
            throw new Exception(str.substring(6).trim());
        String id = str;
        while (true) {
            Thread.sleep(1000L);
            dat = web.downloadData((URI + "?oper=status&task=" + id));
            str = com.pullenti.unisharp.Utils.decodeCharset(java.nio.charset.Charset.forName("UTF-8"), dat, 0, -1);
            if (com.pullenti.unisharp.Utils.startsWithString(str, "ERROR:", true)) 
                throw new Exception(str.substring(6).trim());
            if (com.pullenti.unisharp.Utils.stringsEq(str, "completed")) 
                break;
        }
        dat = web.downloadData((URI + "?oper=result&task=" + id));
        str = com.pullenti.unisharp.Utils.decodeCharset(java.nio.charset.Charset.forName("UTF-8"), dat, 0, -1);
        if (com.pullenti.unisharp.Utils.startsWithString(str, "ERROR:", true)) {
            str = str.substring(6).trim();
            if (com.pullenti.unisharp.Utils.startsWithString(str, "no recognized text", true)) 
                return false;
            throw new Exception(str.substring(6).trim());
        }
        com.pullenti.unisharp.XmlDocumentWrapper xml = new com.pullenti.unisharp.XmlDocumentWrapper();
        xml.doc = xml.db.parse(new org.xml.sax.InputSource(new java.io.StringReader(str)));
        com.pullenti.unitext.UnilayPage page0 = new com.pullenti.unitext.UnilayPage();
        page0.restore(xml.doc.getDocumentElement());
        if (page0.rects.size() == 0) 
            return false;
        page.rects = page0.rects;
        return true;
    }
    public OCRService() {
    }
}
