	with
	  CharAK,
	  ErroAKD,
	  MathAKD,
	  ScrnAKD,
	  StriAKD,
	  Tty;

	package body KeybAKD is
	----------------------------------------------------------------------
	-- Copyright (C) 1994 David Wallace Croft.  All rights reserved.
	----------------------------------------------------------------------

	function  Ask ( Question: in string;
			Default : in HexaAKD.Hex8
			  := ( others => HexaAKD.HexChar'val ( 0 ) )
		   ) return HexaAKD.Hex8 is
	---------------------------------------------------------------------------
	  Temp : string ( 1..8 );
	begin
	  Ask ( Question & " [" & HexaAKD.Hex_To_Str ( Default ) & "]:  ",
	 Temp, "0-9A-F" );
	  if Temp ( 1 ) = ASCII.Nul then
	 return Default;
	  else
	 return HexaAKD.Str_To_Hex ( Temp );
	  end if;
	end Ask;

	function  Ask ( Question: in string; Default: in float ) return float is
	---------------------------------------------------------------------------
	  AnsStr   : string ( 1..float'digits + 1 );
	  Answer   : float;
	  Is_Float : boolean := false;
	begin
	  loop
	 ScrnAKD.Put ( Question & "[" & StriAKD.Image ( Default )
	   & "]:  ");
	 KeybAKD.Ask ( "", AnsStr, "0-9+--,._0-9,._0-9,._0-9E,._0-9E+--" );
	 if AnsStr ( 1 ) = ASCII.NUL then
	   Answer := Default;
	   exit;
	 end if;
	 MathAKD.Float_String ( AnsStr, Is_Float, Answer );
	 exit when Is_Float;
	 ScrnAKD.Put_Line ( ASCII.BEL & "Please try again." );
	  end loop;
	  return Answer;
	exception
	  when others =>
	 ErroAKD.Notify ( "KeybAKD.Ask ( string; float ) return float" );
	 raise;
	end Ask;

	function  Ask (
		 Question : in string;
		 Min      : in long_integer;
		 Max      : in long_integer;
		 Default  : in long_integer ) return long_integer is
	---------------------------------------------------------------------------
	  AnsStr: string ( 1..long_integer'width );
	  Temp : long_integer;
	begin
	  Ask ( Question & " (" & StriAKD.Image ( Min ) & " to "
	 & StriAKD.Image ( Max ) & ") [" & StriAKD.Image ( Default ) & "]:  ",
	   AnsStr, "0-9+-" );
	  if AnsStr ( 1 ) = ASCII.Nul then
	 return Default;
	  end if;
	  Temp := long_integer'value ( AnsStr );
	  if ( Temp >= Min ) and then ( Temp <= Max ) then
	 return Temp;
	  else
	 return Default;
	  end if;
	end Ask;

	function  Ask ( Question: in string; Max: in positive ) return natural is
	---------------------------------------------------------------------------
	  AnsStr: string ( 1.. ( positive'image ( Max )'last-1 ) );
	begin
	  Ask( Question & " (0 to" & positive'image(Max) & "):  ", AnsStr, "0-9");
	  return natural'value(AnsStr);
	exception
	  when others =>
	 ErroAKD.Notify("KeybAKD.Ask(string;positive)");
	 raise;
	end Ask;

	procedure Ask(
		 Question: in string;
		 Answer: out character;
		 Definition_Str: in string := "") is
	---------------------------------------------------------------------------
	  Answer_Str : string ( 1..1 );
	begin
	  Ask ( Question, Answer_Str, Definition_Str );
	  Answer := Answer_Str ( 1 );
	end Ask;

	procedure Ask(
		 Question      : in     string;
		 Answer        :    out string;
		 Definition_Str: in     string := "") is
	---------------------------------------------------------------------------
	  Answer_Index: positive range 1..(Answer'last + 1) := 1;
	  In_Char: character;
	  Valid_Characters: StriAKD.Valid_Characters_Type(Answer'range);
	begin
	  StriAKD.Define_Valid_Characters ( Valid_Characters, Definition_Str );
	  ScrnAKD.Put ( Question );
	  loop
	 In_Char := CharAK.Upcase ( Tty.Get ( No_Echo => true ) );
	 if In_Char = ASCII.CR then
	   ScrnAKD.Put_Line;
	   for index in Answer_Index..Answer'last loop
		Answer ( index ) := ASCII.Nul;
	   end loop;
	   exit;
	 end if;
	 if ( Answer_Index = Answer'last + 1 ) and ( In_Char /= ASCII.BS ) then
	   ScrnAKD.Beep;
	 else
	   if In_Char = ASCII.BS then
		if Answer_Index = 1 then
		  ScrnAKD.Beep;
		else
		  ScrnAKD.Put ( ASCII.BS & ' ' & ASCII.BS );
		  Answer_Index := Answer_Index - 1;
		end if;
	   else
		if Valid_Characters ( Answer_Index ) ( In_Char ) then
		  Answer ( Answer_Index ) := In_Char;
		  Answer_Index := Answer_Index + 1;
		  ScrnAKD.Put ( In_Char );
		else
		  ScrnAKD.Beep;
		end if;
	   end if;
	 end if;
	  end loop;
	--  ScrnAKD.Put_Line;
	exception
	  when others => ErroAKD.Notify("KeybAKD.Ask(string)");
			 raise;
	end Ask;

	procedure Get_Line ( Get_Str: out string; Upcase: in boolean := false ) is
	---------------------------------------------------------------------------
	  Count: natural := 1;
	  In_Char: character;
	  In_Str: string(Get_Str'range);
	begin
	  loop
	 In_Char := Tty.Get(true);
	 if (Count = In_Str'last + 1) and
	   ((In_Char /= ASCII.CR) and (In_Char /= ASCII.BS)) then
		ScrnAKD.Beep;
	 elsif In_Char = ASCII.BS then
	   if Count = 1 then
		ScrnAKD.Beep;
	   else
		Tty.Put(ASCII.BS);
		Tty.Put(' ');
		Tty.Put(ASCII.BS);
		Count := Count - 1;
	   end if;
	 elsif In_Char = ASCII.CR then
	   exit;
	 else
	   if Upcase then
		In_Str(Count) := CharAK.Upcase(In_Char);
	   else
		In_Str(Count) := In_Char;
	   end if;
	   Tty.Put(In_Str(Count));
	   Count := Count + 1;
	 end if;
	  end loop;
	  for index in Count..In_Str'last loop
	 In_Str(index) := ASCII.Nul;
	  end loop;
	  ScrnAKD.Put_Line;
	  Get_Str := In_Str;
	exception
	  when others =>
	 ErroAKD.Notify("KeybAKD.Get_Line");
	 raise;
	end Get_Line;

	procedure Pause is
	---------------------------------------------------------------------------
	  DumChar: character;
	begin
	  ScrnAKD.Put("Please press ENTER to continue...");
	  DumChar := Tty.Get;
	  ScrnAKD.ClrL;
	end Pause;

	procedure Pause(PauseStr: in string) is
	---------------------------------------------------------------------------
	begin
	  ScrnAKD.Put_Line(PauseStr);
	  KeybAKD.Pause;
	end Pause;

	---------------------------------------------------------------------------
	---------------------------------------------------------------------------
	end KeybAKD;
