subroutine StdIn(Col,Row,Len,Mat,Min,Max,Cnv,Fmt,Req,Def,Hlp,Spc,Cmd,Res)
***
* Abstract
*    Subroutine to prompt on screen and edit a value based on match
* pattern, minimum value, maximum value and default value.
* Argument list:
*    Row - Row where prompting will occur.
*    Col - Column where prompting will occur.
*    Len - Length of prompt field.
*    Mat - Match pattern to filter data.
*    Min - Minimum acceptable value.
*    Max - Maximum acceptable value.
*    Cnv - Conversion used when displaying value.
*    Fmt - Format used when displaying value.
*    Req - Boolean indicating when entry required.
*    Def - Default entry.
*    Hlp - Short, one line, help text.
*    Spc - Special - To pass special processing requests. Format of this
*             field is multivalued. Defined requests are as follows:
*          TRANS(filename,filename,...) - translate field from multiple files
*             to insure entry is valid. Maximum of 10 files in this version.
*          MV(n) - to specify a multivalued entry area n rows down from
*             (Col, Row).
*          UC - Blanket conversion of input to upper-case.
*          LC - Blanket conversion of input to lower-case.
*          PREFIX(x) - Prepend 'x' in front of Res before executing TRANS.
*          SUFFIX(x) - Append 'x' at end of Res before executing TRANS.
*          DISABLE(x,x,...) - Prevents 'x' from being entered at the prompt.
*          PROMPT(x) - Prompt padding character, to indicate field size.
*    Cmd - Control commands to be trapped by StdIn and returned to host.
*    Res - Resultant.
***
* Revision Log
* Who..... When.... Why..................................................
* Andrew   22Feb93  Initial coding.
*
***

* Setup common area for Background and Foreground screens in case StdIn
* needs to redraw the screen.
common /STDCOM/BS, FS

equ True to 1
equ False to 0
equ Others to 1

dim TRANSFile(10)

Err = @(0,23)
EEOL = @(-4)

Error = ""
Error<1> = "Input required at this prompt..."
Error<2> = "Input does not match pattern of: "
Error<3> = "Input cannot be less than "
Error<4> = "Input cannot be greater than "
Error<5> = "Input must be in the format of "
Error<6> = "Input did not survive translation of: "
Error<7> = "Input exceeds maximum length of: "
Error<8> = "Argument for MV option is invalid..."
Error<9> = "Unable to open files for TRANSlate: "
Error<10> = "Entry has been disabled for: "

StdHlp = @(0,23):"Enter '^' to backup to previous field, or 'E' to exit this screen...":EEOL

FncList = convert("~",@FM,"MV~TRANS~UC~LC~PREFIX~SUFFIX~DISABLE~PROMPT")
TRANSing = False
UCing = False
LCing = False
MVing    = False
MVCount = 0
TRANSFileList = ""
TRANSFieldList = ""
TRANSCount = 0
TRANSTest = False
Prefix = ""
Suffix = ""
Disable = ""
Prompt = "#"
DISABLEing = False
MoreSpc = len(Spc)
OpenErrors = ""
loop while MoreSpc do
   remove SpcItem from Spc setting MoreSpc
   Fnc = upcase(field(SpcItem,"(",1))
   Arg = convert(",",@FM,upcase(field(field(SpcItem,"(",2),")",1)))
   locate Fnc in FncList<1> setting FncIdx then
      on FncIdx gosub MVHandle, TRANSHandle, UCHandle, LCHandle, PREFIXHandle,
         SUFFIXHandle, DISABLEHandle, PROMPTHandle
   end
repeat
if TRANSTest then
if OpenErrors then
   crt Err:Error<9>:OpenErrors:EEOL:
end else
   TRANSing = True
end
end

