/* *********************************************************************
 * *                                                                   *
 * *  Header file for the Ribbon Display Library                       *
 * *                                                                   *
 * *********************************************************************
 * File: include/ribbon_lib.h
 *
 *                       COPYRIGHT (c) 1999  BY
 *          SIGMET INCORPORATED, WESTFORD MASSACHUSETTS, U.S.A.
 * 
 * THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND  COPIED
 * ONLY  IN  ACCORDANCE WITH  THE  TERMS  OF  SUCH  LICENSE  AND WITH THE
 * INCLUSION OF THE ABOVE COPYRIGHT NOTICE.  THIS SOFTWARE  OR  ANY OTHER
 * COPIES  THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY
 * OTHER PERSON.  NO TITLE TO AND OWNERSHIP OF  THE  SOFTWARE  IS  HEREBY
 * TRANSFERED.
 */
#ifndef SIGMET_RIBBON_LIB_H
#define SIGMET_RIBBON_LIB_H 1

/*
 * Ribbon display configuration structure
 */
#define RIB_MAX_CONFIG_SETS (8)
#define RIB_MAX_DISPLAYS    (8)
#define RIB_DISPLAY_WIDTH   (25)
#define RIB_DISPLAY_HEIGHT  (10)
/*
 * Setup information for on row of one display.
 */
struct ribbon_row_setup
{
  char sCorridor[16];
};

/*
 * Setup information for one display.
 */
struct ribbon_display_setup
{ 
  UINT2 lValid;
  ribbon_row_setup Row[RIB_DISPLAY_HEIGHT-1];
};

struct ribbon_set_setup
{
  char  sName[16];
  struct ribbon_display_setup Display[RIB_MAX_DISPLAYS];
};

struct ribbon_setup
{
  /* Index of the active set, origin 0, valid range 0 - iSetCount-1 */
  UINT2 iActiveSet;
  
  /* Time that display will continue to beep and flash a line before
   * automatically acknowledging it.
   */
  UINT2 iFlashTime;
  UINT1 iPad_4x4[4];
  
  /* Device name for the serial link to the ribbon displays
   */
  char sDevice[32];
  
  char sDisplayAlias[RIB_MAX_DISPLAYS][16];
  char ipad_168x132[132];
  
  struct ribbon_set_setup Set[RIB_MAX_CONFIG_SETS];
};

/* -------------------------------------------------------
 * Structure defining what is on one row of one ribbon display.
 */
struct ribbon_row_contents
{
  UINT4 iFlashStartTime;            /* binary time flashing was started */
  UINT1 lFlashing;                  /* Row is flashing */
  UINT1 lAlert;                     /* Line contains an alert */
  char sText[RIB_DISPLAY_WIDTH+1];  /* Null terminated text on the row */
};
struct ribbon_display_contents      /* Contents of one of the displays */
{
  struct ribbon_row_contents Row[RIB_DISPLAY_HEIGHT];
  UINT4 iStatus;                /* Status reported */
  UINT2 lAlarmEnabled;          /* State of audible alarm enable */
};


/* ********************************************
 * *                                          *
 * * Function Prototypes for Library Routines *
 * *                                          *
 * ********************************************
 */
////////////////////////////////////////////////////////////////////
// This is the base class. Instances can not be created from it.
// It only should be an inherited class
////////////////////////////////////////////////////////////////////

class Ribbon
{
 protected:
  Ribbon(void);          /* Constructor */
  
  UINT2 lBuilderActiveMain( void );  /* Indicates if the builder is running */
  
  UINT2 CloseMain( void );   /* Returns zero on error */
  
  volatile const struct ribbon_set_setup *GetActiveSetPointer
    ( void ) ;

  UINT2 lGetDisplayAlarmMain         /* Get flag indicating that the display is beeping */
    ( UINT2 iDisplay_a );               /* Which display */
  
  void  GetDisplayRowMain
    (struct ribbon_row_contents *pRow,     /* Display text for the specified display */
     UINT2  iRow_a,                   /* Which Row */
     UINT2  iDisplay_a );             /* Select the desired display */
  
  void   KillSerial          /* Kill the serial line processes */
    (void);

  UINT2 LoadSetupMain              /* Returns zero on error */
    ( volatile struct ribbon_setup* pRSetup_a );
  
  void LoadSetupActiveSetMain
    (struct ribbon_set_setup *pSet_a );
  
  UINT2  lPerformSerialOps
    (void);

  UINT2 PowerUpMain          /* Power up interface, returns 0 on error */
    ( UINT4 iClentType_a ); /* Indicate type of client */
  
