/*****************************************************************************
 * $CAMITK_LICENCE_BEGIN$
 *
 * CamiTK - Computer Assisted Medical Intervention ToolKit
 * (c) 2001-2025 Univ. Grenoble Alpes, CNRS, Grenoble INP - UGA, TIMC, 38000 Grenoble, France
 *
 * Visit http://camitk.imag.fr for more information
 *
 * This file is part of CamiTK.
 *
 * CamiTK is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * CamiTK is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with CamiTK.  If not, see <http://www.gnu.org/licenses/>.
 *
 * $CAMITK_LICENCE_END$
 ****************************************************************************/

#ifndef __SYNTAX_HIGHLIGHTER__
#define __SYNTAX_HIGHLIGHTER__

// -- Core stuff
#include "CamiTKAPI.h"

#include <QSyntaxHighlighter>
#include <QRegularExpression>
#include <QTextCharFormat>
#include <QColor>

namespace camitk {
/**
 * @ingroup group_sdk_libraries_core_utils
 *
 * @brief  Base class for syntax highlighting
 *
 * Defines rules for transformation to facilitate new language highlighting.
 *
 * In the inherited class' constructor, just add rules, and that's it!
 * \code {.cpp}
    MyLanguageHighlighter::MyLanguageHighlighter(QTextDocument* parent) : SyntaxHighlighter(parent) {
        // display goto keywords in bold red
        addRule(QRegularExpression("\\bgoto\\b"), QColor("#ff0000"), QFont::Bold);
        ...
    }
 * \endcode
 *
 * You can now highlight any text edit:
 * \code {.cpp}
    QTextEdit* textEdit = new QTextEdit();
    ...
    new MyLanguageHighlighter(textEdit->document());
 * \endcode
 *
 */
class CAMITK_API SyntaxHighlighter : public QSyntaxHighlighter {
    Q_OBJECT

public:
    /// constructor
    /// @param parent (optional) if not given during instantiation, use setDocument(..) afterward
    SyntaxHighlighter(QTextDocument* parent = nullptr) ;

    /// add a new rule (can be done on the fly)
    /// @param regexp to match
    /// @param color text color
    /// @param weight QFont::Normal for normal (default) or QFont::Bold for bold
    /// @param italic false by default
    /// @param backgroundColor transparent by default
    void addRule(QString regexp, QColor color, int weight = QFont::Normal, bool italic = false, QColor backgroundColor = Qt::transparent);

    /// remove an existing rule (can be done on the fly)
    /// @return true if the rule was found and removed
    bool removeRule(QString regexp);

private:
    /// map of regular expression (using a QString to be able to remove it if needed)
    QMap<QString, QRegularExpression> rules;

    /// map of regular expression corresponding text formatting style
    QMap<QString, QTextCharFormat> formatters;

    /// monospace font used for formatting
    QFont monospaceFont;

    /// QSyntaxHighlighter override method called when text is parsed
    /// It will call highlightPattern for all rules
    void highlightBlock(const QString& text) override;

    /// utility function to set the format to a given portion of the text matching the regular expression
    /// (called in highlightBlock for each rule)
    void highlightPattern(const QString& text, const QString& pattern);

};

} // namespace camitk

#endif // #define __SYNTAX_HIGHLIGHTER__