/****************************************************************
 * Filename  :  Overlay.c
 * Functions :
 *              Overlay_New
 *              Overlay_Delete
 *              Overlay_Initialize
 *              Overlay_AddItem
 *              Overlay_AddDepItem
 *              Overlay_AddCondition
 *              Overlay_AddAlarm
 *              Overlay_Display
 *              Overlay_Erase
 *              Overlay_Refresh
 *              Overlay_GetItem
 *              Overlay_GetItemCurve
 *              Overlay_LoadConfig
 *              Overlay_StartDmTasks
 *              Overlay_ReStartDmTasks
 *
 * Purpose   :  Functions for Overlay class
 $Revision: 1.1 $
 ***************************************************************/

#include <stdioLib.h>                   /* VxWorks standard I/O library       */
#include "mbariTypes.h"                 /* MBARI types file                   */
#include "dmvideo.h"                    /* data manager definitions           */
#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 "Config.h"                     /* definitions for Config class       */
#include "Item.h"                       /* definitions for Item class         */
#include "Alarm.h"                      /* definitions for Alarm class        */
#include "Condition.h"                  /* definitions for Condition class    */
#include "Curve.h"                      /* definitions for Curve class        */
#include "Overlay.h"                    /* definitions for Overlay class      */

/*---------------------------------------------------------------
 | Function  :  Overlay_New
 | Purpose   :  Return a new overlay structure
 | Inputs    :  name of instance
 | Outputs   :  none
 | Side FX   :  none
 | comments  :
 | Author    :  sylvain.coudray MBARI-IFREMER/diti/dsi/ie
 ---------------------------------------------------------------*/
    OV_Overlay*
Overlay_New(OV_char *name)
{
    OV_Overlay  *p_overlay;             /* an overlay */
    OV_int      nb_char;                /* number of characters */

    p_overlay = (OV_Overlay *) malloc ( sizeof(OV_Overlay));

/* allocate and initalize string for file name */
    nb_char = My_get_length ( name);
    p_overlay->name = (char *) malloc ( nb_char+1);
    strncpy ( p_overlay->name, name, nb_char);
    *(p_overlay->name+nb_char) = NULL;

    return (p_overlay);

} /* Overlay_New */

/*---------------------------------------------------------------
 | Function  :  Overlay_Delete
 | Purpose   :  Free memory from structure passed in parameter
 | Inputs    :  none
 | Outputs   :  none
 | Side FX   :  none
 | comments  :
 | Author    :  sylvain.coudray MBARI-IFREMER/diti/dsi/ie
 | Modified  :  tarrant 8/7/96
 |                to free all malloced components of structure
 |              tarrant 8/9/96
 |                to support alarms
 |              tarrant 8/27/96
 |                to support dependent items with conditions
 ---------------------------------------------------------------*/
    void
Overlay_Delete(OV_Overlay *p_overlay)
{
    OV_int i_item;                      /* item loop counter                  */
    OV_int i_condition;                 /* condition loop counter             */
    OV_int i_alarm;                     /* alarm loop counter                 */

    if (p_overlay->name != NULL)
        free(p_overlay->name);

    if (p_overlay->p_config !=NULL)
        Config_Delete(p_overlay->p_config);

    for (i_item = 0; i_item < p_overlay->nb_item_in_list; i_item++)
        if (p_overlay->p_item_list[i_item] != NULL)
            Item_Delete(p_overlay->p_item_list[i_item]);

    for (i_item = 0; i_item < p_overlay->nb_dep_items_in_list; i_item++)
        if (p_overlay->p_depItem_list[i_item] != NULL)
            Item_Delete_Dep(p_overlay->p_depItem_list[i_item]);

    for (i_condition = 0; i_condition < p_overlay->nb_conditions_in_list;
         i_condition++)
        if (p_overlay->p_condition_list[i_condition] != NULL)
            Condition_Delete(p_overlay->p_condition_list[i_condition]);

    Alarm_Links_Delete(p_overlay->alarm, &p_overlay->nb_alarms_linked);
    for (i_alarm = 0; i_alarm < p_overlay->nb_alarms_in_list; i_alarm++)
        if (p_overlay->p_alarm_list[i_alarm] != NULL)
            Alarm_Delete(p_overlay->p_alarm_list[i_alarm]);

    free(p_overlay);

    return;

} /* Overlay_Delete */

/*---------------------------------------------------------------
 | Function  :  Overlay_Initialize
 | Purpose   :  object initialization
 | Inputs    :  none
 | Outputs   :  none
 | Side FX   :  none
 | comments  :
 | Author    :  sylvain.coudray MBARI-IFREMER/diti/dsi/ie
 | Modified  :  tarrant 8/7/96
 |                removed foreground and background colours (not used)
 |              tarrant 8/9/96
 |                to support alarms
 ---------------------------------------------------------------*/
    void
