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

/**
 * Базовый класс для всех элементов Unitext: 
 * UnitextPlaintext, UnitextContainer, UnitextTable, UnitextTablecell, UnitextList, UnitextListitem, 
 * UnitextNewline, UnitextPagebreak, UnitextFootnote, UnitextImage, UnitextHyperlink, UnitextComment, 
 * UnitextDocblock и UnitextMisc.
 * Базовый класс элементов Unitext
 * 
 */
public class UnitextItem {

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

    /**
     * Начальная позиция в плоском тексте (формируется только после вызова 
     * функции GetPlaintext, причём с SetPositions = true)
     */
    public int beginChar;

    /**
     * Конечная позиция в плоском тексте (формируется только после вызова 
     * функции GetPlaintext, причём с SetPositions = true) 
     * Если EndChar = BeginChar - 1, то элемент занимает нулевую длину.
     */
    public int endChar;

    // Получить первую непробельную позицию
    public int getPlaintextNsPos(String txt) {
        if (txt != null) {
            for (int p = beginChar; p <= endChar && (p < txt.length()); p++) {
                if (!com.pullenti.unisharp.Utils.isWhitespace(txt.charAt(p))) {
                    if (txt.charAt(p) != ((char)7) && txt.charAt(p) != ((char)0x1E) && txt.charAt(p) != ((char)0x1F)) 
                        return p;
                }
            }
        }
        return beginChar;
    }

    // Получить последнюю непробельную позицию
    public int getPlaintextNsPos1(String txt) {
        if (txt != null) {
            for (int p = endChar; p >= 0 && (p < txt.length()); p--) {
                if (!com.pullenti.unisharp.Utils.isWhitespace(txt.charAt(p))) {
                    if (txt.charAt(p) != ((char)7) && txt.charAt(p) != ((char)0x1E) && txt.charAt(p) != ((char)0x1F)) 
                        return p;
                }
            }
        }
        return endChar;
    }

    /**
     * Ссылка на родительский элемент вверх по иерархии
     */
    public UnitextItem parent;

    /**
     * Идентификатор секции (см. Section), если они поддержаны для формата
     */
    public String pageSectionId;

    public UnitextPagesection getPageSection() {
        String _id = null;
        for (UnitextItem it = this; it != null; it = it.parent) {
            if (it.pageSectionId != null && _id == null) 
                _id = it.pageSectionId;
            if (it instanceof UnitextPagesection) 
                return (UnitextPagesection)com.pullenti.unisharp.Utils.cast(it, UnitextPagesection.class);
            UnitextDocument doc = (UnitextDocument)com.pullenti.unisharp.Utils.cast(it, UnitextDocument.class);
            if (doc != null) {
                for (UnitextPagesection s : doc.sections) {
                    if (com.pullenti.unisharp.Utils.stringsEq(s.id, _id)) 
                        return s;
                }
            }
        }
        return null;
    }


    /**
     * Это некоторая дополнительная информация из исходного документа. 
     * Сейчас реализовано для Excel: 
     * - для таблицы помещается строка формата: XLS_SHEET:имя листа 
     * - для ячейки таблицы строка формата: XLS_CELL:имя ячейки (типа E5), 
     * - для квадрата ячеек XLS_CELL:имя ячейки1-имя ячейки2 (типа E5-F10)
     */
    public String sourceInfo = null;

    /**
     * Признак того, что для этого элемента не генерировать html, 
     * а для плоского текста все тексты заменяются на пробелы (по количеству символов). 
     * Устанавливается для служебных таблиц (их текст заменяется на пробелы) и для разных 
     * служебных вставок.
     */
    public boolean ignorable;

    public UnitextItem clone() {
        return null;
    }

    protected void _cloneFrom(UnitextItem it) {
        beginChar = it.beginChar;
        endChar = it.endChar;
        sourceInfo = it.sourceInfo;
        htmlTitle = it.htmlTitle;
        ignorable = it.ignorable;
        id = it.id;
        extData = it.extData;
        pageSectionId = it.pageSectionId;
    }

    /**
     * Сгенерировать плоский текст
     * @param res результат запишет сюда
     * @param pars параметры
     */
    public void getPlaintext(StringBuilder res, GetPlaintextParam pars) {
        if (pars != null && pars.setPositions) 
            beginChar = res.length();
    }

    /**
     * Сгенерировать плоский текст текущего элемента и всех его подэлементов
     * @param pars параметры генерации
     * @return результат
     */
    public String getPlaintextString(GetPlaintextParam pars) {
        return com.pullenti.unitext.internal.uni.UnitextHelper.getPlaintext(this, pars);
    }

    /**
     * Уникальный идентификатор элемента внутри документа 
     * Если не null, то при генерации Html добавляется &lt;a name=Anchor > 
     * для возможной навигации на этот элемент
     */
    public String id;

    /**
     * Это устанавливайте для генерации хинтов в HTML
     */
    public String htmlTitle;

    /**
     * Некоторые внешние данные, ассоциированные с элементом. Не сериализуется. 
     * Устанавливается и используется в конечных приложениях произвольным образом.
     */
    public Object extData;

    /**
     * Сгенерировать HTML
     * @param res результат
     * @param par параметры генерации
     */
    public void getHtml(StringBuilder res, GetHtmlParam par) {
    }

    /**
     * Сгенерировать HTML
     * @param par параметры генерации
     * @return результат
     */
    public String getHtmlString(GetHtmlParam par) {
        StringBuilder res = new StringBuilder();
        this.getHtml(res, par);
        return res.toString();
    }

    public void getXml(com.pullenti.unisharp.XmlWriterWrapper xml) throws javax.xml.stream.XMLStreamException {
        xml.wr.writeStartElement("unknown");
        xml.wr.writeEndElement();
    }

