/*****************************************************************************
*           Change Log
*  Date     | Change
*-----------+-----------------------------------------------------------------
* 16-Nov-85 | [1.55] Created
*  8-Dec-85 | [1.161] Added tell_alert
* 12-Dec-85 | [1.175] Rearranged lights display to correspond to actual
*           | 1401 panel layout
* 12-Dec-85 | [1.178] Call set_reset_button when an alert is set
* 15-Dec-85 | [1.209] Use symbolic values for position
* 30-Dec-85 | [1.283] Added reset_mandatory field
* 30-Dec-85 | [1.283] If reset_mandatory, require reset as before; otherwise
*           | just turn on indicator and reset light
* 30-Dec-85 | [1.283] Added IO_indicator test procedure
*  8-Feb-86 | [1.359] Added color support; use scdspmsg to draw box.
*  8-Feb-86 | [1.359] <> => "" in includes
*  6-Aug-86 | [1.410] clear_alert now calls mark_screen_color, not mark_screen
* 18-Aug-86 | [1.414] screen.h -> bscreen.h
* 10-Nov-91 | [1.428] <jmn> converted to Microsoft C 6.0 libraries
*****************************************************************************/

/*****************************************************************************
				1401 Simulator

			    Alert Light Processing

This module lights or turns off the alert lights at the top of the console

*****************************************************************************/
#include "stdio.h"
#include "graph.h"

#include "btypes.h"
#include "scdspmsg.h"

#include "alert.h"
#include "alerts.h"
#include "diag.h"
#include "panel.h"
#include "hercules.h"
#include "disp.h"
#include "button.h"
#include "color.h"
#include "display.h"
#include "mach.h"

extern boolean lamp_test;

alert_window alerters[NALERTS] = {
/*
X                       Y         id           code            active  reset
---                     -------   -----------  ----------      ------  -----*/
{alert_X+0*alert_width,  alert_Y,  " Process ", alert_process,  false, true},
{alert_X+1*alert_width,  alert_Y,  "  Ramac  ", alert_ramac,    false, false},
{alert_X+2*alert_width,  alert_Y,  "  Tape   ", alert_tape,     false, false},
{alert_X+3*alert_width,  alert_Y,  " Reader  ", alert_reader,   false, false},
{alert_X+4*alert_width,  alert_Y,  "  Punch  ", alert_punch,    false, false},
{alert_X+5*alert_width,  alert_Y,  " Printer ", alert_printer,  false,false}
				 };

/****************************************************************************
*                                 tell_alert
* Inputs:
*       alert_window * a: Alert to tell about
* Effect: 
*       If diagnostic mode set, writes the alert information to the
*	diagnostic file
****************************************************************************/

void tell_alert(alert_window * a)
    {
     if(!diagnostics_on) 
	return;
     sprintf(diag_buffer,"**************** %s ****************",
     			a->id);
     tell(diag_buffer);
    }

/****************************************************************************
*                                 draw_alerts
* Effect: 
*       draws alert boxes 
****************************************************************************/

void draw_alerts()
    {
     int i;
     attrib fore;
     attrib back;

     if(ismono())
        { /* mono */
	 fore = H_NORMAL;
	 back = 0;
	} /* mono */
     else
        { /* color */
	 fore = WHITE;
	 back = BLACK;
	} /* color */
     for(i=0;i<NALERTS;i++)
        {
	 scdspmsg(alerters[i].Y,alerters[i].X,fore,back,  "ÚÄÄÄÄÄÄÄÄÄ¿");
	 scdspmsg((coord)(alerters[i].Y+1),alerters[i].X,fore,back,"³         ³");
	 scdspmsg((coord)(alerters[i].Y+2),alerters[i].X,fore,back,"ÀÄÄÄÄÄÄÄÄÄÙ");
	 mark_screen_color((coord)(alerters[i].X+1),(coord)(alerters[i].Y+1),
	 			alerters[i].id,
	 			(boolean)(alerters[i].active || lamp_test),
				BLACK,RED,WHITE,BLACK);
	}
	 
    }

/****************************************************************************
*                                  set_alert
* Inputs:
*       alert_window * a: Alert to set
* Effect: 
*       Turns the alert on
****************************************************************************/

void set_alert(alert_window * a)
    {
     a->active = true;
     mark_screen_color((coord)(a->X+1), (coord)(a->Y+1), a->id, true, BLACK,RED,WHITE,BLACK);
     set_reset_button();
    }

/****************************************************************************
*                                  clear_alert
* Inputs:
*       alert_window * a: Alert to clear
* Effect: 
*       Turns the alert off
****************************************************************************/

void clear_alert(alert_window * a)
    {
     a->active = false;
     mark_screen_color((coord)(a->X+1), (coord)(a->Y+1), a->id, false,RED,BLACK,WHITE,BLACK);
    }

/****************************************************************************
*                                    alert
* Inputs:
*       short code: Indicator to be turned on
* Effect: 
*       Turns on the indicated alert light
****************************************************************************/

void alert(short code)
    {
     int i;
     for(i=0;i<NALERTS;i++)
        { /* find alert */
	 if(alerters[i].code == code)
	    { /* found alert */
	     set_alert(&alerters[i]);
	     tell_alert(&alerters[i]);
	     if(alerters[i].reset_mandatory)
	         require_reset();
             else
	         set_reset_button();
	     break;
	    } /* found alert */
	} /* find alert */
    }

/****************************************************************************
*                                reset_alerts
* Effect: 
*       Resets all active alerts
****************************************************************************/

void reset_alerts()
    {
     int i;
     for(i=0;i<NALERTS;i++)
        { /* reset each */
	 clear_alert(&alerters[i]);
	} /* reset each */
	 
    }

/****************************************************************************
*                                IO_indicator
* Inputs:
*       int code: Alert code to be tested for
* Result: boolean
*       true if indicator was on
*	false if indicator was off
* Effect: 
*       resets the indicator 
****************************************************************************/

boolean IO_indicator(short code)
    {
     boolean was = false;
     int i;
     for(i=0;i<NALERTS;i++)
	 if(alerters[i].code == code)
	    { /* found alert */
	     was = alerters[i].active;
	     if(was)
	     	clear_alert(&alerters[i]);
	     break;
	    } /* found alert */
     return was;
    }