Overlay_Initialize(OV_Overlay *p_overlay)
{

        p_overlay->x = 0;
        p_overlay->y = 0;
        p_overlay->width  = 0;
        p_overlay->height = 0;
        p_overlay->p_config = NULL;
        p_overlay->alarm = NULL;
        p_overlay->nb_item_in_list = 0;
        p_overlay->nb_dep_items_in_list = 0;
        p_overlay->nb_conditions_in_list = 0;
        p_overlay->nb_alarms_in_list = 0;
        p_overlay->nb_alarms_linked = 0;
        p_overlay->nb_alarm_groups = 0;
        p_overlay->sampling_rate = 10;

        return;

} /* Overlay_Initialize */


/*---------------------------------------------------------------
 | Function  :  Overlay_AddItem
 | Purpose   :
 | Inputs    :  none
 | Outputs   :  none
 | Side FX   :  none
 | comments  :
 | Author    :  sylvain.coudray MBARI-IFREMER/diti/dsi/ie
 ---------------------------------------------------------------*/
    void
Overlay_AddItem(OV_Overlay *p_overlay, OV_Item *p_item)
{

        OV_int  nb_item;

        /* ... add an item to the list */

        nb_item = p_overlay->nb_item_in_list;
        p_overlay->p_item_list[nb_item] = p_item;
        nb_item = nb_item + 1;
        p_overlay->nb_item_in_list = nb_item;

        /* ... End */

        return;

} /* Overlay_AddItem */


/*---------------------------------------------------------------
 | Function  :  Overlay_AddDepItem
 | Purpose   :  Adds a dependent item to the overlay alarm list.
 | Inputs    :  Overlay and item pointers.
 | Outputs   :  None.
 | Side FX   :  None.
 | comments  :
 | Author    :  Janice Tarrant
 ---------------------------------------------------------------*/
    void
Overlay_AddDepItem(OV_Overlay *p_overlay, OV_Item *p_item)
{
    OV_Dep_Item *p_depItem;

    p_depItem = Item_New_Dep();
    Item_Initialize_Dep(p_depItem);
    p_depItem->p_item = p_item;

    p_overlay->p_depItem_list[p_overlay->nb_dep_items_in_list] = p_depItem;
    p_overlay->nb_dep_items_in_list++;

    return;

} /* Overlay_AddDepItem */


/*---------------------------------------------------------------
 | Function  :  Overlay_AddCondition
 | Purpose   :  Adds a condition item to the overlay condition list.
 | Inputs    :  Overlay and condition pointers.
 | Outputs   :  None.
 | Side FX   :  None.
 | comments  :
 | Author    :  Janice Tarrant
 ---------------------------------------------------------------*/
    void
Overlay_AddCondition(OV_Overlay *p_overlay, OV_Condition *p_condition)
{

    p_overlay->p_condition_list[p_overlay->nb_conditions_in_list] = p_condition;
    p_overlay->nb_conditions_in_list++;

    return;

} /* Overlay_AddCondition */


/*---------------------------------------------------------------
 | Function  :  Overlay_AddAlarm
 | Purpose   :  Adds an alarm item to the overlay alarm list.
 | Inputs    :  Overlay and item pointers.
 | Outputs   :  None.
 | Author    :  Janice Tarrant
 ---------------------------------------------------------------*/
    void
Overlay_AddAlarm(OV_Overlay *p_overlay, OV_Item *p_item)
{
    OV_Alarm *p_alarm;

    p_alarm = Alarm_New();
    Alarm_Initialize(p_alarm);

    p_alarm->p_item = p_item;

    p_overlay->p_alarm_list[p_overlay->nb_alarms_in_list] = p_alarm;
    p_overlay->nb_alarms_in_list++;

    return;

} /* Overlay_AddAlarm */


/*---------------------------------------------------------------
 | Function  :  Overlay_Display
 | Purpose   :  displays all the items of the overlay
 | Inputs    :  none
 | Outputs   :  none
 | Side FX   :  none
 | comments  :
 | Author    :  sylvain.coudray MBARI-IFREMER/diti/dsi/ie
 | Modified  :  tarrant 08/20/96 to support dependent items
 |           :  tarrant 07/14/97 replaced globals with alignment structure
 ---------------------------------------------------------------*/
    void
Overlay_Display(OV_alignment *alignment, OV_Overlay *p_overlay)
{
    Int16 i_item;                               /* item index                 */
    Int16 nb_item;                              /* number of item             */
    Int16 nb_dep_items;                         /* number of dependent items  */
    Int16 nb_alarms = 0;                        /* number of alarms           */

    nb_item = p_overlay->nb_item_in_list;
    for (i_item = 0; i_item < nb_item; i_item++)
       Item_Display(alignment, p_overlay->p_item_list[i_item]);

    nb_dep_items = p_overlay->nb_dep_items_in_list;
    for (i_item = 0; i_item < nb_dep_items; i_item++)
        if (*(p_overlay->p_depItem_list[i_item]->on_display))
            Item_Display(alignment, p_overlay->p_depItem_list[i_item]->p_item);

    Alarm_Display(alignment, p_overlay->alarm, p_overlay->alarmsUp, &nb_alarms);

    return;

} /* Overlay_Display */


/*---------------------------------------------------------------
 | Function  :  Overlay_Erase
 | Purpose   :  Erases all the items from the overlay.
 | Inputs    :  Overlay pointer.
 | Outputs   :  None.
 | Author    :  Janice Tarrant
 ---------------------------------------------------------------*/
    void
