#include <patty/timer.h>

void patty_timer_init(patty_timer *timer, time_t ms) {
    timer->ms = ms;
}

int patty_timer_running(patty_timer *timer) {
    return (timer->flags & PATTY_TIMER_RUNNING)? 1: 0;
}

int patty_timer_expired(patty_timer *timer) {
    if (!(timer->flags & PATTY_TIMER_RUNNING)) {
        return 0;
    }

    return timer->t.tv_sec < 0
       || (timer->t.tv_sec == 0 && timer->t.tv_usec <= 0)? 1: 0;
}

void patty_timer_clear(patty_timer *timer) {
    timer->t.tv_sec  = 0;
    timer->t.tv_usec = 0;

    timer->flags &= ~PATTY_TIMER_RUNNING;
}

void patty_timer_start(patty_timer *timer) {
    timer->t.tv_sec  =  timer->ms / 1000;
    timer->t.tv_usec = (timer->ms % 1000) * 1000;

    timer->flags |= PATTY_TIMER_RUNNING;
}

void patty_timer_stop(patty_timer *timer) {
    timer->flags &= ~PATTY_TIMER_RUNNING;
}

void patty_timer_sub(struct timeval *a,
                     struct timeval *b,
                     struct timeval *c) {
    c->tv_usec  = a->tv_usec - b->tv_usec;
    c->tv_sec   = a->tv_sec  - b->tv_sec - (c->tv_usec / 1000000);
    c->tv_usec %= 1000000;
}

void patty_timer_tick(patty_timer *timer,
                      struct timeval *elapsed) {
    struct timeval res;

    if (!(timer->flags & PATTY_TIMER_RUNNING)) {
        return;
    }

    patty_timer_sub(&timer->t, elapsed, &res);

    timer->t.tv_sec  = res.tv_sec;
    timer->t.tv_usec = res.tv_usec;
}