/*****************************************************************************
*           Change Log
*  Date     | Change
*-----------+-----------------------------------------------------------------
* 24-Dec-85 | [1.231] Created change log
* 24-Dec-85 | [1.231] Added CE panel support
* 24-Dec-85 | [1.233] hide/show mouse cursor around display operation (avoid
*           | rewriting bogus character under cursor!)
* 24-Jan-86 | [1.311] Save cursor around screen redraw
* 22-Feb-86 | [1.362] Re-enabled active display page management for handling
*           | instantaneous displays on color screen
* 22-Feb-86 | [1.362] include <> => include ""
* 23-Feb-86 | [1.366] Hide/display mouse cursor around page selections so it
*           | isn't lost accidently
* 23-Feb-86 | [1.368] markscreen now takes 4 color args
* 31-Jul-86 | [1.405] Made char variables unsigned
*  6-Aug-86 | [1.410] mark_screen_color gets proper argument declarations
*  6-Aug-86 | [1.410] Cast scattrib arg 3 to correct type
* 18-Aug-86 | [1.414] screen.h -> bscreen.h
* 18-Aug-86 | [1.415] _curpage -> b_curpage
* 18-Aug-86 | [1.417] change monochrome display to show/invisible the
*           | lights
* 19-Aug-86 | [1.420] Added setcolor; call it for markscreen and mark_screen
* 19-Aug-86 | [1.423] Added debugcolor.h and ifs on it
* 10-Nov-91 | [1.428] <jmn> converted for microsoft C 6.0
*****************************************************************************/
#include "boolean.h"
#include "graph.h"

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

#include "display.h"
#include "hercules.h"
#include "disp.h"
#include "kb.h"
#include "scan.h"
#include "debugcolor.h"
#include "periph.h"
#include "color.h"
#include "data.h"
#include "1401.h"
#include "select.h"
#include "vprinter.h"

#if debugcolor
#include "diag.h"
#endif

int display; 
extern void select_other_display_page();
extern void activate_display_page();

/****************************************************************************
*                               showing_console
* Result: boolean
*       true if console display active
*	false otherwise
****************************************************************************/

boolean showing_console()
    {
     return display == CONSOLE;
    }

/****************************************************************************
*                             showing_peripherals
* Result: boolean
*       true if we are showing the peripherals screen
*	false if we are not
****************************************************************************/

boolean showing_peripherals()
    {
     return display == PERIPHERALS;
    }


/****************************************************************************
*                                 showing_ce
* Result: boolean
*       true if showing ce panel
*	false if not
****************************************************************************/

boolean showing_ce()
    {
     return display = CEPANEL;
    }

/****************************************************************************
*                                 set_display
* Inputs:
*       int style: Sets display mode
* Result: int
*       Previous display mode
* Effect: 
*       Sets the display mode.
****************************************************************************/

short set_display(short style)
    {
     short oldstyle;

     oldstyle = display;
     display = style;
     return oldstyle;
    }

/****************************************************************************
*                             draw_current_screen
* Effect: 
*       Redraws the currently displayed screen
****************************************************************************/

void draw_current_screen()
    {
     coord x;
     coord y;

     hide_mouse_cursor();

     sccurpos(&y, &x);

/* The following sequence is designed to get around a defect in the
   msmouse level 4.0 software, in which the text cursor is displayed
   only on page 0.  We switch to page 1, clear it, display it, switch
   to page 0, clear it, draw the desired display, then display it.

   If they ever fix this, remove the lines marked msmouse kludge. 

   Ecchh!
*/

#if 0 /* don't do this for Microsoft C 6.0 */
     select_other_display_page();		/* select other page */

     scclear();					/* msmouse kludge */

     activate_display_page();			/* msmouse kludge */

     select_other_display_page();		/* msmouse kludge */
#endif

     switch(display)
        { /* decode */
	 case CONSOLE: 
		 drawscreen();
		 break;
	 case PERIPHERALS: 
		 draw_peripherals_screen();
		 break;
	 case CEPANEL: 
		 draw_ce_panel();
		 break;
	 case VPRINTER:
		 draw_vprinter();
		 break;
	} /* decode */

     sccurset(y, x);
     
#if 0 /* not for C 6.0 */
     activate_display_page();
#endif

     show_mouse_cursor();


    }

/****************************************************************************
*                                  setcolor
* Inputs:
*       boolean set: Select color for true or false condition
*	attrib * fore:  Foreground color to use (output)
*	attrib * back:  Background color to use (output)
*	attrib t_fore:  Foreground color to select if true
*	attrib t_back:  Background color to select if true
*	attrib f_fore:  Foreground color to select if false
*	attrib f_back:  Background color to select if false
* Result: void
*       
* Effect: 
*       Computes the foreground and background colors to be used for the
*	set operation.
*	If a color display, uses t_fore, t_back or f_fore, f_back as
*	based on 'set'
*	If a mono display, selects a color based on the decode table
*
*	    	----color---	---------mono---------
*	    	fore	back	fore	back	effect
*		====    ====    ====    ====	======
*	    A.	color	black	7	0	normal
*	    B.	black	color	0 	7	reverse
*	    C.	black	black	0	0	off
****************************************************************************/