Overlay_Erase(OV_alignment *alignment, OV_Overlay *p_overlay)
{
    Int16 i_item;                               /* item index                 */
    Int16 nb_item;                              /* number of item             */
    Int16 nb_dep_items;                         /* number of dependent items  */

    nb_item = p_overlay->nb_item_in_list;
    for (i_item = 0; i_item < nb_item; i_item++)
       Item_Erase(alignment, p_overlay->p_item_list[i_item]);

    nb_dep_items = p_overlay->nb_dep_items_in_list;
    for (i_item = 0; i_item < nb_dep_items; i_item++)
        if (*(p_overlay->p_depItem_list[i_item]->on_display))
            Item_Erase(alignment, p_overlay->p_depItem_list[i_item]->p_item);

                                           /* resets display mode after erase */
    Alarm_Erase(alignment, p_overlay->alarm, p_overlay->alarmsUp);

    return;

} /* Overlay_Erase */


/*---------------------------------------------------------------
 | Function  :  Overlay_Refresh
 | Purpose   :  refresh all items
 | Inputs    :  Pointer to overlay.
 | Outputs   :  None.
 | Side FX   :  none
 | comments  :
 | Author    :  sylvain.coudray MBARI-IFREMER/diti/dsi/ie
 | Modified  :  tarrant 08/20/96 to support dependent items
 |           :  tarrant 07/14/97 replaced globals with alignment structure
 ---------------------------------------------------------------*/
    void
Overlay_Refresh(OV_Context *alarmLink, OV_alignment *alignment,
                OV_Overlay *p_overlay)
{

    OV_int      i_item;                 /* current item index                 */
    OV_int      nb_item;                /* number of items                    */
    OV_int      nb_dep_items;           /* number of dependent items          */
    Int16       nb_alarms = 0;          /* number of alarms                   */
    OV_Dep_Item *p_depItem;             /* dependent item pointer             */

    nb_item = p_overlay->nb_item_in_list;
    for (i_item = 0; i_item < nb_item; i_item++)
        Item_Refresh(alignment, p_overlay->p_item_list[i_item]);

    nb_dep_items = p_overlay->nb_dep_items_in_list;
    for (i_item = 0; i_item < nb_dep_items; i_item++)
    {
        p_depItem = p_overlay->p_depItem_list[i_item];
        if (*(p_depItem->on_display))
        {
            if (!p_depItem->prev_on_display)
                Item_Display(alignment, p_depItem->p_item);
            else
                Item_Refresh(alignment, p_depItem->p_item);
        }
        else if (p_depItem->prev_on_display)
            Item_Erase(alignment, p_depItem->p_item);
        p_depItem->prev_on_display = *(p_depItem->on_display);
    }

    Alarm_Refresh(alarmLink, alignment, p_overlay->alarm, p_overlay->alarmsUp,
                  &nb_alarms);

    return;

} /* Overlay_Refresh */


/*---------------------------------------------------------------
 | Function  :  Overlay_GetItem
 | Purpose   :  Get Item which name is given in parameter.
 | Inputs    :  none
 | Outputs   :  pointer on item or NULL
 | Side FX   :  none
 | comments  :
 | Author    :  sylvain.coudray MBARI-IFREMER/diti/dsi/ie
 | Modified  :  tarrant 10/17/96
 |                to support dependent items
 ---------------------------------------------------------------*/
    OV_Item*
Overlay_GetItem(OV_Overlay *p_overlay, OV_char *name)
{
    OV_int  i_item;                     /* current item index                 */
    OV_int  nb_items;                   /* number of items                    */
    OV_int  nb_dep_items;               /* number of dependent items          */
    OV_Item *p_item;                    /* Item pointer                       */

/* search item list                                                           */
    nb_items = p_overlay->nb_item_in_list;
    for (i_item = 0; i_item < nb_items; i_item++)
    {
        p_item = p_overlay->p_item_list[i_item];
/*debug
printf ( " name         = %s \n", name);
printf ( " p_item->name = %s \n", p_item->name);
enddebug*/

        if (strcmp(p_item->name, name) == 0)
            return(p_item);
    }

/* search dependent item list                                                 */
    nb_dep_items = p_overlay->nb_dep_items_in_list;
    for (i_item = 0; i_item < nb_dep_items; i_item++)
    {
        p_item = p_overlay->p_depItem_list[i_item]->p_item;
        if (strcmp(p_item->name, name) == 0)
            return(p_item);
    }

/* if through here : item not found */
    return ( NULL);

} /* Overlay_GetItem */


/*---------------------------------------------------------------
 | Function  :  Overlay_GetItemCurve
 | Purpose   :  Get Item Curve from the name given.
 | Inputs    :  Overlay pointer and curve item name.
 | Outputs   :  Pointer to item curve or NULL
 | Author    :  Janice Tarrant
 ---------------------------------------------------------------*/
    OV_Item*
