/* ---------------------------------------------------------------------
   (c) Emmanuel Delahaye 2004
   Project      :
   Function     : implementation
   Module       : alarme
   File         : alarme.c
   Created      : 31-05-2004
   Modified     : 31-05-2004
   --------------------------------------------------------------------- */

/* ---------------------------------------------------------------------
   Log

   0.0 31-05-2004 Created
   1.0 31-05-2004 Initial version

   --------------------------------------------------------------------- */
#include <stddef.h>

#ifdef __cplusplus
#error This source file is not C++ but rather C. Please use a C-compiler
#endif

#include "inc/alarme.h"

/* macros ============================================================== */
/* constants =========================================================== */
/* types =============================================================== */
/* structures ========================================================== */
/* private variables =================================================== */
/* private functions =================================================== */
/* internal public functions =========================================== */

/* ---------------------------------------------------------------------
   out()
   ---------------------------------------------------------------------
   appel de la fonction de sortie enregistree (si disponible)
   ---------------------------------------------------------------------
   I: contexte                  
   I: etat de l'alarme
   O: pas de retour
   --------------------------------------------------------------------- */
static void out (alarme_s *this, int on)
{
   if (this->pf_out)
   {
       this->pf_out (on);
   }
   
   /* si le pointeur est NULL, on peut appeler un 'stub()' 
    * qui simule la sortie (utile en debug) 
    */

}

/* entry points ======================================================== */
/* public variables ==================================================== */

/* ---------------------------------------------------------------------
   alarme_install_out()
   ---------------------------------------------------------------------
   Enregistrement de la fonction de sortie 'alarme'
   ---------------------------------------------------------------------
   I: contexte                  
   I: adresse de la fonction    
   O: retour : 0 = OK 1 = erreur
   --------------------------------------------------------------------- */
int alarme_install_out (alarme_s *const this, alarme_out_f *const pf)
{      
   /* par defaut, pas d'erreur */
   int err = 0;
   
   /* pas question de continuer si le contexte est NULL */
   if (this != NULL)
   {                
      /* enregistrer l'adresse de la fonction de sortie */
      this->pf_out = pf;
   }
   else
   {
      err = 1;
   }
   
   return err;
}
 
/* ---------------------------------------------------------------------
   alarme_trigger_level()
   ---------------------------------------------------------------------
   Reglage du seuil de declenchement
   ---------------------------------------------------------------------
   I: contexte                   
   I: valeur du seuil           
   O: retour : 0 = OK 1 = erreur 
   --------------------------------------------------------------------- */
int alarme_trigger_level (alarme_s *const this, int const level)
{
   int err = 0;
   
   if (this != NULL)
   {
      if (level >= ALARME_VALUE_MIN
       && level <= ALARME_VALUE_MAX)
      {
         this->seuil_declenchement = level;
      }
      else
      {
         err = 1;
      }
   }
   else
   {
      err = 1;
   }
   
   return err;
}
 
/* ---------------------------------------------------------------------
   alarme_return_level()
   ---------------------------------------------------------------------
   Reglage du seuil de retour
   ---------------------------------------------------------------------
   I: contexte                  
   I: valeur du seuil           
   O: retour : 0 = OK 1 = erreur
   --------------------------------------------------------------------- */
int alarme_return_level (alarme_s *const this, int const level)
{
   int err = 0;
   
   if (this != NULL)
   {
      if (level >= ALARME_VALUE_MIN
       && level <= ALARME_VALUE_MAX)
      {
         this->seuil_retour = level;
      }
      else
      {
         err = 1;
      }
   }
   else
   {
      err = 1;
   }
   
   return err;
}

/* ---------------------------------------------------------------------
   alarme_eval()
   ---------------------------------------------------------------------
   Evaluation de la mesure. Detection des reactions eventuelles.
   Implementation de l'algorithme :
   
   IF NOT in_alarme
      IF mesure >= seuil_declenchement
         in_alarme := TRUE
         sortie_alarme (ON)
      ENDIF
   ELSE
      IF mesure < seuil_retour
         in_alarme := FALSE
         sortie_alarme (OFF)
      ENDIF
   ENDIF

   ---------------------------------------------------------------------
   I: contexte                  
   I: valeur a evaluer
   O: retour : 0 = OK 1 = erreur
   --------------------------------------------------------------------- */
int alarme_eval (alarme_s *const this, int const value)
{
   int err = 0;
   
   if (this != NULL)
   {
      if (value >= ALARME_VALUE_MIN
       && value <= ALARME_VALUE_MAX)
      {
      if (!this->active)
      {
         if (value > this->seuil_declenchement)
         {
            this->active = 1;

            out (this, 1);
         }
      }
      else
      {
         if (value < this->seuil_retour)
         {
            this->active = 0;

            out (this, 0);
         }
      }
      }
      else
      {
         err = 1;
      }
   }
   else
   {
      err = 1;
   }
   
   return err;
}

