#include "params.h"
#include "can-halal.h"
#include "vehicle.h"

/**
 * Decrements the given value if it is above the minimum allowed value
 */
// TODO these functions take into account that the parameters are unsigned, it's definitely better to have them
// signed but would need to be tested with the autobox 
#define DEC_IF_ABOVE(param_val, min_val, decr_amt) ((param_val) = (((int)(param_val) - (int)(decr_amt)) > (int)(min_val)) ? ((param_val) - (decr_amt)) : (min_val))
#define INC_IF_BELOW(param_val, max_val, incr_amt) ((param_val) = (((param_val) + (incr_amt)) < (max_val)) ? ((param_val) + (incr_amt)) : (max_val))

Params params = {0};

void params_init()
{
  // Default values
  params.plim = 20;
  params.tlim = 1400;
  params.slim = 70;
  params.tvec = 50;
  params.pg = 0;
  params.reku = 0;
}

void params_inc(ParamType param)
{
  switch (param)
  {
  case PF_PLIM:
    INC_IF_BELOW(params.plim, 80, 1);
    break;
  case PF_TLIM:
    INC_IF_BELOW(params.tlim, 1500, 100);
    break;
  case PF_SLIM:
    INC_IF_BELOW(params.slim, 100, 1);
    break;
  case PF_TVEC:
    INC_IF_BELOW(params.tvec, 100, 1);
    break;
  case PF_PG:
    INC_IF_BELOW(params.pg, 100, 1);
    break;
  case PF_REKU:
    INC_IF_BELOW(params.reku, 100, 1);
    break;
  }
}

void params_dec(ParamType param)
{
  switch (param)
  {
  case PF_PLIM:
    DEC_IF_ABOVE(params.plim, 0, 1);
    break;
  case PF_TLIM:
    DEC_IF_ABOVE(params.tlim, 0, 100);
    break;
  case PF_SLIM:
    DEC_IF_ABOVE(params.slim, 0, 1);
    break;
  case PF_TVEC:
    DEC_IF_ABOVE(params.tvec, 0, 1);
    break;
  case PF_PG:
    DEC_IF_ABOVE(params.pg, 0, 1);
    break;
  case PF_REKU:
    DEC_IF_ABOVE(params.reku, 0, 1);
    break;
  }
}

void params_broadcast(ParamType param)
{
  int32_t value;
  switch (param)
  {
  case PF_PLIM:
    value = params.plim;
    break;
  case PF_TLIM:
    value = params.tlim;
    break;
  case PF_SLIM:
    value = params.slim;
    break;
  case PF_TVEC:
    value = params.tvec;
    break;
  case PF_PG:
    value = params.pg;
    break;
  case PF_REKU:
    value = params.reku;
    break;
  default:
    return;
  }
  vehicle_broadcast_param(param, value);
}