void setcolor(boolean set,attrib * fore,attrib * back,
		attrib t_fore,attrib t_back,
		attrib f_fore,attrib f_back)
    {
     if(ismono())
        { /* mono */
	 if(set)
	    { /* on */
	     if(t_fore != BLACK)
	        { /* Case A. */
		 *fore = H_NORMAL;
		 *back = H_INVISIBLE;
		} /* Case A. */
	     else
	        { /* case B. or C. */
		 *fore = H_INVISIBLE;

		 if(t_back == BLACK)
		    { /* Case C. */
		     *back = H_INVISIBLE;
		    } /* Case C. */
		 else
		    { /* case B. */
		    *back = H_NORMAL;		     
		    } /* case B. */
		} /* case B. or C. */
	    } /* on */
	 else
	    { /* off */
	     if(f_fore != BLACK)
	        { /* Case A. */
		 *fore = H_NORMAL;
		 *back = H_INVISIBLE;
		} /* Case A. */
	     else
	        { /* Case B. or C. */
		 *fore = H_INVISIBLE;
		 if(f_back == BLACK)
		    { /* Case C. */
		     *back = H_INVISIBLE;
		    } /* Case C. */
		 else
		    { /* Case B. */
		     *back = H_NORMAL;		     
		    } /* Case B. */
		} /* Case B. or C. */
	    } /* off */
	} /* mono */
     else
        { /* color */
	 *fore = (set ? t_fore : f_fore);
	 *back = (set ? t_back : f_back);
	} /* color */

#if debugcolor
      sprintf(diag_buffer,"setcolor(%s,0x%x,0x%x,%d,%d,%d,%d) [%d,%d]",
      	(set ? "true" : "false"),
	fore,
	back,
	t_fore,
	t_back,
	f_fore,
	f_back,
	*fore,
	*back);
	tell(diag_buffer);
#endif
    }

/****************************************************************************
*                                 markscreen
* Inputs:
*       short row: Row to mark
*	short column: Column to mark
*	boolean set: true to highlight, false to unhighlight
*	short t_fore: Color to set character to for 'true'
*	short t_back: Color to set background to for 'true'
*	short f_fore: Color to set character to for 'false'
*	short f_back: Color to set background to for 'false'
* Effect: 
*       Sets the mode of the screen.
*
*	If monochrome, set "true" sets the color to reverse video, "false"
*	sets it to normal video.
*
*	If color, set "true" sets the f/b ground to the indicated colors and
*	false sets the color to  and the
*	background black.
****************************************************************************/

void markscreen(coord row,coord column,boolean set,
			attrib t_fore,attrib t_back,
			attrib f_fore,attrib f_back)
    {
     unsigned char ch;
     attrib fore;
     attrib back;

     sccurset(row, column);
	      
     ch = scread(&fore,&back);

     setcolor(set,&fore,&back,t_fore,t_back,f_fore,f_back);

     scattrib(fore,back,(char) ch,1);
    }

/****************************************************************************
*                          select_other_display_page
*
* Effect: 
*       Selects the "other" display page.  The page is one different than
*	the current active display page.
****************************************************************************/

#if 0 /* Not applicable to Microsoft C 6.0 */
void select_other_display_page()
    {
     short active_page;
     short mode;
     short columns;

     if(!ismono())
        { /* color */
	 scmode(&mode,&columns,&active_page);
	 if(active_page != 0) active_page = 0;
	 else active_page = 1;
	 scpage(active_page);
	} /* color */
    }
#endif

/****************************************************************************
*                            activate_display_page
* Effect: 
*       The current display page is activated
****************************************************************************/

#if 0 /* Not done for C 6.0 */
void activate_display_page()
    {
     if(ismono())
	scapage(b_curpage);
    }
#endif

/****************************************************************************
*                                 mark_screen
* Inputs:
*       coord X: screen X position of legend
*	coord Y: screen Y position of legend
*	char * msg: message to display
*	boolean set: true to highlight, false to unhighlight
* Effect: 
*       Highlights the button 
****************************************************************************/

void mark_screen(coord X,coord Y,char * msg,boolean set)
    {
     attrib fore;
     attrib back;
     setcolor(set,&fore,&back,BLACK,WHITE,WHITE,BLACK);
#if debugcolor
     sprintf(diag_buffer,"mark_screen(%d,%d,\"%s\",%s) [%d,%d]",
     		X,Y,
		msg,
		(set ? "true" : "false"),
		fore,back);
      tell(diag_buffer);
#endif
     scdspmsg(Y,X,fore,back,msg);
    }

/****************************************************************************
*                              mark_screen_color
* Inputs:
*       coord X: X-position to start message
*	coord Y: Y-position to start message
*	char * msg: Message to display
*	boolean set: True to mark 'on', false to mark 'off'
*	attrib t_fore: on-color for foreground
*	attrib t_back: on-color for background
*	attrib f_fore: off-color for foreground
*	attrib f_back: off-color for background
* Effect: 
*       Marks the screen.  If in monochrome mode, the on-color is reverse
*	video and the off-color is normal video.
*
*	If a color display, the on-color is the background color (and the
*	letters are displayed in black), while the off-color is the
*	color of the letters with the background black.
****************************************************************************/

void mark_screen_color(coord X,coord Y,char * msg,
			boolean set,
			attrib t_fore,
			attrib t_back,
			attrib f_fore,
			attrib f_back)
    {
     attrib fore;
     attrib back;

     setcolor(set,&fore,&back,t_fore,t_back,f_fore,f_back);

#if debugcolor
     sprintf(diag_buffer,"mark_screen_color(%d,%d,\"%s\",%s,%d,%d,%d,%d) [%d,%d]",
     		X,Y,
		msg,
		(set ? "true" : "false"),
		t_fore,t_back,
		f_fore,f_back,
		fore,back);
      tell(diag_buffer);
#endif
     scdspmsg(Y,X,fore,back,msg);
    }
