/******************************************************************************/
/* Copyright 1996 MBARI                                                       */
/******************************************************************************/
/* Summary  : Video overlay functions for Alarm class                         */
/* Filename : Alarm.c                                                         */
/* Author   : Janice Tarrant                                                  */
/* Project  : Tiburon                                                         */
/* Version  : Version 1.0                                                     */
/* Created  : 08/09/96                                                        */
/* Modified :                                                                 */
/* Archived :                                                                 */
/******************************************************************************/
/* Modification History :                                                     */
/* $Header$
 * $Log$
 *
 */
/******************************************************************************/

#include "dmvideo.h"                    /* data manager definitions           */
#include <types.h>                      /* MBARI style guide type declarations*/
#include "OVtypes.h"                    /* video overlay type definitions     */
#include "dy4std.h"                     /* DY4 standard definitions           */
#include "video.h"                      /* DY4 video definitions              */
#include "mygraphics.h"                 /* graphics alignment definitions     */
#include "dy4driver.h"                 	/* DY$ driver definitions             */
#include "Item.h" 			/* definitions for Item class         */
#include "Alarm.h" 			/* definitions for Alarm class        */

/******************************************************************************/
/* Function : Alarm_New                                                       */
/* Purpose  : Constructor for Alarm class.                                    */
/* Inputs   : None.                                                           */
/* Outputs  : Returns pointer to alarm structure.                             */
/******************************************************************************/
    OV_Alarm*
Alarm_New(Void)
{
    OV_Alarm *p_alarm;				/* alarm structure pointer    */

    p_alarm = (OV_Alarm *) malloc(sizeof(OV_Alarm));

    return(p_alarm);

}  /* Alarm_New */


/******************************************************************************/
/* Function : Alarm_Delete                                                    */
/* Purpose  : Destructor for Alarm class.                                     */
/* Inputs   : Pointer to alarm structure.                                     */
/* Outputs  : None.                                                           */
/******************************************************************************/
    Void
Alarm_Delete(OV_Alarm *p_alarm)
{
    if (p_alarm->p_item != NULL)
	Item_Delete(p_alarm->p_item);

    free(p_alarm);

    return;

}  /* Alarm_Delete */


/******************************************************************************/
/* Function : Alarm_Links_Delete                                              */
/* Purpose  : Destructor for Alarm linked list.                               */
/* Inputs   : Pointer to alarm structure.                                     */
/* Outputs  : None.                                                           */
/******************************************************************************/
    Void
Alarm_Links_Delete(struct alarmLink *link, OV_int *nb_linked)
{
    struct alarmLink *tempLink;			/* temporary link             */

    if (link != NULL)
    {
	(*nb_linked)--;
	tempLink = link->next;
	free(link);
	Alarm_Links_Delete(tempLink, nb_linked);
    }

}  /* Alarm_Links_Delete */


/******************************************************************************/
/* Function : Alarm_Initialize                                                */
/* Purpose  : Initializes Alarm class.                                        */
/* Inputs   : Pointer to alarm structure.                                     */
/* Outputs  : None.                                                           */
/******************************************************************************/
    Void
Alarm_Initialize(OV_Alarm *p_alarm)
{
    p_alarm->on_display = FALSE;
    p_alarm->idBit = NULL;
    p_alarm->priority = NO_ITEM;
    p_alarm->priorityBit = NULL;

}  /* Alarm_Initialize */


/******************************************************************************/
/* Function : Alarm_Positions                                                 */
/* Purpose  : Initializes alarm positions on overlay.                         */
/* Inputs   : Alarm items, first x and y position.                            */
/* Outputs  : None.                                                           */
/******************************************************************************/
    Void
Alarm_Positions(alarmItem alarm[], Flt32 xPosition, Flt32 yPosition)
{
    Int16 i_alarm;				/* alarm counter              */

    for (i_alarm = 0; i_alarm < MAX_ALARMS_ON_DISPLAY; i_alarm++)
    {
	alarm[i_alarm].xPosition = xPosition;
	alarm[i_alarm].yPosition = yPosition - i_alarm * ALARM_SPACING;
	alarm[i_alarm].name = NULL;
    }

}  /* Alarm_Positions */


/******************************************************************************/
/* Function : Add_AlarmLink                                                   */
/* Purpose  : Adds an alarm link to the linked list.                          */
/* Inputs   : Alarm link and name.                                            */
/* Outputs  : None.                                                           */
/******************************************************************************/
    struct alarmLink*
Add_AlarmLink(struct alarmLink *link, OV_int *nb_linked, OV_Item *p_item)
{
    if (link == NULL)
    {
	link = (struct alarmLink *) malloc(sizeof(struct alarmLink));
	(*nb_linked)++;
	link->name = p_item->dm_name + strlen(ALARM_PREFIX);
	link->p_context = p_item->p_context;
	link->next = NULL;
    }
    else if (strcmp(link->name, p_item->dm_name+strlen(ALARM_PREFIX)) != 0)
	link->next = Add_AlarmLink(link->next, nb_linked, p_item);

    return(link);

}  /* Add_AlarmLink */


/******************************************************************************/
/* Function : Delete_AlarmLink                                                */
/* Purpose  : Deletes an alarm link in the linked list.                       */
/* Inputs   : Alarm link and name.                                            */
/* Outputs  : None.                                                           */
/******************************************************************************/
    struct alarmLink*
