#pragma once

#include <QString>
#include <QStringBuilder>
#include <QVariant>

#define qs QStringLiteral

namespace Xybrid::Util {
    template<typename Num> inline QString numAndName(Num num, const QString& name) {
        if (name.isEmpty()) return QString::number(num);
        return qs("%1 (\"%2\")").arg(num).arg(name);
    }

    inline QString hex(int num, int fw = 2) {
        return qs("%1").arg(num, fw, 16, QChar('0')).toUpper();
    }

    template <typename T>
    inline QString enumName(T t) { return QVariant::fromValue(t).toString(); }

    inline QString sampleLength(int rate, int length) {
        double rSec = static_cast<double>(length) / static_cast<double>(rate);
        int tSec = static_cast<int>(rSec);
        int sec = tSec % 60;
        int min = (tSec - sec) / 60;
        int sub = static_cast<int>(rSec * 100) % 100;
        QChar zero('0');
        return qs("%1:%2.%3").arg(min, 2, 10, zero).arg(sec, 2, 10, zero).arg(sub, 2, 10, zero);
    }

    constexpr char notemap[] = "C-C#D-D#E-F-F#G-G#A-A#B-";
    inline QString noteName(int16_t note) {
        if (note == -1) return " - ";
        if (note == -2) return " ^ ";
        if (note == -3) return " x ";
        QString s(3, ' ');
        auto nn = note % 12;
        auto oc = (note - nn) / 12;
        s[2] = '0' + static_cast<char>(oc);
        s[0] = notemap[nn*2];
        s[1] = notemap[nn*2+1];
        return s;
    }
}
