/*
 * Copyright (c) 2014-2026 Meltytech, LLC
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef UTIL_H
#define UTIL_H

#include <MltProperties.h>
#include <functional>
#include <QColorDialog>
#include <QFileDialog>
#include <QPair>
#include <QPalette>
#include <QString>
#include <QUrl>

class QWidget;
class QDoubleSpinBox;
class QTemporaryFile;

namespace Mlt {
class Producer;
}

class Util
{
private:
    Util() {}

public:
    static QString baseName(const QString &filePath, bool trimQuery = false);
    static void setColorsToHighlight(QWidget *widget, QPalette::ColorRole role = QPalette::Window);
    static void showInFolder(const QString &path);
    static bool warnIfNotWritable(const QString &filePath, QWidget *parent, const QString &caption);
    static QString producerTitle(const Mlt::Producer &producer);
    static QString removeFileScheme(QUrl &url, bool fromPercentEncoding = true);
    static const QStringList sortedFileList(const QList<QUrl> &urls);
    static int coerceMultiple(int value, int multiple = 2);
    static QList<QUrl> expandDirectories(const QList<QUrl> &urls);
    static bool isDecimalPoint(QChar ch);
    static bool isNumeric(QString &str);
    static bool convertNumericString(QString &str, QChar decimalPoint);
    static bool convertDecimalPoints(QString &str, QChar decimalPoint);
    static void showFrameRateDialog(const QString &caption,
                                    int numerator,
                                    QDoubleSpinBox *spinner,
                                    QWidget *parent = Q_NULLPTR);
    static QTemporaryFile *writableTemporaryFile(const QString &filePath = QString(),
                                                 const QString &templateName = QString());
    static void applyCustomProperties(Mlt::Producer &destination,
                                      Mlt::Producer &source,
                                      int in,
                                      int out);
    static QString getFileHash(const QString &path);
    static QString getHash(Mlt::Properties &properties);
    static bool hasDriveLetter(const QString &path);
    static QColorDialog::ColorDialogOptions getColorDialogOptions();
    static QFileDialog::Options getFileDialogOptions();
    static bool isMemoryLow();
    static QString removeQueryString(const QString &s);
    static int greatestCommonDivisor(int m, int n);
    static void normalizeFrameRate(double fps, int &numerator, int &denominator);
    static QString textColor(const QColor &color);
    static void cameraFrameRateSize(const QByteArray &deviceName, qreal &frameRate, QSize &size);
    static bool ProducerIsTimewarp(Mlt::Producer *producer);
    static QString GetFilenameFromProducer(Mlt::Producer *producer, bool useOriginal = true);
    static double GetSpeedFromProducer(Mlt::Producer *producer);
    static QString updateCaption(Mlt::Producer *producer);
    static void passProducerProperties(Mlt::Producer *src, Mlt::Producer *dst);
    static bool warnIfLowDiskSpace(const QString &path);
    static bool isFpsDifferent(double a, double b);
    static QString getNextFile(const QString &filePath);
    static QString trcString(int trc);
    static bool trcIsCompatible(int trc);
    static QString getConversionAdvice(Mlt::Producer *producer);
    static mlt_color mltColorFromQColor(const QColor &color);
    static void offerSingleFileConversion(QString &message,
                                          Mlt::Producer *producer,
                                          QWidget *parent);
    static double getAndroidFrameRate(Mlt::Producer *producer);
    static double getSuggestedFrameRate(Mlt::Producer *producer);
    static Mlt::Producer openMltVirtualClip(const QString &path);
    static bool hasiPhoneAmbisonic(Mlt::Producer *producer);
    static bool installFlatpakWrappers(QWidget *parent);
    static QString getExecutable(QWidget *parent);
    // Returns a pair of booleans: (dockerInstalled, imagePresent)
    // imagePresent is only meaningful (true/false) if dockerInstalled is true; otherwise false.
    static QPair<bool, bool> dockerStatus(const QString &imageName);
    static bool isDockerImageCurrent(const QString &imageRef);
    // Asynchronous version of isDockerImageCurrent. The callback is invoked on the GUI thread
    // with the result. If any step fails (including docker not found), result is false.
    // 'receiver' is used as the parent for internal QProcess objects (may be nullptr).
    static void isDockerImageCurrentAsync(const QString &imageRef,
                                          QObject *receiver,
                                          std::function<void(bool)> callback);
    static bool isChromiumAvailable();
    static bool startDetached(const QString &program, const QStringList &arguments);
    static bool openUrl(const QUrl &url);
};

#endif // UTIL_H