Delete_AlarmLink(OV_Context *lastLink, struct alarmLink *link,
		 OV_int *nb_linked, char *name)
{
    struct alarmLink *tempLink;			/* temporary link             */

    if (link != NULL)
    {
	if (strcmp(link->name, name) == 0)
	{
	    (*nb_linked)--;
	    tempLink = link->next;
	    *lastLink = *(link->p_context);
	    free(link);
	    return(tempLink);
	}
	else
	    link->next = Delete_AlarmLink(lastLink, link->next, nb_linked,
					  name);
    }

    return(link);

}  /* Delete_AlarmLink */


/******************************************************************************/
/* Function : Alarm_Display                                                   */
/* Purpose  : Displays an alarm on the overlay.                               */
/* Inputs   : Alarm link, alarms up and number of alarms up.                  */
/* Outputs  : None.                                                           */
/******************************************************************************/
    Void
Alarm_Display(OV_alignment *alignment, struct alarmLink *link,
	      alarmItem alarmsUp[], Int16 *nb_alarms)
{
    if ((link != NULL) && (*nb_alarms < MAX_ALARMS_ON_DISPLAY))
    {
	My_string_resources(link->p_context->text_font,
	                    link->p_context->foreground_color,
			    link->p_context->display_mode,
			    link->p_context->line_width,
			    link->p_context->line_style);
	My_wri_text(alignment, alarmsUp[*nb_alarms].xPosition,
		    alarmsUp[*nb_alarms].yPosition,
		    alarmsUp[*nb_alarms].name);

	(*nb_alarms)++;
	Alarm_Display(alignment, link->next, alarmsUp, nb_alarms);
    }

    return;

}  /* Alarm_Display */


/******************************************************************************/
/* Function : Alarm_Erase                                                     */
/* Purpose  : Erases the alarm list from the overlay.                         */
/* Inputs   : Alarm link, alarms up and number of alarms up.                  */
/* Outputs  : None.                                                           */
/******************************************************************************/
    Void
Alarm_Erase(OV_alignment *alignment, struct alarmLink *link,
	    alarmItem alarmsUp[])
{
    Int16 nb_alarms = 0;                        /* number of alarms           */

    Set_pixel_processing_operation(10);		/* erase mode                 */
    Alarm_Display(alignment, link, alarmsUp, &nb_alarms);
    Set_pixel_processing_operation(0);		/* display mode               */

}  /* Alarm_Erase */


/******************************************************************************/
/* Function : Alarm_Refresh                                                   */
/* Purpose  : Refreshes an alarm display on the overlay.                      */
/* Inputs   : Alarm link, alarms up and number of alarms up.                  */
/* Outputs  : None.                                                           */
/******************************************************************************/
    Void
Alarm_Refresh(OV_Context *lastLink, OV_alignment *alignment,
	      struct alarmLink *link, alarmItem alarmsUp[], Int16 *nb_alarms)
{
    Int16 i_alarm;				/* alarm counter              */

    if (*nb_alarms < MAX_ALARMS_ON_DISPLAY)
    {
    	if (link != NULL)
    	{
/* new alarm to display                                                       */
	    if (strcmp(link->name, alarmsUp[*nb_alarms].name) != 0)
	    {
/*
printf("replace %s with %s\n", alarmsUp[*nb_alarms].name, link->name);
*/
	        My_string_resources(link->p_context->text_font,
	                            link->p_context->foreground_color,
			            link->p_context->display_mode,
			            link->p_context->line_width,
			            link->p_context->line_style);

						/* erase alarm up             */
	        Set_pixel_processing_operation(10);
	        My_wri_text(alignment, alarmsUp[*nb_alarms].xPosition,
		            alarmsUp[*nb_alarms].yPosition,
		            alarmsUp[*nb_alarms].name);

						/* display alarm in list      */
	        alarmsUp[*nb_alarms].name = link->name;
	        Set_pixel_processing_operation(0);
	        My_wri_text(alignment, alarmsUp[*nb_alarms].xPosition,
			    alarmsUp[*nb_alarms].yPosition,
			    alarmsUp[*nb_alarms].name);
	    }

/* refresh next alarm in list                                                 */
	    (*nb_alarms)++;
	    Alarm_Refresh(lastLink, alignment, link->next, alarmsUp, nb_alarms);
        }
    	else if (link == NULL)
    	{
            for (i_alarm = *nb_alarms; i_alarm < MAX_ALARMS_ON_DISPLAY;
		 i_alarm++)
	    	if (alarmsUp[i_alarm].name != NULL)
	    	{
/*
printf("refresh(erase) %s\n", alarmsUp[i_alarm].name);
*/
						/* erase last alarm up        */
	            My_string_resources(lastLink->text_font,
				        lastLink->foreground_color,
			                lastLink->display_mode,
				        lastLink->line_width,
			                lastLink->line_style);
	    	    Set_pixel_processing_operation(10);
	    	    My_wri_text(alignment, alarmsUp[i_alarm].xPosition,
		                alarmsUp[i_alarm].yPosition,
			        alarmsUp[i_alarm].name);
	    	    Set_pixel_processing_operation(0);
	    	    alarmsUp[i_alarm].name = NULL;
	        }
	}
    }  /* if (*nb_alarms < MAX_ALARMS_ON_DISPLAY) */

    return;

}  /* Alarm_Refresh */
