// Copyright 2015 - 2025, GIBIS-UNIFESP and the wiRedPanda contributors
// SPDX-License-Identifier: GPL-3.0-or-later

#pragma once

#include <QCoreApplication>
#include <QLoggingCategory>
#include <QObject>
#include <stdexcept>

Q_DECLARE_LOGGING_CATEGORY(zero)
Q_DECLARE_LOGGING_CATEGORY(one)
Q_DECLARE_LOGGING_CATEGORY(two)
Q_DECLARE_LOGGING_CATEGORY(three)
Q_DECLARE_LOGGING_CATEGORY(four)
Q_DECLARE_LOGGING_CATEGORY(five)

#undef qCDebug // to add noquote() and nospace()

#if QT_VERSION < QT_VERSION_CHECK(6, 3, 0)
#define qCDebug(category) \
    for (bool qt_category_enabled = category().isDebugEnabled(); qt_category_enabled; qt_category_enabled = false) \
        QMessageLogger(QT_MESSAGELOG_FILE, QT_MESSAGELOG_LINE, QT_MESSAGELOG_FUNC, category().categoryName()).debug().noquote().nospace()
#else
#define qCDebug(category) QT_MESSAGE_LOGGER_COMMON(category, QtDebugMsg).debug().noquote().nospace()
#endif

class Comment
{
public:
    static void setVerbosity(const int verbosity);
};

class Pandaception : public std::runtime_error
{
public:
    explicit Pandaception(const QString &translatedMessage, const QString &englishMessage);

    QString englishMessage() const;

private:
    QString m_englishMessage;
};

// Main macro for class contexts that can use tr() - uses __VA_OPT__ for optional arguments
#define PANDACEPTION(msg, ...) \
    Pandaception(tr(msg) __VA_OPT__(.arg(__VA_ARGS__)), QString(msg) __VA_OPT__(.arg(__VA_ARGS__)))

// Special macro for non-class contexts - uses __VA_OPT__ for optional arguments
#define PANDACEPTION_WITH_CONTEXT(context, msg, ...) \
    Pandaception(QCoreApplication::translate(context, msg) __VA_OPT__(.arg(__VA_ARGS__)), QString(msg) __VA_OPT__(.arg(__VA_ARGS__)))

class GraphicElement;

class Common
{
public:
    static QVector<GraphicElement *> sortGraphicElements(QVector<GraphicElement *> elements);
    static int calculatePriority(GraphicElement *elm, QHash<GraphicElement *, bool> &beingVisited, QHash<GraphicElement *, int> &priorities);
};
