CCCPaste

Ile jeszcze

#include 
#include 
#include 
#include 

#include 
#include 

using namespace std;

class ProgressBar
{
private:
    int currentTime, beginningTime, endingTime;
    float percentPassed;
    bool end = false;
    string prompt;

    int GetMessageLenght(string message)
    {
        int messageLenght = 0;
        for (int i = 0, c, ix = message.length(); i < ix; i++, messageLenght++)
        {
            c = (unsigned char)message[i];
            if (c >= 0 && c <= 127) i += 0;
            else if ((c & 0xE0) == 0xC0) i += 1;
            else if ((c & 0xF0) == 0xE0) i += 2;
            else if ((c & 0xF8) == 0xF0) i += 3;
        }
        return messageLenght;
    }

    void Variant(int left, string variants[], string &message)
    {
        message += to_string(left);

        int last = left % 10;

        if (left == 1) message += variants[0];                                                                    // minutę
        else if ((last == 2 || last == 3 || last == 4) && !(left > 10 && left < 20)) message += variants[1];      // minuty
        else message += variants[2];                                                                              // minut
    }

    string GetMessage()
    {
        string message;
        int left = endingTime - currentTime;
        int daysLeft = left / 60 / 60 / 24;
        int hoursLeft = (left - daysLeft * 60 * 60 * 24) / 60 / 60;
        int minutesLeft = (endingTime - currentTime - daysLeft * 60 * 60 * 24 - hoursLeft * 60 * 60) / 60;
        percentPassed = ((float)currentTime - (float)beginningTime) / ((float)endingTime - (float)beginningTime) * 100;

        if (currentTime >= endingTime) 
        {
            end = true;
            return "To już jest koniec, nie ma już nic";
        }

        int lastHours, lastMinutes;

        message += prompt;

        Variant(daysLeft, new string[3]{" dzień, ", " dni, ", " dni, "}, message);
        Variant(hoursLeft, new string[3]{" godzinę i ", " godziny i ", " godzin i "}, message);
        Variant(minutesLeft, new string[3]{" minutę", " minuty", " minut"}, message);

        return message;
    }

    string GetProgressBar()
    {
        struct winsize size;
        ioctl(STDOUT_FILENO, TIOCGWINSZ, &size);

        string progressBarStr = "[";
        int progressBarLenght = size.ws_col - 10;
        float step = 100.0 / progressBarLenght;

        int i = 0;
        while (i < round(percentPassed / step) - 1) {
            progressBarStr += "=";
            i++;
        }

        progressBarStr += ">";

        while (i < progressBarLenght - 1)
        { 
            progressBarStr += " ";
            i++; 
        }

        progressBarStr += "]";

        return progressBarStr;
    }

public:
    void Print()
    {
        cout << GetMessage() << "\n";

        if (end == false)
        {
            cout << GetProgressBar() << " ";
            if (percentPassed < 10) cout << " ";
            cout << fixed << setprecision(3) << percentPassed << "%";
        }

        cout << endl;
    }

    ProgressBar(string bT, string eT, string p)
    {
        tm t{};
        istringstream sbT(bT);
        istringstream seT(eT);

        t.tm_isdst = 1;

        sbT >> get_time(&t, "%H:%M %d.%m.%Y");
        beginningTime = (int)mktime(&t);

        seT >> get_time(&t, "%H:%M %d.%m.%Y");
        endingTime = (int)mktime(&t);

        if (sbT.fail() || seT.fail()) throw runtime_error{"incorrect date"};

        currentTime = (int)time(NULL);
        prompt = p;

        Print();
    }
};

int main()
{
    ProgressBar def("00:00 01.09.2020", "10:30 25.06.2021", "Trzeba przeżyć jeszcze ");

    return 0;
}