/*
 *  Copyright 1994-2022 Olivier Girondel
 *
 *  This file is part of lebiniou.
 *
 *  lebiniou is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  lebiniou is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with lebiniou. If not, see <http://www.gnu.org/licenses/>.
 */

#include "alarm.h"
#include "brandom.h"


void
Alarm_init(Alarm_t *a)
{
  a->delay = (uint16_t)b_rand_uint32_range(a->min, a->max);
  Timer_start(a->timer);
}


Alarm_t *
Alarm_new(const int32_t min, const int32_t max)
{
  Alarm_t *a = NULL;

  a = xcalloc(1, sizeof(Alarm_t));

  a->timer = Timer_new("alarm");
  a->min = min;
  a->max = max;
  assert(a->min <= a->max);

  Alarm_init(a);

  return a;
}


void
Alarm_delete(Alarm_t *a)
{
  if (NULL != a) {
    Timer_delete(a->timer);
  }
  xfree(a);
}


int
Alarm_ring(Alarm_t *a)
{
  if (Timer_elapsed(a->timer) >= (float)a->delay) {
    Alarm_init(a);
    return 1;
  } else {
    return 0;
  }
}


float
Alarm_elapsed_pct(Alarm_t *a)
{
  float elapsed = Timer_elapsed(a->timer);
  uint16_t delay = a->delay;
  float pct;

  pct = elapsed / (float)delay;

  assert(pct >= 0);

  if (pct > 1) {
    pct = 1;
  }

  return pct;
}


void
Alarm_update(Alarm_t *a, const int32_t min, const int32_t max)
{
  assert(min <= max);
  a->min = min;
  a->max = max;
  Alarm_init(a);
}


void
Alarm_trigger(Alarm_t *a)
{
  a->delay = -1;
}
