#include "headers/speedtimer.h"

SpeedTimer * pGlobalSpeedTimer = nullptr;

SpeedTimer::SpeedTimer(QObject *parent) : QObject(parent)
{

    this->date = new QDateTime;

    this->startTime = 0;
    this->stopTime = 0;
    this->stoppedTime = 0;
    this->reactionTime = 0;
    this->state = IDLE;
}

bool SpeedTimer::start(bool force) {
    if(this->state != STARTING && !force){
        return false;
    }
    qDebug() << "starting timer";
    if(!force){
        this->stopTime = 0;
        this->stoppedTime = 0;
        this->reactionTime = 0;
        this->startTime = this->date->currentMSecsSinceEpoch();
    }

    this->setState(RUNNING);

    return true;
    //this->startPad->appendCommand("SET_LED_RUNNING");
}

bool SpeedTimer::stop(int type, bool force) {

    // type can be:
    // 0: stopped
    // 1: cancelled
    // 2: failed (fase start)

    if( ( this->state != SpeedTimer::STARTING && this->state != SpeedTimer::RUNNING && this->state ) && !force ){
        return false;
    }

    //qDebug() << "Stopping: " << "start Time: " << startTime << " stopTime: " << stopTime << " stoppedTime: " << stoppedTime << " reactionTime: " << reactionTime;

    switch (type) {
    case 0:
    {
        this->stopTime = this->date->currentMSecsSinceEpoch();
        this->stoppedTime = this->stopTime - this->startTime;
        this->setState(STOPPED);
        break;
    }
    case 1:
    {
        this->stoppedTime = 0;
        this->setState(CANCELLED);
        break;
    }
    case 2:
    {
        this->stoppedTime = this->reactionTime;
        this->setState(FAILED);
        break;
    }
    }

    qDebug() << "Stopped: " << "start Time: " << startTime << " stopTime: " << stopTime << " stoppedTime: " << stoppedTime << " reactionTime: " << reactionTime;

    return true;
    //this->startPad->appendCommand("SET_LED_STARTING");
}

bool SpeedTimer::reset(bool force){
    if( ( this->state != STOPPED && this->state != FAILED && this->state != CANCELLED ) && !force){
        return false;
    }

    this->startTime = 0;
    this->stopTime = 0;
    this->stoppedTime = 0;
    this->reactionTime = 0;
    this->setState(IDLE);

    return true;
    //this->startPad->appendCommand("SET_LED_STARTING");
}

void SpeedTimer::setState(timerState newState){
    this->state = newState;
    qDebug() << "+--- timer state changed: " << newState;
    emit this->stateChanged(newState);
}

QString SpeedTimer::getState(){
    switch(state){
    case IDLE:
        return("IDLE");
    case STARTING:
        return("STARTING");
    case RUNNING:
        return("RUNNING");
    case STOPPED:
        return("STOPPED");
    case FAILED:
        return("FAILED");
    case CANCELLED:
        return("CANCELLED");
    }
    return("ERROR");
}

double SpeedTimer::getCurrTime() {
    double currTime;
    if(this->state == RUNNING && this->startTime > 0){
        currTime = this->date->currentMSecsSinceEpoch() - this->startTime;
    }
    else {
        currTime = this->stoppedTime;
    }

    return(currTime);
}

QString SpeedTimer::getText() {
    //qDebug() << this->getState();
    QString newText;
    switch (this->state) {
    case SpeedTimer::IDLE:
        newText = "Click Start to start";
        break;
    case SpeedTimer::STARTING:
        newText = "0.000 sec";
        break;
    case SpeedTimer::RUNNING:
        newText = QString::number( this->getCurrTime() / 1000.0, 'f', 3 ) + " sec";
        break;
    case SpeedTimer::STOPPED:
        newText = QString::number( this->stoppedTime / 1000.0, 'f', 3 ) + " sec";
        break;
    case SpeedTimer::FAILED:
        newText = "False Start";
        break;
    case SpeedTimer::CANCELLED:
        newText = "Cancelled";
        break;
    }

    return newText;
}

void SpeedTimer::delay(int mSecs){
    QEventLoop loop;
    QTimer timer;

    timer.setSingleShot(true);
    // quit the loop when the timer times out
    loop.connect(&timer, SIGNAL(timeout()), &loop, SLOT(quit()));
    //quit the loop when the connection was established
    // start the timer before starting to connect
    timer.start(mSecs);
    //connect

    //wait for the connection to finish (programm gets stuck in here)
    loop.exec();
}

SpeedTimer::timerState SpeedTimer::stateFromString(QString state){

    if(state == "IDLE"){
        return IDLE;
    }
    else if (state == "STARTING") {
        return STARTING;
    }
    else if (state == "RUNNING") {
        return RUNNING;
    }
    else if (state == "STOPPED") {
        return STOPPED;
    }
    else if (state == "FAILED") {
        return FAILED;
    }
    else {
        return CANCELLED;
    }
}