Overlay_GetItemCurve(OV_Overlay *p_overlay, OV_char *name)
{
    OV_int  i_item;                     /* current item index                 */
    OV_int  nb_items;                   /* number of items                    */
    OV_int  nb_dep_items;               /* number of dependent items          */
    OV_Item *p_item;                    /* Item pointer                       */

/* search item list                                                           */
    nb_items = p_overlay->nb_item_in_list;
    for (i_item = 0; i_item < nb_items; i_item++)
    {
        p_item = p_overlay->p_item_list[i_item];
/*debug
printf ( " name         = %s \n", name);
printf ( " p_item->name = %s \n", p_item->name);
enddebug*/

        if (strcmp(p_item->name, name) == 0)
        {
            if ( (strcmp(p_item->type, "GAUGE") == 0) ||
                 (strcmp (p_item->type, "CURVE") == 0) )
                return(p_item);
        }
    }

/* search dependent item list                                                 */
    nb_dep_items = p_overlay->nb_dep_items_in_list;
    for (i_item = 0; i_item < nb_dep_items; i_item++)
    {
        p_item = p_overlay->p_depItem_list[i_item]->p_item;

        if (strcmp(p_item->name, name) == 0)
            if (strcmp(p_item->type, "DEP_GAUGE_LINE") == 0)
                return(p_item);
    }

/* if through here : item not found */
    return ( NULL);

} /* Overlay_GetItemCurve */


/*---------------------------------------------------------------
 | Function  :  Overlay_LoadConfig
 | Purpose   :  Load associated configuration file
 | Inputs    :  none
 | Outputs   :  none
 | Side FX   :  none
 | comments  :
 | Author    :  sylvain.coudray MBARI-IFREMER/diti/dsi/ie
 | Modified  :  tarrant 8/9/96
 |                to support alarms
 |              tarrant 8/27/96
 |                to support dependent items with conditions
 ---------------------------------------------------------------*/
    uint32
Overlay_LoadConfig(OV_Overlay *p_overlay)
{
    OV_int       kerr ;                 /* error code                         */
    OV_int       i_item;                /* item index                         */
    OV_int       i_string;              /* string index                       */
    OV_int       i_alarm;               /* alarm index                        */
    OV_int       i_curve;               /* curve index                        */
    OV_int       i_condition;           /* condition index                    */
    OV_int       i_matrix;              /* matrix index                       */
    OV_float     values_a[NVAL];        /* array of values                    */
    OV_char      *strings_a[NSTR];      /* array of string                    */
    OV_int       nb_char;               /* number of characters               */
    OV_Item      *p_item;               /* pointer to item                    */
    OV_Dep_Item  *p_depItem;            /* pointer to dependent item          */
    OV_Condition *p_condition;          /* pointer to condition               */
    OV_Alarm     *p_alarm;              /* pointer to alarm                   */
    OV_Config    *p_config;             /* pointer to config                  */

    kerr = 0;

/* create an associated config object                                         */
    p_config = Config_New(p_overlay->name);
    Config_Initialize(p_config);
    Config_OpenFile(p_config);
    Config_ReadHeader(p_config);

    p_overlay->p_config = p_config;

/* create items                                                               */
    i_matrix = 1;
    for (i_item = 0; i_item < p_config->nb_item; i_item++)
    {
        Config_ReadLine(p_config, i_matrix, i_item, values_a, strings_a);

        p_item = Item_New(strings_a[ITEM_TYPE], strings_a[ITEM_COMMENT]);
        Item_Initialize(p_item);
        Item_SetPosition(p_item, values_a[ITEM_X], values_a[ITEM_Y]);
        Item_SetResources(p_item, strings_a[ITEM_FONT], strings_a[ITEM_COLOR],
                          strings_a[ITEM_MODE], values_a[ITEM_FORMAT],
                          "WIDTH1", "SOLID");
        Item_SetDmName(p_item, strings_a[ITEM_DMITEM]);

        if (strncmp(p_item->type, "DEP", 3) == 0)
            Overlay_AddDepItem(p_overlay, p_item);
        else
            Overlay_AddItem(p_overlay, p_item);

    } /* endfor i_item */

/*  create alarms                                                             */
    i_matrix = 2;
    for (i_alarm = 0; i_alarm < p_config->nb_alarms; i_alarm++)
    {
        Config_ReadLine(p_config, i_matrix, i_alarm, values_a, strings_a);

        p_item = Item_New(strings_a[ITEM_TYPE], strings_a[ITEM_COMMENT]);
        Item_Initialize(p_item);
        Item_SetPosition(p_item, values_a[ITEM_X], values_a[ITEM_Y]);
        Item_SetResources(p_item, strings_a[ITEM_FONT], strings_a[ITEM_COLOR],
                          strings_a[ITEM_MODE], values_a[ITEM_FORMAT],
                          "WIDTH1", "SOLID");
        Item_SetDmName(p_item, strings_a[ITEM_DMITEM]);

        Overlay_AddAlarm(p_overlay, p_item);

    } /* endfor i_alarm */

/* initialize alarm positions                                                 */
    p_alarm = p_overlay->p_alarm_list[0];
    Alarm_Positions(p_overlay->alarmsUp, p_alarm->p_item->x,
                    p_alarm->p_item->y);

/* load information about curves                                              */
    i_matrix = 3;
    for (i_curve = 0; i_curve < p_config->nb_curve; i_curve++)
    {
/* read a line in config file */
        Config_ReadLine(p_config, i_matrix, i_curve, values_a, strings_a);

/* get corresponding previously created item                                  */
        p_item = Overlay_GetItemCurve(p_overlay, strings_a[CURVE_COMMENT]);

        if (p_item == NULL)
        {
            logMsg("Video Overlay WARNING: item for curve %s not found\n",
                   strings_a[CURVE_COMMENT]);
            printf ( "*** error : item for curve not found ***\n");
            printf ( "*** check comments in your conf.file ***\n");
        }

/* initialize attributes                                                      */
        Curve_SetResources(p_item->p_curve, values_a[CURVE_XMIN],
                           values_a[CURVE_XMAX], values_a[CURVE_XGRAD],
                           values_a[CURVE_XLENGTH], values_a[CURVE_YMIN],
                           values_a[CURVE_YMAX], values_a[CURVE_YGRAD],
                           values_a[CURVE_YLENGTH], strings_a[CURVE_LINEWIDTH],
                           strings_a[CURVE_LINESTYLE]);

    } /* endfor i_curve */

/* load information about conditions                                          */
    i_matrix = 4;
    for (i_condition = 0; i_condition < p_config->nb_conditions; i_condition++)
    {

/* check for maximum number of conditions                                     */
        if (i_condition >= GROUP_MAX)
        {
            logMsg("Video Overlay WARNING: number of conditions exceeds maximum\n");
            break;
        }

/* read a line in config file                                                 */
        Config_ReadLine(p_config, i_matrix, i_condition, values_a, strings_a);

        p_condition = Condition_New(strings_a[CONDITION_COMMENT],
                                    strings_a[ITEM_DMITEM]);
        Condition_Initialize(p_condition);
        Overlay_AddCondition(p_overlay, p_condition);

/* check all dependent items for a match with each condition                  */
        for (i_item = 0; i_item < p_overlay->nb_dep_items_in_list; i_item++)
        {
            p_depItem = p_overlay->p_depItem_list[i_item];

            if (strcmp(p_depItem->p_item->name, p_condition->name) == 0)
            {
/*
printf("dep item %s comment %s matches %s\n", p_depItem->p_item->dm_name,
       p_depItem->p_item->name, p_condition->dm_name);
*/
                p_depItem->on_display = &p_condition->value;
                p_depItem->prev_on_display = *(p_depItem->on_display);

            }
        }

    } /* endfor i_condition */

/* check all dependent items for no match with a condition                    */
    for (i_item = 0; i_item < p_overlay->nb_dep_items_in_list; i_item++)
    {
        if (p_depItem->on_display == NULL)
        {
            logMsg("Video Overlay WARNING: condition for dependent item %s not found\n",
                   p_depItem->p_item->dm_name);
        }
    }

    return(kerr);

} /* Overlay_LoadConfig */