  void  RegisterStatusByteMain /*Register status byte received from a display*/
    (UINT1 iStatus_a );
  
  UINT2  SaveSetupFile       /* Returns zero on error */
    ( const struct ribbon_setup* pRSetup_a );

  void   StartSerial         /* Start up the serial line processes */
    (void);
  
  UINT4  iSerialUpdateTime; /* Time (ms) to return for a periodic update (and poll) */
  
  UINT2  lMemoryMapped;     /* Shared memory has been mapped */
  UINT4  iVDisplayNumber;   /* Virtual display number, origin 0, if we are a Vdisplay */
  
 private:
  UINT2  GlobalInit
    ( UINT2* lcreated_a );
  void   InitFirst
    ( void );
  UINT2  LoadSetupFile       /* Returns zero on error */
    ( volatile struct ribbon_setup* pRSetup_a );
  UINT2  lProcessClientType  /* Process the client type on startup */
    ( UINT4 iClientType_a );

};

/*
 * Used only for the virtual ribbon display
 */
class RibbonVDisplay : private Ribbon 
{
 public:
  UINT2 PowerUp(void);
  UINT2 Close(void);
  UINT2 lGetDisplayAlarm(UINT2 iDisplay_a);
  void  GetDisplayRow(struct ribbon_row_contents *pRow, 
		      UINT2  iRow_a, UINT2  iDisplay_a );
  void  AcknowledgePressed( UINT2 iDisplay_a );
};

/*
 * Used only for the ribbon setup program
 */
class RibbonSetup : private Ribbon 
{
   public :
      UINT2 PowerUp(void);
      UINT2 Close(void);
      UINT2 LoadSetup(volatile struct ribbon_setup* pRSetup_a);
      UINT2 SaveSetup(const struct ribbon_setup* pRSetup_a );

#define RIBBON_STATUS_DEAD     (0)   /* Display has timed out, or never run */
#define RIBBON_STATUS_OK       (1)   /* Everything working */
#define RIBBON_STATUS_FAULT    (2)   /* Failed internal diagnostics */
#define RIBBON_STATUS_OVERFLOW (3)   /* Serial data overflow */
  
      void  GetActivity(SINT4 incnt_a[RIB_MAX_DISPLAYS],
                       SINT4 ioutcnt_a[RIB_MAX_DISPLAYS], 
                       UINT4 iStatus_a[RIB_MAX_DISPLAYS],
                       SINT4 iAgeOfLast[RIB_MAX_DISPLAYS] ); 
};

/*
 * Used only for the serial receiver process connected to the displays
 */
class RibbonSerialRcv : private Ribbon 
{
   public :
      UINT2 PowerUp(void);
      UINT2 Close(void);
      void  RegisterSerialStatus(MESSAGE iStatus_a );
      UINT2 lBuilderActive( void ); 
      UINT2 LoadSetup(volatile struct ribbon_setup* pRSetup_a);
      void  RegisterStatusByte(UINT1 iStatus_a );
};

/*
 * Used only for the serial transmitter process connected to the displays
 */
class RibbonSerialXmt : private Ribbon 
{
 public:
  void  CancelFlashing(void);
  UINT2 Close(void);
  void  GetDisplayRow (struct ribbon_row_contents *pRow_a,
		       UINT2 iRow_a,  UINT2 iDisplay_a );
  void  IncrementOutCounts(SINT4 iOut, SINT4 iError, SINT4 iDisplay );
  UINT2 lBuilderActive( void ); 
  UINT2 LoadSetup(volatile struct ribbon_setup* pRSetup_a);
  UINT2 lGetDisplayAlarm ( UINT2 iDisplay_a );
  UINT2 lWaitForChange(void);
  void  LoadSetupActiveSet(struct ribbon_set_setup *pSet_a );
  UINT2 PowerUp(void);
  void  RegisterSerialStatus(MESSAGE iStatus_a );
  void  SetWaitTimeout(UINT4 iWaitInMs_a);
};

/*
 * Used only for the builder process
 */
class RibbonBuilder : private Ribbon 
{
 public:
  UINT2 Close(void);
  void  DisableTime(void);
  void  EnableTime(void);
  void  LoadSetupActiveSet(struct ribbon_set_setup* pSetup_a);
  UINT2 PowerUp(void);
  void  SetChangedFlag(void);
  void  SetDisplayRow
    (const char *sText_a,    /* Text for specified Row */
     UINT1 lAlert_a,         /* Row contains an alert */
     UINT2 iRow_a,           /* Which row */
     UINT2 iDisplay_a );     /* Which display */
};

#endif /* #ifndef SIGMET_RIBBON_LIB_H */
