#ifndef H_ED_MUSR_20031003125441
#define H_ED_MUSR_20031003125441

#ifdef __cplusplus
extern "C"
{
#endif

/* ---------------------------------------------------------------------
   (c) ED 2002-2005
   Project      : CLIB
   Function     : Multi-user manager
   Module       : MUSR
   File         : MUSR.H
   Created      : 03-09-2002
   Modified     : 17-03-2005
   --------------------------------------------------------------------- */

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

   0.0 - 03-09-2002 Created
   1.0 - 03-09-2002 Initial version
   1.1 - 16-10-2002 MUSR_refresh() added
   1.2 - 17-10-2002 callback return value added
   1.3 - 06-11-2002 transition value added
   1.4 - 07-11-2002 action flags added (ALL, FIRST, LAST)
   1.5 - 09-11-2002 action flags modified ALL becomes ALL_ON / ALL_OFF
   1.6 - 13-11-2002 callback return management debug.
   1.7 - 18-11-2002 "release a NO_ID client" debug.
   1.8 - 19-11-2002 "apply()" debug.
   .                error handlig debug.
   1.9 - 21-11-2002 Events order changed in release().
   1.10- 05-05-2004 Added MUSR_stra()
   1.11- 17-03-2005 Linux : include file names forced to lowercase

   Specifications
   --------------

   This module is a multi-user manager. It has been designed to solve
   the issue of a ressource beeing used by several users.

   A typical example is a LED (ressource) shared between several
   application (clients)

   Two kind of statuses are specified:

   - Active statuses (can be more than one)
   - Inactive status (unique)

   The inactive status is recorded at init time.

   init (INACTIVE)

   When a new client activates the ressource, he receives a unique client
   number. If he is the first client, or if the status changes, the action
   is triggered (callback) with the current status as a parameter.

   client_a ->apply(ACTIV_A)  [ ]----> Action(ACTIV_A)
   cli_id_a <---------------- [ ]

   If a new client activates the ressource with the same status,
   the output is not activated, but a new client number is returned.

   client_b ->apply(ACTIV_A)  [ ]
   cli_id_b <---------------- [ ]

   If a known client activates the ressource with a different status,
   the output is triggered.

   client_b ->apply(ACTIV_B)  [ ]----> Action(ACTIV_B)

   If a known client deactivates the ressource, its client number is
   cancelled

   client_b ->release()  [ ]
   NO_ID <-------------- [ ]

   If he was the last client, the output is triggered with the pre-recorded
   INACTIVE status.

   client_a ->release()  [ ]----> Action(INACTIVE)
   NO_ID <-------------- [ ]

   Callback return value
   ---------------------

   The value returned by the output function (callback) is valid when:
   - the value returned by the functions apply(), release()
   . and refresh() is MUSR_OK
   - the value returned by the cb_ret() function is not -1.

   Hence, the design of the callback must not use '-1' as a valid return
   value.

   --------------------------------------------------------------------- */
#include "ed/inc/types.h"

/* public data ========================================================= */
/* macros ============================================================== */
/* constants =========================================================== */
#define MUSR_DBG 1

   typedef enum
   {
      MUSR_OK,
#define ITEM(a,b) MUSR_ERR_##a,
#include "ed/inc/musr_err.itm"
#undef ITEM
      MUSR_ERR_NB
   }
   eMUSR_ERR;

   typedef enum
   {
#define ITEM(a) MUSR_TRA_##a,
#include "ed/inc/musr_tra.itm"
#undef ITEM
      MUSR_TRA_NB
   }
   eMUSR_TRA;

   enum
   {
      MUSR_NO_ID = -1
   };

/* types =============================================================== */
/* ---------------------------------------------------------------------
   fMUSR_OUT()
   ---------------------------------------------------------------------

   ---------------------------------------------------------------------
   E : Anonymous pointer to user's context
   E : generic status value
   S :
   --------------------------------------------------------------------- */
   typedef int (fMUSR_OUT) (void *pData, uint sts, eMUSR_TRA tra);


/* structures ========================================================== */
   typedef struct
   {
      eMUSR_ERR last_err;
      void *pPrivate;
   }
   sMUSR;

   typedef int musr_cli_id_s;

/* internal public data ================================================ */
/* internal public functions =========================================== */
/* entry points ======================================================== */

/* ---------------------------------------------------------------------
   MUSR_sver()
   ---------------------------------------------------------------------
   Returns the "Version" string
   ---------------------------------------------------------------------
   E :
   S : ASCIIZ string pointer
   --------------------------------------------------------------------- */
   char const *MUSR_sver (void);

/* ---------------------------------------------------------------------
   MUSR_sid()
   ---------------------------------------------------------------------
   Returns the "Identification" string
   ---------------------------------------------------------------------
   E :
   S : ASCIIZ string pointer
   --------------------------------------------------------------------- */
   char const *MUSR_sid (void);

/* ---------------------------------------------------------------------
   MUSR_serr()
   ---------------------------------------------------------------------
   Returns the "Error" string
   ---------------------------------------------------------------------
   E :
   S : ASCIIZ string pointer
   --------------------------------------------------------------------- */
   char const *MUSR_serr (eMUSR_ERR err);

/* ---------------------------------------------------------------------
   MUSR_stra()
   ---------------------------------------------------------------------
   Returns the "Transition" string
   ---------------------------------------------------------------------
   E :
   S : ASCIIZ string pointer
   --------------------------------------------------------------------- */
   char const *MUSR_stra (eMUSR_TRA tra);

/* ---------------------------------------------------------------------
   MUSR_init()
   ---------------------------------------------------------------------
   Creates and initializes the C-object
   ---------------------------------------------------------------------
   E :
   S : Context
   --------------------------------------------------------------------- */
   sMUSR *MUSR_init (uint sts_off);

/* ---------------------------------------------------------------------
   MUSR_end()
   ---------------------------------------------------------------------
   Suppresses the C-object
   ---------------------------------------------------------------------
   E : Context
   S :
   --------------------------------------------------------------------- */
   void MUSR_end (sMUSR * this);

/* ---------------------------------------------------------------------
   MUSR_apply()
   ---------------------------------------------------------------------
   MUSR activation
   ---------------------------------------------------------------------
   E : Context
   E : Status
   E : Id address
   S :
   --------------------------------------------------------------------- */
   eMUSR_ERR MUSR_apply (sMUSR * this
                         ,uint sts
                         ,musr_cli_id_s * pid);

/* ---------------------------------------------------------------------
   MUSR_release()
   ---------------------------------------------------------------------
   MUSR deactivation
   ---------------------------------------------------------------------
   E : Context
   E : Id address or NULL to clear all
   S :
   --------------------------------------------------------------------- */
   eMUSR_ERR MUSR_release (sMUSR * this
                           ,musr_cli_id_s * pid);

/* ---------------------------------------------------------------------
   MUSR_refresh()
   ---------------------------------------------------------------------
   Forces the notification with current status
   ---------------------------------------------------------------------
   E : Context
   S :
   --------------------------------------------------------------------- */
   eMUSR_ERR MUSR_refresh (sMUSR * this);

#if MUSR_DBG
/* ---------------------------------------------------------------------
   MUSR_dbg_sts()
   ---------------------------------------------------------------------
   send status to stdout
   ---------------------------------------------------------------------
   E : Context
   S :
   --------------------------------------------------------------------- */
   void MUSR_dbg_sts (sMUSR * this);
#endif

/* ---------------------------------------------------------------------
   MUSR_install_out()
   ---------------------------------------------------------------------
   Installs a callback (default NULL)
   ---------------------------------------------------------------------
   E : Context
   S :
   --------------------------------------------------------------------- */
   eMUSR_ERR MUSR_install_out (sMUSR * this, fMUSR_OUT * pf, void *pData);

/* ---------------------------------------------------------------------
   MUSR_set_first()
   ---------------------------------------------------------------------
   sets the 'first' flag (default 0)
   ---------------------------------------------------------------------
   E : Context
   E : first status 0|1
   S :
   --------------------------------------------------------------------- */
   eMUSR_ERR MUSR_set_first (sMUSR * const this, int first);

/* ---------------------------------------------------------------------
   MUSR_set_last()
   ---------------------------------------------------------------------
   sets the 'last' flag (default 0)
   ---------------------------------------------------------------------
   E : Context
   E : last status 0|1
   S :
   --------------------------------------------------------------------- */
   eMUSR_ERR MUSR_set_last (sMUSR * const this, int last);

/* ---------------------------------------------------------------------
   MUSR_set_all_on()
   ---------------------------------------------------------------------
   sets the 'all_on' flag (default 0)
   ---------------------------------------------------------------------
   E : Context
   E : all_on status 0|1
   S :
   --------------------------------------------------------------------- */
   eMUSR_ERR MUSR_set_all_on (sMUSR * const this, int all_on);

/* ---------------------------------------------------------------------
   MUSR_set_all_off()
   ---------------------------------------------------------------------
   sets the 'all_off' flag (default 0)
   ---------------------------------------------------------------------
   E : Context
   E : all status 0|1
   S :
   --------------------------------------------------------------------- */
   eMUSR_ERR MUSR_set_all_off (sMUSR * const this, int all_off);

/* ---------------------------------------------------------------------
   MUSR_errno()
   ---------------------------------------------------------------------
   Returns the current error number
   ---------------------------------------------------------------------
   E : Context
   S :
   --------------------------------------------------------------------- */
   eMUSR_ERR MUSR_errno (sMUSR const *this);

/* ---------------------------------------------------------------------
   MUSR_cb_ret()
   ---------------------------------------------------------------------
   Returns the last callback return value
   -1 = invalid
   ---------------------------------------------------------------------
   E : Context
   S : Last callback return value
   --------------------------------------------------------------------- */
   int MUSR_cb_ret (sMUSR const *this);

/* File generated by 'NEW.EXE' Ver 1.30 (c) ED 1998-2001 */

/* GUARD (c) ED 2000 Nov 17 2000 Ver. 1.2 */

#ifdef __cplusplus
}
#endif

#endif                          /* H_ED_MUSR_20031003125441 */

/* Guards added by GUARD (c) ED 2000-2003 Feb 14 2003 Ver. 1.5 */