/*---------------------------------------------------------------
 | Function  :  Overlay_StartDmTasks
 | Purpose   :  start dataManager consumer task for each item
 | Inputs    :  none
 | Outputs   :  none
 | Side FX   :  none
 | comments  :
 | Author    :  sylvain.coudray MBARI-IFREMER/diti/dsi/ie
 | Modified  :  tarrant 9/5/96
 |                new version of My_init_dm_item
 |              tarrant 8/9/96
 |                to support alarms
 |              tarrant 8/28/96
 |                to support dependent items with conditions
 |              tarrant 12/9/96
 |                new version of My_init_dm_item
 ---------------------------------------------------------------*/
    void
Overlay_StartDmTasks(OV_Overlay *p_overlay,MBool *dmItemsExist)
{
    OV_char      priorityName[MAX_NMLEN];       /* alarm priority dm item name*/
    OV_int       i_item;                        /* item loop counter          */
    OV_int       i_condition;                   /* condition loop counter     */
    OV_int       i_alarm, numAlarms;            /* alarm loop counter         */
    OV_int       i_group, numGroups;            /* group loop counter         */
    OV_int       nb_item;                       /* number of items            */
    OV_int       nb_dep_items;                  /* number of dependent items  */
    OV_int       nb_conditions;                 /* number of conditions       */
    OV_int       nb_alarms;                     /* number of alarms           */
    MBool        alarmOn;                       /* alarm on flag              */
    MBool        acknowledge;                   /* alarm acknowledge          */
    Nat16        alarmData;                     /* alarm data                 */
    Nat16        priority;                      /* alarm priority             */
    OV_Item      *p_item;                       /* item pointer               */
    OV_Condition *p_condition;                  /* condition pointer          */
    OV_Alarm     *p_alarm;                      /* alarm pointer              */
    Errno        status;                        /* data manager error code    */

    nb_item = p_overlay->nb_item_in_list;
    nb_dep_items = p_overlay->nb_dep_items_in_list;
    nb_conditions = p_overlay->nb_conditions_in_list;
    nb_alarms = p_overlay->nb_alarms_in_list;

/* start task as consumer for items in overlay item lists                     */
    for (i_item = 0; i_item < nb_item; i_item++)
    {
        p_item = p_overlay->p_item_list[i_item];
        if ( (strncmp(p_item->dm_name, "TIBURON.", 8) == 0) ||
	     (strncmp(p_item->dm_name, "WESTERN_", 8) == 0) )
        {
            if (My_init_dm_item(p_item->dm_name, &(p_item->dm_item),
                &(p_item->dm_type), &(p_item->dm_size)) == ERROR)
            {
                p_item->dm_item = NO_ITEM;
                *dmItemsExist = FALSE;
            }
        }
    }

    for (i_item = 0; i_item < nb_dep_items; i_item++)
    {
        p_item = p_overlay->p_depItem_list[i_item]->p_item;

        if ( (strncmp( p_item->dm_name, "TIBURON.", 8) == 0) || 
	     (strncmp( p_item->dm_name, "WESTERN_", 8) == 0) )
        {
            if (My_init_dm_item(p_item->dm_name, &(p_item->dm_item),
                &(p_item->dm_type), &(p_item->dm_size)) == ERROR)
            {
                p_item->dm_item = NO_ITEM;
                *dmItemsExist = FALSE;
            }
        }
    }

/* start task as consumer for conditions in overlay conditions list           */
    for (i_condition = 0; i_condition < nb_conditions; i_condition++)
    {
        p_condition = p_overlay->p_condition_list[i_condition];
        if (My_init_dm_item(p_condition->dm_name, &(p_condition->dm_item),
            &(p_condition->dm_type), &(p_condition->dm_size)) == ERROR)
        {
            p_condition->dm_item = NO_ITEM;
            *dmItemsExist = FALSE;
        }

    }

/* start task as consumer for alarms in overlay alarm list                    */
    for (i_alarm = 0; i_alarm < nb_alarms; i_alarm++)
    {
        p_item = p_overlay->p_alarm_list[i_alarm]->p_item;
        if (My_init_dm_item(p_item->dm_name, &(p_item->dm_item),
            &(p_item->dm_type), &(p_item->dm_size)) == ERROR)
        {
            p_item->dm_item = NO_ITEM;
            *dmItemsExist = FALSE;
        }
    }

/* determine condition values                                                 */
    for (i_condition = 0; i_condition < nb_conditions; i_condition++)
    {
        p_condition = p_overlay->p_condition_list[i_condition];
        if (p_condition->dm_item != NO_ITEM)
            Condition_Read(p_condition);
        else
            p_condition->value = TRUE;
    }

/* determine alarm priorities and values, and add to linked list              */
    for (i_alarm = 0; i_alarm < nb_alarms; i_alarm++)
    {
        p_alarm = p_overlay->p_alarm_list[i_alarm];

                                /* create priority data manager item          */
        strcpy(priorityName, p_alarm->p_item->dm_name);
        strcat(priorityName, PRIORITY_KEYWORD);
        status = dm_create(priorityName, 1, &p_alarm->priority, DM_NAT16,
                           1, DM_ENDT);
        if (checkCreate(status, priorityName, FALSE) == ERROR)
        {
            logMsg("Video Overlay WARNING: can't change display priority of %s\n",
                   p_alarm->p_item->dm_name);
            p_alarm->on_display = TRUE;
        }
        else

        {                       /* start consumer priority dm item            */
            status = dm_start_consumer(p_alarm->priority, DM_ASYNC, SEM_NULL);
            if (checkConsumer(status, priorityName, FALSE) == ERROR)
            {
                logMsg("Video Overlay WARNING: can't change display priority of %s\n",
                       p_alarm->p_item->dm_name);
                p_alarm->on_display = TRUE;
            }
            else

            {                   /* read priority dm item                      */
                status = dm_read(p_alarm->priority, (Void *) &alarmData,
                                     sizeof(alarmData), (DM_Time *) NULL);
                if (checkRead(status, priorityName, FALSE) == ERROR)
                {
                    logMsg("Video Overlay WARNING: can't change display priority of %s\n",
                           p_alarm->p_item->dm_name);
                    p_alarm->on_display = TRUE;
                }
                else

                {               /* use alarm priority to set on display flag  */
                    priority = 0xFF & alarmData;
                    acknowledge = alarmData >> 8;
                    if (priority == 1)
                        p_alarm->on_display = TRUE;
                    else
                        p_alarm->on_display = FALSE;
                } /* checkRead */
            } /* checkConsumer */
        } /* checkCreate */

        if (p_alarm->p_item->dm_item != NO_ITEM)
        {
                                /* read alarm values                          */
            alarmOn = My_get_dm_alarm_item(p_alarm->p_item->dm_item,
                                           p_alarm->p_item->type);
            if (alarmOn && p_alarm->on_display)
            {
                if (p_overlay->nb_alarms_linked < MAX_ALARMS_ON_DISPLAY)
                    p_overlay->alarmsUp[p_overlay->nb_alarms_linked].name =
                        p_alarm->p_item->dm_name + strlen(ALARM_PREFIX);
                p_overlay->alarm = Add_AlarmLink(p_overlay->alarm,
                                                 &p_overlay->nb_alarms_linked,
                                                 p_alarm->p_item);
            }

        } /* if NO_ITEM */
    } /* for i_alarm */

/* add conditions to a data manager group                                     */
    p_overlay->conditionGroup = dm_create_group();
    for (i_condition = 0; i_condition < nb_conditions; i_condition++)
    {
        p_condition = p_overlay->p_condition_list[i_condition];
        if (p_condition->dm_item != NO_ITEM)
        {
            status = dm_group_add_item(p_overlay->conditionGroup,
                                       p_condition->dm_item,
                                       &p_condition->idBit);
            if (checkGroup(status, p_condition->dm_name) == ERROR)
            {
                logMsg("Video Overlay WARNING: %s condition not modifiable\n",
                       p_condition->dm_name);
                p_condition->value = TRUE;
            }
        }
    }

/* create data manager alarm and priority groups                              */
    p_overlay->nb_alarm_groups = (Int16) (nb_alarms / GROUP_MAX +1);
    if (p_overlay->nb_alarm_groups > NUM_ALARM_GROUPS)
    {
        logMsg("Video Overlay WARNING:  Exceeded max number of alarm groups\nNot all alarms will be displayed\n");
        p_overlay->nb_alarm_groups = NUM_ALARM_GROUPS;
    }
    for (i_group = 0; i_group < p_overlay->nb_alarm_groups; i_group++)
    {
        p_overlay->alarmGroup[i_group] = dm_create_group();
        p_overlay->priorityGroup[i_group] = dm_create_group();
    }

/* add alarms and priorities to data manager groups                           */
    numAlarms = 0;
    numGroups = 0;
    for (i_alarm = 0; i_alarm < nb_alarms; i_alarm++)
    {
        p_alarm = p_overlay->p_alarm_list[i_alarm];

        numAlarms++;
        if (numAlarms > GROUP_MAX)              /* current group is full,     */
        {                                       /* start next group           */
            numAlarms = 1;
            numGroups++;
        }

        if (p_alarm->p_item->dm_item != NO_ITEM)
        {
            status = dm_group_add_item(p_overlay->alarmGroup[numGroups],
                                       p_alarm->p_item->dm_item,
                                       &p_alarm->idBit);
            if (checkGroup(status, p_alarm->p_item->dm_name) == ERROR)
            {
                logMsg("Video Overlay WARNING: %s will not be displayed\n",
                       p_alarm->p_item->dm_name);
                p_alarm->on_display = FALSE;
            }
        }

        if (p_alarm->priority != NO_ITEM)
        {
            status = dm_group_add_item(p_overlay->priorityGroup[numGroups],
                                       p_alarm->priority,
                                       &p_alarm->priorityBit);
            strcpy(priorityName, p_alarm->p_item->dm_name);
            strcat(priorityName, PRIORITY_KEYWORD);
            if (checkGroup(status, priorityName) == ERROR)
                logMsg("Video Overlay WARNING: can't change display priority of %s\n",
                       p_alarm->p_item->dm_name);
        }

    } /* for i_alarm */

    return;

} /* Overlay_StartDmTasks */


