/*****************************************************************************
*           Change Log
*  Date     | Change
*-----------+-----------------------------------------------------------------
* 15-Nov-85 | [1.30] Created
* 14-Dec-85 | [1.190] Added test_SS, made last_card not be identical to SS A
* 14-Dec-85 | [1.194] in_ss uses 'bounded' call
* 14-Dec-85 | [1.194] wait for mouse up after toggling switch
* 14-Dec-85 | [1.194] Do not turn off last_card on test; requires explicit
*           | action from device or start-reset
* 24-Jan-86 | [1.307] Use ss_width-1 to fix problem where switch+1 position
*           | also toggled switch
* 22-Feb-86 | [1.364] printf -> scdspmsg to support color
* 22-Feb-86 | [1.364] include <> => include ""
* 25-Feb-86 | [1.378] Use color.h, control legend and outline separately
* 31-Jul-86 | [1.406] Log sense switch change event
* 10-Nov-91 | [1.428] <jmn> converted to Microsoft C 6.0
*****************************************************************************/


/*****************************************************************************
				 1401 Emulator

			      Sense Switch Module

This modules implements the 1401 sense switches, including display, setting,
clearing, and sensing

*****************************************************************************/
#include "stdio.h"
#include "boolean.h"

#include "btypes.h"
#include "scdspmsg.h"

#include "panel.h"
#include "diag.h"
#include "hercules.h"
#include "disp.h"
#include "kb.h"
#include "scan.h"
#include "display.h"
#include "1401.h"
#include "button.h"
#include "switches.h"
#include "color.h"

sense_switch SSs[NSS] = {
		{ ss_X+0*ss_delta, ss_Y, 'A', false}, 
		{ ss_X+1*ss_delta, ss_Y, 'B', false}, 
		{ ss_X+2*ss_delta, ss_Y, 'C', false}, 
		{ ss_X+3*ss_delta, ss_Y, 'D', false}, 
		{ ss_X+4*ss_delta, ss_Y, 'E', false}, 
		{ ss_X+5*ss_delta, ss_Y, 'F', false}, 
		{ ss_X+6*ss_delta, ss_Y, 'G', false}};

boolean last_card = false;

/****************************************************************************
*                                   draw_ss
* Inputs:
*       sense_switch * SS: Sense switch to draw
* Effect: 
*       Draws the sense switch
****************************************************************************/

void draw_ss(sense_switch * SS)
    {
     char msg[10];
     attrib fore;
     attrib back;
     attrib b_fore;
     attrib b_back;
     attrib h_fore;
     attrib h_back;

     if(ismono())
        { /* mono */
	 fore = H_NORMAL;
	 back = 0;
	 b_fore = H_NORMAL;
	 b_back = 0;
	 h_fore = H_NORMAL;
	 h_back = 0;
	} /* mono */
     else
        { /* color */
	 fore = COLOR_WHITE;
	 back = COLOR_BLACK;
	 b_fore = control_fore;
	 b_back = control_back;
	 h_fore = legend_fore;
	 h_back = legend_back;
	} /* color */

     hide_mouse_cursor();
     scdspmsg(SS->Y,SS->X,b_fore,b_back,"ÉÍ Í»");
     sprintf(msg,"%c",SS->id);
     scdspmsg(SS->Y,(coord)(SS->X+2),h_fore,h_back,msg);
     scdspmsg((coord)(SS->Y+1),SS->X,b_fore,b_back,"º   º");
     mark_screen((coord)(SS->X+1),(coord)(SS->Y+1)," on",SS->active);
     scdspmsg((coord)(SS->Y+2),SS->X,b_fore,b_back,"º   º");
     mark_screen((coord)(SS->X+1),(coord)(SS->Y+2),"off",(boolean)!SS->active);
     scdspmsg((coord)(SS->Y+3),SS->X,b_fore,b_back,"ÈÍÍÍ¼");
     show_mouse_cursor();

    }

/****************************************************************************
*                                  in_ss
* Inputs:
*       coord X: X-screen coordinate
*	coord Y: Y-screen coordinate
*	sense_switch * SS: Button descriptor
* Result: boolean
*       true if cursor is on button
*	false otherwise
****************************************************************************/

boolean in_ss(coord X,coord Y,sense_switch * SS)
    {
     return bounded(X,Y,SS->X,SS->Y,(coord)(SS->X+ss_width-1),
     				    (coord)(SS->Y+ss_height));
    }

/****************************************************************************
*                             draw_sense_switches
* Effect: 
*       Draws the sense switches on the panel
****************************************************************************/

void draw_sense_switches()
    {
     short i;

     for(i=0;i<NSS;i++) draw_ss(&SSs[i]);
    }

/****************************************************************************
*                                   ss_flip
* Inputs:
*       sense_switch * SS: Switch to flip
* Effect: 
*       Changes the state of the switch
****************************************************************************/

void ss_flip(sense_switch * SS)
    {
     SS->active = !SS->active;
     if(diagnostics_on)
        { /* log it */
	 char msg[80];
	 sprintf(msg,"Switch %c %s",SS->id,(SS->active ? "ON" : "OFF"));
	 log_console_event(msg);
	} /* log it */
     draw_ss(SS);
     clear_off();
    }

/****************************************************************************
*                               check_switches
* Inputs:
*       coord X: screen coordinate of mouse hit
*	coord Y: screen coordinate of mouse hit
* Effect: 
*       If in a sense switch, changes its setting
****************************************************************************/

void check_switches(coord X,coord Y)
    {
     short i;

     for(i=0;i<NSS;i++)
     {
      if(in_ss(X,Y,&SSs[i])) 
	  {
	   ss_flip(&SSs[i]);
	   wait_for_mouse_up();
	   break;
	  }
     }
    }

/****************************************************************************
*                                 set_cdr_eof
* Effect: 
*       Turns on last card indicator, which is also sense switch A
****************************************************************************/

void set_cdr_eof()
    {
     last_card = true;
    }

/****************************************************************************
*                                clear_cdr_eof
* Effect: 
*       Clears the card reader EOF
****************************************************************************/

void clear_cdr_eof()
    {
     last_card = false;
    }

/****************************************************************************
*                                   test_SS
* Inputs:
*       short d: Switch to test, one of 'A'..'G' encoded as 0..6
* Result: boolean
*       true if switch is on
*	false if switch is off
****************************************************************************/

boolean test_SS(short d)
    {
#if 1
	if(d > 6) 
	   { /* bad */
	    sprintf(diag_buffer,"Illegal SS value %d",d);
	    tell(diag_buffer);
	   } /* bad */
#endif     
     if(diagnostics_on)
        { /* tell test */
	 sprintf(diag_buffer,"Testing sense switch %c: %s",
	 		d+'A',(SSs[d].active ? "on" : "off"));
	 tell(diag_buffer);
	} /* tell test */
     if(d == 0 && last_card)
        { /* BLC */
	 return true;
	} /* BLC */
     return SSs[d].active;
    }
