//
// Created by Krad on 2021/12/16.
//

#include "RollingMessageWidget.h"
#include <QLabel>
#include <QThread>
#include <QDebug>
#include <QShowEvent>


const int WAIT_TIMES = 60;

RollingMessageWidget::RollingMessageWidget(QWidget *parent) :QWidget(parent){
    this->setFixedHeight(36);
//    this->setMinimumWidth(1000);

    this->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Preferred);
    label_current = new QLabel(this);
    label_next = new QLabel(this);

}

void RollingMessageWidget::timerEvent(QTimerEvent *e) {
    if (!this->isVisible()) return;
    //滚动
    if (rolling) {
        //end rolling, reset next
        if (rollStep == ROLL_DISTANCE){
            waitStep = 0;
            rolling = false;
            QPoint p3 = {ROLL_DISTANCE+5,2};
//            p3.setY(label_next->geometry().y());
            label_current->move(p3);
//            printf("move last to 505,2\n");
            std::swap(label_current,label_next);
            return;
        }
        //rolling
        rollStep+=2;
        QPoint p1 = {ROLL_DISTANCE+5 - rollStep,2};
        label_next->move(p1);
        if (p1.x()-label_current->geometry().x()<=label_current->width()+20)
        {
            QPoint p2 = {label_current->geometry().x()-2,2};
            label_current->move(p2);
        }

        return ;
    }
    else{

        //有等待的高优先级消息时，不停顿
        if (waitStep == WAIT_TIMES || (waitPriorityCount > 0 && waitStep == WAIT_TIMES/3)){
            locker.lock();
            label_next->setText(getNextMessage());
            label_next->setFixedWidth(label_next->text().length()*16);
            locker.unlock();
        } else{
            waitStep++;
        }
    }
}

void RollingMessageWidget::setMessageList(const QStringList &message) {
    //empty, don't set
    if (message.isEmpty()) return;
    messages.clear();
    needRolling = false;
    // set default label
    label_current->setText(message[0]);
    messages.push_back({0,message[0],0});
    //add list
    if (message.length()>0)
    {

        for (int k = 1; k < message.length(); ++k) {
            messages.push_front({k, message[k],-1});
        }
        needRolling = true;
    }

}

void RollingMessageWidget::updateMessagePriority(int innerIndex, int priority) {
    //lock thread
    locker.lock();
    //高优先级，需要插入
    if (priority > 0)
    {
        int idx = -1, insert_idx = -1;
        for (int i = 0; i < messages.length(); ++i) {
            if (messages[i].innerId == innerIndex)
            {
                messages[i].priority = priority;
                idx = i;
            }
            else if (insert_idx < 0 && messages[i].priority<1)
            {
                insert_idx = i;
            }
            if (idx>=0 && insert_idx >=0) break;
        }
        insert_idx = insert_idx==-1?0:insert_idx;
        //move
        if(insert_idx<idx)messages.move(idx,insert_idx);
        waitPriorityCount++;
    }
    // 低优先级，更新状态即可
    else{
        for (WarnMessage & message : messages) {
            if (message.innerId == innerIndex) {
                message.priority = -1;
                break;
            }
        }
    }
    locker.unlock();
}

QString RollingMessageWidget::getNextMessage() {

    QString ret = "No message";
    int retryCount = 0;
    bool priorityFlag = false;
    while (retryCount<messages.length()){
        messages.move(0,messages.length()-1);
        retryCount++;
        if(messages.last().priority>=0)
        {
            qDebug()<<"get next:"<<messages.last().toString();
            priorityFlag = messages.last().priority>0;
            ret = messages.last().msg;
            messages.last().priority = 0;
            break;
        }
    }
    if (priorityFlag && waitPriorityCount > 0) waitPriorityCount--;
    rollStep = 0;
    rolling = true;
    waitStep = 0;
    return ret;
}

void RollingMessageWidget::showEvent(QShowEvent *event) {
    QWidget::showEvent(event);
    if (!init)
    {
        ROLL_DISTANCE = this->width();
        QPoint p1 = {5,2};
        label_current->setFixedHeight(30);
        label_current->show();
        label_current->move(p1);
        label_current->setText(tr("Message of warn!"));
        label_current->setFixedWidth(label_current->text().length()*16);
        QPoint p2 = {ROLL_DISTANCE+5,2};
        label_next->setFixedHeight(30);
        label_next->show();
        label_next->move(p2);
        label_next->setText(tr("Message2 of warn!"));
        label_next->setFixedWidth(label_next->text().length()*16);

        timerId = startTimer(40);
        init = true;
    }
}