/*---------------------------------------------------------------
 | Function  :  Overlay_ReStartDmTasks
 | Purpose   :  Restarts data manager consumer task for items that
 |              did not exist the first time through.
 | Inputs    :  none
 | Outputs   :  none
 | Author    :  Janice Tarrant
 ---------------------------------------------------------------*/
/*
setting DM_ITEM_EXIST_DEBUG to 1 will allow you to see datamanager items
that are referenced in the video overlay cfg file that do not exist in the 
system.  The datamanager items in question will be printed to the 
rov-console every time Overlay_ReStartDmTasks is called.
*/
#define DM_ITEM_EXIST_DEBUG	0

    void
Overlay_ReStartDmTasks(OV_Overlay *p_overlay, MBool *dmItemsExist)
{
    OV_int       i_item;                        /* item loop counter          */
    OV_int       i_condition;                   /* condition loop counter     */
    OV_int       i_alarm, numAlarms;            /* alarm loop counter         */
    OV_int       i_group, numGroups;            /* group loop counter         */
    OV_int       nb_item;                       /* number of items            */
    OV_int       nb_dep_items;                  /* number of dependent items  */
    OV_int       nb_conditions;                 /* number of conditions       */
    OV_int       nb_alarms;                     /* number of alarms           */
    MBool        alarmOn;                       /* alarm on flag              */
    Nat16        alarmData;                     /* alarm data                 */
    OV_Item      *p_item;                       /* item pointer               */
    OV_Condition *p_condition;                  /* condition pointer          */
    OV_Alarm     *p_alarm;                      /* alarm pointer              */
    Errno        status;                        /* data manager error code    */

    *dmItemsExist = TRUE;                       /* reset failed lookup flag   */

    nb_item = p_overlay->nb_item_in_list;
    nb_dep_items = p_overlay->nb_dep_items_in_list;
    nb_conditions = p_overlay->nb_conditions_in_list;
    nb_alarms = p_overlay->nb_alarms_in_list;

/* lookup and start consumer for items that previously did not exist          */
    for (i_item = 0; i_item < nb_item; i_item++)
    {
        p_item = p_overlay->p_item_list[i_item];
        if (p_item->dm_item == NO_ITEM)
        {
            if ( (strncmp(p_item->dm_name, "TIBURON.", 8) == 0) ||
	         (strncmp(p_item->dm_name, "WESTERN_", 8) == 0) )
            {
                if (My_init_dm_item(p_item->dm_name, &(p_item->dm_item),
                    &(p_item->dm_type), &(p_item->dm_size)) == ERROR)
                {
                    p_item->dm_item = NO_ITEM;
                    *dmItemsExist = FALSE;
#if DM_ITEM_EXIST_DEBUG 
		    printf ("p_item->dm_name = %s\n", p_item->dm_name);
#endif
                }
            }
        }
    }
    for (i_item = 0; i_item < nb_dep_items; i_item++)
    {
        p_item = p_overlay->p_depItem_list[i_item]->p_item;
        if (p_item->dm_item == NO_ITEM)
        {
            if ( (strncmp( p_item->dm_name, "TIBURON.", 8) == 0) ||
		 (strncmp( p_item->dm_name, "WESTERN_", 8) == 0) )
            {
                if (My_init_dm_item(p_item->dm_name, &(p_item->dm_item),
                    &(p_item->dm_type), &(p_item->dm_size)) == ERROR)
                {
                    p_item->dm_item = NO_ITEM;
                    *dmItemsExist = FALSE;
#if DM_ITEM_EXIST_DEBUG
	            printf ("p_item->dm_name = %s\n", p_item->dm_name);
#endif 
                }
            }
        }
    }

/* lookup, start consumer, read values and add to a group conditions that     */
/* previously did not exist                                                   */
    for (i_condition = 0; i_condition < nb_conditions; i_condition++)
    {
        p_condition = p_overlay->p_condition_list[i_condition];
        if (p_condition->dm_item == NO_ITEM)
        {
            if (My_init_dm_item(p_condition->dm_name, &(p_condition->dm_item),
                &(p_condition->dm_type), &(p_condition->dm_size)) == ERROR)
            {
                p_condition->dm_item = NO_ITEM;
                *dmItemsExist = FALSE;
#if DM_ITEM_EXIST_DEBUG
		printf ("p_condition->dm_name = %s\n", p_condition->dm_name);
#endif
            }
            else
            {
                Condition_Read(p_condition);
                status = dm_group_add_item(p_overlay->conditionGroup,
                                   p_condition->dm_item, &p_condition->idBit);
                if (checkGroup(status, p_condition->dm_name) == ERROR)
                {
                    logMsg("Video Overlay WARNING: %s condition not modifiable\n",
                       p_condition->dm_name);
                    p_condition->value = TRUE;
                }
            }
        }  /* p_condition->dm_item == NO_ITEM */
    }  /* i_condition */

/* lookup, start consumer, read values and add to a group alarms that         */
/* previously did not exist                                                   */
    numAlarms = 0;
    numGroups = 0;
    for (i_alarm = 0; i_alarm < nb_alarms; i_alarm++)
    {
        p_alarm = p_overlay->p_alarm_list[i_alarm];
        p_item = p_alarm->p_item;

        numAlarms++;
        if (numAlarms > GROUP_MAX)              /* current group is full,     */
        {                                       /* start next group           */
            numAlarms = 1;
            numGroups++;
        }

        if (p_item->dm_item == NO_ITEM)
        {
            if (My_init_dm_item(p_item->dm_name, &(p_item->dm_item),
                &(p_item->dm_type), &(p_item->dm_size)) == ERROR)
            {
                p_item->dm_item = NO_ITEM;
                *dmItemsExist = FALSE;
#if DM_ITEM_EXIST_DEBUG
	        printf ("p_item->dm_name = %s\n", p_item->dm_name);
#endif
            }
            else
            {
                                /* read alarm values                          */
                alarmOn = My_get_dm_alarm_item(p_item->dm_item, p_item->type);
                if (alarmOn && p_alarm->on_display)
                {
                    if (p_overlay->nb_alarms_linked < MAX_ALARMS_ON_DISPLAY)
                        p_overlay->alarmsUp[p_overlay->nb_alarms_linked].name =
                            p_item->dm_name + strlen(ALARM_PREFIX);
                    p_overlay->alarm =
                        Add_AlarmLink(p_overlay->alarm,
                                      &p_overlay->nb_alarms_linked,
                                      p_alarm->p_item);
                }
                                /* add alarms to a group                      */
                status = dm_group_add_item(p_overlay->alarmGroup[numGroups],
                                           p_item->dm_item, &p_alarm->idBit);
                if (checkGroup(status, p_item->dm_name) == ERROR)
                {
                    logMsg("Video Overlay WARNING: %s will not be displayed\n",
                           p_item->dm_name);
                    p_alarm->on_display = FALSE;
                }
            }
        }  /* p_item->dm_item == NO_ITEM */
    }  /* i_alarm */

}  /* Overlay_ReStartDmTasks */