prompt ''
SaveDef = oconv(Def,Cnv)
Step = 1
loop
   if MVing then ;* let's call ourselves to handle the MV section
      for i = 1 to MVCount step Step
         Step = 1
         MVRes = ""
         call *StdIn(Col,Row+i-1,Len,Mat,Min,Max,Cnv,Fmt,Req,Def<1,i>,
            Hlp,"","E":@VM:"^",MVRes)
         begin case
            case upcase(Res) eq "E"
               Res = MVRes
               return
            case upcase(Res) eq "^"
               i -= 1
               Step = 0
               i = if i lt 1 then 1 else i
         end case
         Res<i> = MVRes
      next i
   end
   Clear = space(if len(Res) gt Len then len(Res) else Len)
   Default = fmt(oconv(Def,Cnv),Fmt)
   if len(Default) eq 0 then
      Default = space(Len)
   end
   convert " " to Prompt in Default
   Clear[1,len(Default)] = Default
   crt @(Col,Row):Clear:@(Col,Row):
   input Res
   if len(Res) eq 0 then
      if len(Def) ne 0 then
         Res = SaveDef
      end else
         if Req then crt Err:Error<1>:EEOL:;continue
      end
   end else
      CmdTest = upcase(trim(Res))
      locate CmdTest in Cmd<1,1> setting dummy then
         Clear = space(if Len gt len(Res) then Len else len(Res))
         crt @(Col,Row):Clear:@(0,22):EEOL:@(0,23):EEOL:
         Res = CmdTest
         return
      end
      if Res eq "?" then gosub Help
      if Res eq "?" then continue
      if Res eq "??" then
         ReqTest = if Req then ", required" else ", not required"
         crt @(0,22):"Len=":Len:", Mat=":Mat:", Min=":oconv(Min,Cnv):", Max=":oconv(Max,Cnv):", Cnv=":Cnv:", Fmt=":Fmt:", Def=":SaveDef:", Spc=":Spc:ReqTest:EEOL:
         continue
      end
      if UCing then Res = upcase(Res)
      if LCing then Res = downcase(Res)
      if Mat and not(Res matches Mat) then crt Err:Error<2>:Mat:EEOL:;continue
      if Len and len(Res) gt Len then crt Err:Error<7>:Len:EEOL:;continue
      if DISABLEing then if Res matches Disable then crt Err:Error<10>:Res:EEOL:;continue
   end
   if (len(Cnv) gt 0) and (len(Res) gt 0) then
      Res = iconv(Res, Cnv)
      if status() then gosub ConvError;continue
   end
   if Min and Res lt Min then crt Err:Error<3>:oconv(Min,Cnv):EEOL:;continue
   if Max and Res gt Max then crt Err:Error<4>:oconv(Max,Cnv):EEOL:;continue
   if TRANSing then
      Found = False
      Test = Prefix:Res:Suffix
      for i = 1 to TRANSCount
         readv dummy from TRANSFile(i), Test, TRANSFieldList<1,i> then
            Found = True
         end else
            readv dummy from TRANSFile(i), upcase(Test), TRANSFIeldList<1,i> then
               Res = upcase(Res)
               Found = True
            end
         end
      until Found
      next i
      if not(Found) then
         crt Err:Error<6>:TRANSFileList:EEOL:
         continue
      end
   end
   crt @(Col,Row):fmt(oconv(Res,Cnv),Fmt):@(0,22):EEOL:@(0,23):EEOL:
   exit
repeat
return

MVHandle:
   if num(Arg) then
      MVing = True
      MVCount = Arg
   end else
      crt Err:Error<8>:EEOL:
   end
   return

TRANSHandle:
   TRANSTest = True
   MoreArg = Arg ne ""
   loop while MoreArg do
      remove Item from Arg setting MoreArg
      TRANSFileList<-1> = Item
      TRANSCount += 1
      open "",Item to TRANSFile(TRANSCount) else
         OpenErrors := Item:" "
      end
   repeat
   return

UCHandle:
   UCing = True
   return

LCHandle:
   LCing = True
   return

PREFIXHandle:
   Prefix = Arg<1>
   return

SUFFIXHandle:
   Suffix = Arg<1>
   return

DISABLEHandle:
   Disable = Arg
   if Disable then DISABLEing = True
   convert @FM to @VM in Disable
   return

PROMPTHandle:
   Prompt = Arg
   return

ConvError:
   begin case
      case Cnv matches "D..."
         Spec = "a date."
      case Cnv matches "MD..."
         Spec = "a masked decimal numer."
      case Cnv matches "MT..."
         Spec = "time (i.e. HH:MM[:SS])."
      case 1
         Spec = Cnv
   end case
   crt Err:Error<5>:Spec:EEOL:
   return

Help:
if TRANSing then
   Selection = ""
   call std.picklist(TransFileList, Fmt, Selection)
   crt BS:FS:
   if Selection ne "" then
      Res = Selection
      crt @(Col,Row):fmt(oconv(Res,Cnv),Fmt):
   end else
      Res = "?"
   end
end else
   crt Err:Hlp:EEOL:
end
return

end
