Program NDC_Demo (Input, Output);

(* J. R. Senning
 * Shepherd College
 * April 1993
 *
 * This is a demonstration program for the NDC package.
 *)

Uses
    Crt, NDC;

Const
    BarX	= 0.9;
    BarDx	= 0.03;
    BarDy	= 0.04;
    BarYSpace	= 0.0625;

Var
    Done		: Boolean;
    Device		: DeviceType;
    KeyMeasure		: KeyboardMeasure;
    LocMeasure		: LocatorMeasure;
    Last_Position	: Point;
    V			: VertexList;
    NumPoints		: Integer;

(*-------------------------------------------------------------------------*)

Procedure ColorBar (NColor : Integer);

(*
 * Draws a color bar on the right hand side of the display.  Uses
 * the BarX and BarYspace constants to determine location of the
 * bar and the BarDx and BarDy constants to determine the size of the
 * color regions.
 *)

Var
    I	: Integer;
    Y	: Real;

Begin
    (*
     * Set polygon file pattern.  Could also be SOLID_BIT_PATTERN,
     * MEDIUM_GRAY_BIT_PATTERN or DIAGONAL_BIT_PATTERN.
     *)
    NDC_SetFillStyle (BITMAP_PATTERN_OPAQUE);
    NDC_SetFillBitmapPattern (BRICK_BIT_PATTERN);

    (*
     * Loop through the specified number of colors, displaying color
     * filled rectangles for each color of the palette.
     *)
    For I := 0 to NColor do Begin
	Y := I * BarYSpace;
	NDC_SetColor (I);	{Interior color}
	NDC_FillRectangleCoord (BarX, Y, BarX+BarDx, Y+BarDy);
	NDC_SetColor (WHITE);	{Border color}
	NDC_RectangleCoord (BarX, Y, BarX+BarDx, Y+BarDy);
    End; {For}
End; {ColorBar}

(*-------------------------------------------------------------------------*)

Procedure Process_Left_Button_Press (Var P, Last_P : Point);

(*
 * This procedure is called every time the left-hand button of the
 * locator (mouse) is pressed.  It determines if the button was
 * pressed while the the locator was inside one of the color regions of
 * the color bar.  If so then a new line color is established and a
 * text string is sent to the upper right hand corner of the display
 * to indcate the current color.  If the button was pressed anywhere
 * outside of the color bar regions, a line is drawn in the current
 * color from the last position to the locator position.
 *)

Const
    ColorText	= 'Current Color';

Var
    Found	: Boolean;
    I		: Integer;
    Y		: Real;
    TextLoc	: Point;
    W, H, D	: Real;

Begin
    (*
     * Determine if mouse was pressed inside a color rectangle.
     *)
    I := 0;
    Repeat
	Y := I * BarYSpace;
	I := I + 1;
	Found := (BarX <= P.X) and (P.X <= BarX+BarDx) and
		 (Y <= P.Y) and (P.Y <= Y+BarDy);
    Until Found or (I > 15);

    If Found then Begin
	(*
	 * Inside color rectangle, set new color and update text
	 *)
	NDC_SetColor (I-1);
	NDC_InquireTextExtent (ColorText, W, H, D);
	NDC_DefPoint (W / 2.0, 1.0 - H / 2.0, TextLoc);
	NDC_Text (TextLoc, ColorText);
    End Else Begin
	(*
	 * Need to draw line from last position to new position.
	 *)
	NDC_Line (Last_P, P);
	Last_P := P;
    End; {Else}
End; {Process_Left_Button_Press}

(*-------------------------------------------------------------------------*)
(*-------------------------------------------------------------------------*)
(*-------------------------------------------------------------------------*)

Begin
    (*
     * Display simple instructions and wait for the user to press
     * return before starting the graphics.
     *)
    ClrScr;
    Writeln ('Demonstration Program for NDC Package');
    Writeln ('Draws a simple house and then waits for the user to draw lines');
    Writeln;
    Writeln ('Type q or Q to Quit');
    Writeln;
    Writeln ('Left-hand mouse button:');
    Writeln ('      Outside color squares: Line from center of screen to current position');
    Writeln ('      Inside color square:   Select color for subsequent lines');
    Writeln;
    Writeln ('Right-hand mouse button:');
    Writeln ('      Quit');
    Writeln;
    Write ('Press Return to continue...');
    Readln;

    (*
     * Initialize the NDC graphics.  Set both the keyboard and the locator
     * to event mode.  Put the keyboard in raw mode so that single key-
     * presses are separate events.  Register both the left and right
     * locator buttons so that a press or release of either will generate
     * an event.  Initialize the marker.
     *)
    NDC_Begin (640, 480);
    NDC_SetInputMode (KEYBOARD, EVENT);
    NDC_SetKeyboardProcessingMode (RAW);
    NDC_SetInputMode (LOCATOR, EVENT);
    NDC_SetLocatorButtonMask ([LEFT_BUTTON, RIGHT_BUTTON]);
    NDC_SetLocatorEchoType (RUBBER_LINE);
    NDC_SetMarker ('*');

    (*
     * The initial value to draw from is the center of the screen
     *)
    NDC_DefPoint (0.5, 0.5, Last_Position);

    (*
     * Draw the color bar
     *)
    ColorBar (15);

    (*
     * Draw a "house" on the screen.
     *)
    NDC_DefPoint (0.15, 0.55, V[1]);
    NDC_DefPoint (0.25, 0.35, V[2]);
    NDC_DefPoint (0.25, 0.05, V[3]);
    NDC_DefPoint (0.05, 0.05, V[4]);
    NDC_DefPoint (0.05, 0.35, V[5]);
    NDC_DefPoint (0.15, 0.55, V[6]);
    NumPoints := 6;
    NDC_SetColor (LIGHT_RED);
    NDC_PolyMarker (NumPoints-1, V);
    NDC_SetColor (WHITE);
    NDC_PolyLine (NumPoints, V);

    (*
     * Begin main loop, continuing until Done becomes true.  This is an
     * event driven loop.
     *)
    Done := False;
    Repeat
	NDC_WaitEvent (INDEFINITE, Device);
	Case Device of
	    KEYBOARD:
		Begin
		    (*
		     * Keyboard event has occured, see what key was pressed.
		     * If it was a q or Q we will quit, otherwise ignore it.
		     * Notice that we do not halt here, but Done becomes
		     * true.  This allows us to exit gracefully.
		     *)
		    NDC_GetKeyboard (KeyMeasure);
		    Done := (KeyMeasure[1] = 'q') or (KeyMeasure[1] = 'Q');
		End; {KEYBOARD}
	    LOCATOR:
		Begin
		    (*
		     * Locator event has occured, i.e., a button has been
		     * pressed.  Get the measure of the locator (state when
		     * button was pressed).  If the button pressed was the
		     * left-hand button then process it.  If the right-hand
		     * button was pressed then set Done to true so that
		     * we can quit gracefully.
		     *)
		    NDC_GetLocator (LocMeasure);
		    With LocMeasure do
			Case ButtonOfMostRecentTransition of
			    LEFT_BUTTON:
				If (ButtonChord[LEFT_BUTTON] = DOWN) then Begin
				    Process_Left_Button_Press (Position,
				    			Last_Position);
				End; {If}
			    RIGHT_BUTTON:
				Done := True;
			End; {Case}
		End; {LOCATOR}
	End; {Case}
    Until Done;

    (*
     * Ok, done with main loop, now turn off the graphics and leave.
     *)
    NDC_End;
End.