    protected void _writeXmlAttrs(com.pullenti.unisharp.XmlWriterWrapper xml) throws javax.xml.stream.XMLStreamException {
        if (id != null) 
            xml.wr.writeAttribute("id", com.pullenti.util.MiscHelper.correctXmlValue(id));
        if (beginChar > 0 || endChar > 0) {
            xml.wr.writeAttribute("b", ((Integer)beginChar).toString());
            xml.wr.writeAttribute("e", ((Integer)endChar).toString());
        }
        if (htmlTitle != null) 
            xml.wr.writeAttribute("title", com.pullenti.util.MiscHelper.correctXmlValue(htmlTitle));
        if (pageSectionId != null) 
            xml.wr.writeAttribute("section", pageSectionId);
        if (sourceInfo != null) 
            xml.wr.writeAttribute("sourceinfo", com.pullenti.util.MiscHelper.correctXmlValue(sourceInfo));
        if (ignorable) 
            xml.wr.writeAttribute("ignored", "true");
    }

    public void fromXml(org.w3c.dom.Node xml) throws NumberFormatException {
        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), "id")) 
                    id = a.getNodeValue();
                else if (com.pullenti.unisharp.Utils.stringsEq(com.pullenti.unisharp.Utils.getXmlLocalName(a), "b")) 
                    beginChar = com.pullenti.unisharp.Utils.parseInteger(a.getNodeValue(), 0, null);
                else if (com.pullenti.unisharp.Utils.stringsEq(com.pullenti.unisharp.Utils.getXmlLocalName(a), "e")) 
                    endChar = com.pullenti.unisharp.Utils.parseInteger(a.getNodeValue(), 0, null);
                else if (com.pullenti.unisharp.Utils.stringsEq(com.pullenti.unisharp.Utils.getXmlLocalName(a), "l")) 
                    endChar = (beginChar + com.pullenti.unisharp.Utils.parseInteger(a.getNodeValue(), 0, null)) - 1;
                else if (com.pullenti.unisharp.Utils.stringsEq(com.pullenti.unisharp.Utils.getXmlLocalName(a), "t") || com.pullenti.unisharp.Utils.stringsEq(com.pullenti.unisharp.Utils.getXmlLocalName(a), "title")) 
                    htmlTitle = a.getNodeValue();
                else if (com.pullenti.unisharp.Utils.stringsEq(com.pullenti.unisharp.Utils.getXmlLocalName(a), "section")) 
                    pageSectionId = a.getNodeValue();
                else if (com.pullenti.unisharp.Utils.stringsEq(com.pullenti.unisharp.Utils.getXmlLocalName(a), "sourceinfo")) 
                    sourceInfo = a.getNodeValue();
                else if (com.pullenti.unisharp.Utils.stringsEq(com.pullenti.unisharp.Utils.getXmlLocalName(a), "ignored")) 
                    ignorable = com.pullenti.unisharp.Utils.stringsEq(a.getNodeValue(), "true");
            }
        }
    }

    public UnitextItem optimize(boolean isContent, CreateDocumentParam pars) {
        return this;
    }

    /**
     * Получить список всех элементов (этот и все нижележащий)
     * @param res 
     */
    public void getAllItems(java.util.ArrayList<UnitextItem> res, int lev) {
        if (lev > 40) {
        }
        if (res != null) 
            res.add(this);
    }

    public boolean isWhitespaces() {
        return false;
    }


    public boolean isInline() {
        return true;
    }

    public boolean setInline(boolean value) {
        return value;
    }


    public boolean getStartsOnNewline() {
        return false;
    }


    protected static GetPlaintextParam m_DefParams;

    public void addPlainTextPos(int d) {
        beginChar += d;
        endChar += d;
    }

    public void correct(com.pullenti.unitext.internal.uni.LocCorrTyp typ, Object data) {
    }

    public String getInnerTag() {
        return null;
    }


    /**
     * Поиск среди текущего элемента и его внутренних элементов
     * @param _id идентификатор для поиска
     * @return результат
     */
    public UnitextItem findById(String _id) {
        if (com.pullenti.unisharp.Utils.stringsEq(id, _id)) 
            return this;
        return null;
    }

    public boolean replaceChild(UnitextItem old, UnitextItem ne) {
        return false;
    }

    public void setDefaultTextPos(com.pullenti.unisharp.Outargwrapper<Integer> cp, StringBuilder res) {
        beginChar = cp.value;
        endChar = cp.value - 1;
    }

    /**
     * Получить ссылку на стилевой фрагмент для указанной текстовой позиции. 
     * Отметим, что для элемента BeginChar..EndChar может покрывать или пересекаться 
     * с несколькими стилевыми фрагментами.
     * @param textPos позиция текста в системе BeginChar..EndChar (-1 - для первой позиции текущего элемента)
     * @return фрагмент, наиболее удалённый в иерархии фрагментов и содержащий указанную позицию
     */
    public UnitextStyledFragment getStyledFragment(int textPos) {
        if ((textPos < 0) && m_StyledFrag != null) 
            return m_StyledFrag;
        if (textPos < 0) 
            textPos = beginChar;
        for (UnitextItem it = this; it != null; it = it.parent) {
            if (it.m_StyledFrag != null) {
                UnitextStyledFragment res = it.m_StyledFrag.findByCharPosition(textPos);
                if (res != null) {
                    if (m_StyledFrag == null) 
                        m_StyledFrag = res;
                    return res;
                }
            }
        }
        return null;
    }

    public UnitextStyledFragment m_StyledFrag;

    public UnitextItem() {
    }
    
    static {
        m_DefParams = new GetPlaintextParam();
    }
}
