(*
( FILENAME: QuickGraph.Pas
(   Main driver for Quick Graph
(
( CONTENTS: CloseDataFile
(			ChkGraType
(			Color_Hdw
(			ConfirmFinish
(			Create_or_Edit
(			DisplayFKeys
(			DisplayFunctionKey
(			InitVideo
(			GetEditFileSpec
(			OpenDataFile
(			OverWriteOk
(			ParamInit
(			ParamSetSimple
(			ParamListStart
(			ParamSetNextInList
(			RemoveBlanks
(			Read_A_Byte
(			ReadDataFile
(			Read_the_FieldB
(			Read_the_FieldC
(			WriteDataFile
(			Write_the_FieldB
(			Write_the_FieldC
(			WriteStatusLine
(			ZipBGP
(
( REVISION HISTORY
(
( VERSION	DATE		BY DESCRIPTION
( 			 
(
(	2.3		121991	CB	Check fColorMonitor in QueryVidHdw to determine if 
(							color monitor is present, check for ArtDesigner.Run
(	2.2		022790	CB	If run under Context Manager, QG now returns
(							to the CM screen not the Command line.
(	2.1.1	020189	CB	Expand size of some LString variables
(							to 50 characters (see LineMod.Pas)
(	2.1		112688	CB	Protected mode, supports OFIS Graphics
(							(16 Pie Slices)
(	2.0		021287	TM	Allow as much data as memory permits
(	1.3.1	053186	CB	Cosmetic changes to all the forms.
(	1.3		022586	CB	Eliminated call to OpenDataFile in
(							GetEditFileSpec, used OpenByteStream
(	1.2		021786	CB	Allow retries in OpenDataFile
(	1.1		010885	CB	Changed ZipBGP to look for ExitRunFile
(							and ChainFile on Local then Master disk.
(	1.0		120185	CB	First release
(
(
*)
PROGRAM QuickGraph;
{$Debug}

TYPE 
   Pointer    =  ADS OF WORD;
   LSFileSpec =  LSTRING(50);

CONST 

   B21       =  2;
   Bar       =  0;
   Cancel    =  7;
   ExecExitRunFile  =  '[sys]<sys>Exec.Run';
   CMExitRunFile    =  '[sys]<sys>CMNull.Run';
   F1        =  15;
   F2        =  16;
   F3        =  17;
   F4        =  18;
   F10       =  1F;
   Finish    =  4;
   Go        =  27;
   Line      =  3;
   ModeRead  =  Retype(WORD,'mr');
   NLine     =  2;
   EditNo    =  False;
   Pie       =  1;

VAR [EXTERN]
   WelcomeForm    :  WORD;
   B21WelcomeForm :  WORD;

VAR 

   BsBuf     :  ARRAY[1..1024] OF BYTE;
   BSWA      :  ARRAY[1..130] OF BYTE;
   cbRead    :  WORD;
   Done      :  BOOLEAN;
   Erc       :  WORD;
   ExitState :  RECORD
                   ich[0]       :  WORD;
                   ch[2]        :  WORD;
                   fAutoExit[4] :  BOOLEAN;
                   fModified[6] :  WORD;
                   fEmpty[8]    :  WORD;
                   Reserved[10] :  ARRAY[1..6] OF BYTE;
                END;
   GraphType :  WORD;
   InitState :  ARRAY[1..4] OF WORD;
   KbdByte   :  BYTE;
   Param     :  RECORD
                   pb :  Pointer;
                   cb :  WORD;
                END;
   pMap      :  Pointer;
   MaxLines  :  WORD;
   VidStatus :  RECORD
                   level      [0] :  BYTE;
                   nLinesMax  [1] :  BYTE;
                   nColsNarrow[2] :  BYTE;
                   nColsWide  [3] :  BYTE;
                   bitMapLevel[4] :  BYTE;
                   ignore     [5] :  Array [1..35] of Byte;
                   fColorMon [41] :  Boolean;
                END;
   WsType    :  BYTE;
   fBTOSIIGraphics :  BOOLEAN;

{$Include:'Bs.Edf'}
{$Include:'Forms.Edf'}
{$Include:'Misc.Edf'}
{$Include:'Param.Edf'}
{$Include:'Task.Edf'}
{$Include:'Vid.Edf'}

PROCEDURE AlphaLine_Chart(Editing  : BOOLEAN;
                          FileSpec : LSFileSpec);EXTERN;

PROCEDURE Bar_Chart(Editing  : BOOLEAN;
                    FileSpec : LSFileSpec);EXTERN;

PROCEDURE Line_Chart(Editing  : BOOLEAN;
                     FileSpec : LSFileSpec);EXTERN;

PROCEDURE Pie_Chart(Editing  : BOOLEAN;
                    FileSpec : LSFileSpec;
                    fBTOSIIGraphics : BOOLEAN);EXTERN;

{}
PROCEDURE CloseDataFile[PUBLIC];
{}
BEGIN
   CheckErc(CloseByteStream(ADS BSWA));
END;

{
 Returns TRUE if workstation has a color monitor otherwise 
 returns FALSE.                                            
}
FUNCTION Color_Hdw:  BOOLEAN [PUBLIC];

BEGIN
   IF VidStatus.fColorMon
      THEN Color_Hdw := TRUE
      ELSE Color_Hdw := FALSE;
END;

{
 Asks the user to confirm exiting the program 
}
PROCEDURE ConfirmFinish[PUBLIC];

CONST 
   ConfirmTxt =  'Press Go to confirm finish, Cancel to deny.';
   Blank      =  '                                           ';
   Finishing  =  'Finishing......                            ';
   Go         =  1B;
   Cancel     =  7;

VAR 
   KbdByte :  BYTE;

BEGIN
   REPEAT
      CheckErc(PutFrameChars(1,0,1, ADS ConfirmTxt, Upper(ConfirmTxt)));
      CheckErc(PutFrameAttrs(1,0,1,8,80));
      CheckErc(ReadKbd(ADS KbdByte));
      IF KbdByte = Go
         THEN
            BEGIN
               CheckErc(PutFrameChars(1,0,1, ADS Finishing, Upper(Finishing)));
               Exit;
            END;
      IF KbdByte <> Cancel
         THEN Beep;
   UNTIL KbdByte = Cancel;
   CheckErc(PutFrameChars(1,0,1, ADS Blank, Upper(Blank)));
   CheckErc(PutFrameAttrs(1,0,1,0,80));
END;

{
 Displays a blank Function Key Form at the bottom of 
 the screen (Video frame 2).                         
}
PROCEDURE DisplayFKeys[PUBLIC];

VAR [EXTERN]
   FunctKeysForm :  WORD;

BEGIN
   CheckErc(DisplayForm(ADS FunctKeysForm, 2, 255, 255));
END;

{
 Initialize a Variable Length Parameter Block in Long Lived Memory 
 of size 'MemorySize' to contain 'cParameters' Parameters.         
}
PROCEDURE ParamInit(MemorySize : WORD;
                    cParams    : WORD)[PUBLIC];

VAR 
   ParamBlk :  Pointer;

BEGIN
   CheckErc(ResetMemoryLL);
   CheckErc(AllocMemoryLL(MemorySize, ADS ParamBlk));
   CheckErc(rgParamInit(ParamBlk,MemorySize,cParams));
END;

{
 Load the 'iParameter' with the contents of 'Parameter' 
 into the VLPB.                                         
}
PROCEDURE ParamSetSimple(       iParameter : WORD;
                         CONSTS Parameter  : LSTRING)[PUBLIC];
BEGIN
   Param.pb := ADS Parameter[1];
   Param.cb := Parameter.Len;
   CheckErc(rgParamSetSimple(iParameter,ADS Param))
END;

{
 Initialize the VLPB to accept a list of 
 subparameters for parameter 'Param'.   
}
PROCEDURE ParamListStart(Param : WORD)[PUBLIC];

BEGIN
   CheckErc(rgParamSetListStart(Param));
END;

{
 Load the 'Parameter' as the next subparameter into 
 the VLPB of a previously identified  VLPB parameter 
}
PROCEDURE ParamSetNextInList(CONSTS  Parameter : LSTRING)[PUBLIC];

BEGIN
   Param.pb := ADS Parameter[1];
   Param.cb := Parameter.Len;
   CheckErc(rgParamSetEltNext( ADS Param))
END;

{
 Opens a ByteStream of filespec 'FileName' in mode 'Mode' 
}
FUNCTION OpenDataFile(CONSTS FileName : LSTRING;
                      Mode     : WORD;
                      Graphing : BOOLEAN):  WORD[PUBLIC];

CONST 
   WaitMsg   =  'Please WAIT.....';

VAR 
   LocalErc :  WORD;
   WriteErc :  WORD;
   KbdChar  :  BYTE;
   ErcCode  :  LSTRING(5);
   fDone     :  BOOLEAN;

BEGIN
   REPEAT
      IF Graphing
         THEN CheckErc(PutFrameChars(0, 10, 12, ADS WaitMsg, Upper(WaitMsg)));
      LocalErc := OpenByteStream(ADS BSWA[1], ADS FileName[1], FileName.Len,
                                 ADS NIL,0, Mode, ADS BsBuf[1], SizeOf(BsBuf));
      IF LocalErc = 0
         THEN fDone := True
         ELSE
            BEGIN
               CheckErc(ResetFrame(0));
               Beep;
               CheckErc(PutFrameChars(0,1,12,ADS 'System Error: ',14));
               fDone := Encode(ErcCode,LocalErc:5);
               CheckErc(PutFrameChars(0,15,12,ADS ErcCode[1],ErcCode.Len));
               CheckErc(PutFrameChars(0,1,13,
                        ADS 'Press Go to retry, Finish to exit.',34));
               REPEAT
                  WriteErc := ReadKbd(ADS KbdChar);
               UNTIL (KbdChar = 1B) OR (KbdChar = 04);
               IF KbdChar = 1B
                  THEN fDone := False;
               IF KbdChar = 04
                  THEN fDone := True;
               CheckErc(ResetFrame(0));
            END;
   UNTIL fDone;
   OpenDataFile := LocalErc;
END;

{
 Read 1 byte from the data file and place it in bRet 
 also RETURNS the Error Code                         
}
FUNCTION Read_A_Byte(pbRet : Pointer):  WORD[PUBLIC];

BEGIN
   Read_A_Byte := ReadByte(ADS BSWA, pbRet);
END;

{
 Reads cbData Bytes to pbData from the data file.    
 Returns the actual number of bytes read and the ERC 
}
FUNCTION ReadDataFile(pbData : Pointer;
                      cbData : WORD;
                      psDataRet : Pointer):  WORD[PUBLIC];

BEGIN
   ReadDataFile := ReadBsRecord(ADS BSWA, pbData, cbData, psDataRet);
END;

{
  Reads the BINARY field 'FieldName' with an index of 'Index'  
  from form 'Form'. Places the field data into 'DataRet'.      
}
PROCEDURE Read_the_FieldB(      Form  : Pointer;
                          CONSTS FieldName: LSTRING;
                          Index : WORD;
                          VARS   DataRet  : WORD;
                          ExitState: Pointer);

CONST 
   bType =  'Binary.';

VAR 
   Ok    :  BOOLEAN;

BEGIN
   Ok := False;
   REPEAT
      InitState[1] := 0;
      CheckErc(UserFillField(Form, ADS FieldName[1], FieldName.Len, Index,
               ADS InitState[1], ExitState));
      Erc := ReadField(Form, ADS FieldName[1], FieldName.Len, Index,
             ADS DataRet, 2, ADS cbRead, ADS bType);
      Ok := True;
      IF Erc = 3708
         THEN
            BEGIN
               Beep;
               Ok := False
            END;
   UNTIL Ok;
END;

{
  Reads the CHARACTER field 'FieldName' with an index of 'Index' 
  from form 'Form'. Places the field data into 'DataRt'.         
}
PROCEDURE Read_the_FieldC(      Form  : Pointer;
                          CONSTS FieldName: LSTRING;
                          Index : WORD;
                          VARS   DataRt : LSTRING;
                          DataRetMax: WORD;
                          ExitState : Pointer)[PUBLIC];

CONST 
   cType =  'Character.';

BEGIN
   InitState[1] := 0;
   CheckErc(UserFillField(Form, ADS FieldName[1], FieldName.Len, Index,
            ADS InitState[1], ExitState));
   CheckErc(ReadField(Form, ADS FieldName[1], FieldName.Len,Index,
            ADS DataRt[1], DataRetMax, ADS cbRead, ADS cType));
   DataRt.Len := cbRead;
END;

{
 Accepts a file spec.  If the file exists then user is 
 asked to confirm OverWrite.  Returns True if the     
 file does not exist.  Returns False if the file exists. 
}
FUNCTION OverWriteOk(VARS DataFile : LSFileSpec):  BOOLEAN [PUBLIC];

CONST 
   AlreadyExists =  'data file already exists, Overwrite?';
   ConfirmTxt    =  'Press Go confirm, Cancel to deny.';

VAR [EXTERN]
   ConfirmForm :  WORD;

VAR 
   FhRet       :  WORD;
   KbdByte     :  BYTE;

BEGIN
   Erc := OpenFile(ADS FhRet, ADS DataFile[1], DataFile.Len,
          ADS NIL, 0, ModeRead);
   IF Erc = 0
      THEN
         BEGIN
            Erc := CloseFile(FhRet);
            DisplayFKeys;
            CheckErc(ResetFrame(0));
            CheckErc(PutFrameChars(0,0,20, ADS DataFile[1], DataFile.Len4));
            CheckErc(PutFrameChars(0,DataFile.Len3,20,
                     ADS AlreadyExists, Upper(AlreadyExists)));
            CheckErc(PutFrameChars(0,5,21,ADS ConfirmTxt, Upper(ConfirmTxt)));
            REPEAT
               Beep;
               CheckErc(ReadKbd(ADS KbdByte));
            UNTIL (KbdByte = Cancel) OR
         ELSE (KbdByte = Go)
            OR
      ELSE (KbdByte = Finish);

   CASE KbdByte OF
      Cancel :
                BEGIN
                   CheckErc(DisplayForm(ADS ConfirmForm, 0, 0, 20));
                   REPEAT
                      Read_the_FieldC(ADS ConfirmForm, 'FileName', 0,
                                      DataFile, 80, ADS ExitState);
                      IF DataFile.Len = 0
                         THEN ExitState.ch := 0;
                      IF ExitState.ch <> Go
                         THEN Beep;
                      IF ExitState.ch = Finish
                         THEN ConfirmFinish;
                   UNTIL ExitState.ch = Go;
                   CheckErc(UnDisplayForm(ADS ConfirmForm));
                   OverWriteOk := False
                END;

      Go     :  OverWriteOk := True;

      Finish :
                BEGIN
                   ConFirmFinish;
                   OverWriteOk := False
                END;
   OTHERWISE ;
   END;
   CheckErc(ResetFrame(0));
END
ELSE OverWriteOk := True;
END;

{
 Accepts LString 'Source' and RETURNS LString 'Dest' 
 with all blanks removed. This is handy for user     
 input that will be used as file specs.              
}
PROCEDURE RemoveBlanks(VARS Source : LSTRING;
                       VARS Dest   : LSTRING)[PUBLIC];

VAR 
   I,cBytes :  Integer;
BEGIN
   cbytes := 0;
   FOR I := 1 TO Ord(Source.Len) DO
      BEGIN
         IF Source[I] = ' '
            THEN  DO nothing
            ELSE
               BEGIN
                  cbytes := cbytes +1;
                  Dest[cbytes] := Source[I];
               END;
      END;
   Dest.Len := Wrd(cbytes);
END;

{
 Create the Three video frames this program needs,  
 independent of hardware type. Display the program  
 heading and path in frame 1. Also loads the global 
 Variable WsType with the code for the workstation  
 type.                                              
}
PROCEDURE InitVideo;

CONST 
   Heading  =  'Quick Graph  Version';
   sUCB     =  95;
   PathC    =  'Path: ';


VAR [EXTERN]
   sbVerRun    :  LSTRING(1);

VAR 
   border     :  BYTE;
   borderATTR :  BYTE;
   borderDESC :  BYTE;
   bSpace     :  BYTE;
   ColStart   :  WORD;
   LineStart  :  WORD;
   Frame      :  WORD;
   iAttr      :  WORD;
   nCols      :  WORD;
   nLines     :  WORD;
   Path       :  LSTRING(30);
   pMap       :  Pointer;
   sMap       :  WORD;
   UCB        :  RECORD
                    LogInId[0]          :  Integer;
                    DefaultVol[2]       :  LSTRING(12);
                    DefaultDir[15]      :  LSTRING(12);
                    DefaultPassWord[28] :  LSTRING(12);
                    Prefix[41]          :  LSTRING(40);
                    DefaultNode[82]     :  Char;
                 END;

BEGIN
   CheckErc(QueryVidHdw(ADS VidStatus,42));
   WsType := VidStatus.level;
   CheckErc(GetUCB(ADS UCB, sUCB));

   bSpace := 00;
   CheckERC(ResetVideo(Wrd(VidStatus.nColsNarrow), Wrd(VidStatus.nLinesMax),
   TRUE, bSpace, ADS sMap));

   border     := D8;
   borderATTR := 1;
   borderDESC := 4;
   ColStart   := 0;
   Frame      := 1;
   LineStart  := 0;
   nCols      := Wrd(VidStatus.nColsNarrow);
   nLines     := 2;
   CheckERC(InitVidFrame(Frame, ColStart, LineStart, nCols, nLines,
            borderDESC, border, borderATTR, FALSE, FALSE));

   borderDESC := 0;
   ColStart   := 0;
   Frame      := 0;
   LineStart  := 3;
   nCols      := Wrd(VidStatus.nColsNarrow);
   nLines     := Wrd(VidStatus.nLinesMax4);
   CheckERC(InitVidFrame(Frame, ColStart, LineStart, nCols, nLines,
            borderDESC, border, borderATTR, FALSE, FALSE));

   ColStart   := 0;
   Frame      := 2;
   LineStart  := Wrd(VidStatus.nLinesMax1);
   nCols      := Wrd(VidStatus.nColsNarrow);
   nLines     := 1;
   CheckERC(InitVidFrame(Frame, ColStart, LineStart, nCols, nLines,
            borderDESC, border, borderATTR, FALSE, FALSE));

   pMap.R := 0;
   pMap.S := 0;
   CheckERC(InitCharMap(pMap, sMap));

   iAttr := 1;
   CheckERC(SetScreenVidAttr(iAttr,TRUE));
   CheckErc(ResetFrame(0));
   CheckErc(ResetFrame(1));
   CheckErc(ResetFrame(2));

   CheckERC(PutFrameChars(1, 0, 0, ADS Heading,Upper(Heading)));
   CheckERC(PutFrameChars(1, Upper(Heading)+1, 0,
   ADS sbVerRun[1], sbVerRun.Len));
   Path := PathC;
   ConCat(Path,'[');
   ConCat(Path,UCB.DefaultVol);
   ConCat(Path,']<');
   ConCat(Path,UCB.DefaultDir);
   ConCat(Path,'>');
   CheckERC(PutFrameChars(1, Wrd(VidStatus.nColsNarrow)Path.Len, 0,
   ADS Path[1], Path.Len));

END;

{
  Writes 'WriteData' to the BINARY field 'FieldName' with an    
  index of 'Index' from form 'Form'.                            
}
PROCEDURE Write_the_FieldB(       Form  : Pointer;
                           CONSTS FieldName: LSTRING;
                           Index : WORD;
                           WriteData: Pointer)[PUBLIC];

CONST 
   bType =  'Binary.';

BEGIN
   CheckErc(WriteField(Form, ADS FieldName[1], FieldName.Len, Index,
            WriteData, 2, ADS bType));
END;

{
  Writes 'WriteData' to the CHARACTER field 'FieldName' with    
  an index of 'Index' from form 'Form'.                         
}
PROCEDURE Write_the_FieldC(       Form  : Pointer;
                           CONSTS FieldName: LSTRING;
                           Index : WORD;
                           WriteData: Pointer;
                           sDataMax: WORD)[PUBLIC];

CONST 
   cType =  'Character.';

BEGIN
   CheckErc(WriteField(Form, ADS FieldName[1], FieldName.Len, Index,
            WriteData, sDataMax, ADS cType));
END;

{
 Writes 'pbData' of size 'cbData' to ByteStream opened by 'OpenDataFile' 
}
PROCEDURE WriteDataFile( pbData : Pointer;
                        cbData : WORD)[PUBLIC];

VAR 
   cbWritten :  WORD;

BEGIN
   CheckErc(WriteBsRecord(ADS BSWA[1], pbData, cbData, ADS cbWritten));
END;

{
 Writes 'Data' to the Status Line of 'Form'.   
 Waits for a key to be pressed if Wait is TRUE 
}
PROCEDURE WriteStatusLine(       Form : Pointer;
                          CONSTS Data : LSTRING;
                          Index : WORD;
                          Wait : BOOLEAN)[PUBLIC];

CONST 
   StatusFld =  'Status';

VAR 
   I :  BYTE;

BEGIN
   Write_the_FieldC(Form, StatusFld, Index, ADS Data[1], Data.Len);
   IF Wait
      THEN
         BEGIN
            CheckErc(ReadKbd( ADS I));
            CheckErc(DefaultField(Form, ADS StatusFld,6,Index))
         END;
END;

{
 Displays the Function Key Label 'LabelData' for 
 Function Key 'FunctionKey' in the Template at   
 the bottom of the screen (Video frame 2). This  
 LABEL is displayed with the video attribute of  
 'Attribute'. If 'Attribute' is zero (0) then    
 the default unselected attribute for the field  
 will be used.                                   
}
PROCEDURE DisplayFunctionKey(     FunctionKey : WORD;
                             CONSTS LabelData : LSTRING;
                             Attribute : WORD)[PUBLIC];

CONST 
   FctKey =  'FKey';

VAR [EXTERN]
   FunctKeysForm :  WORD;

BEGIN
   Write_the_FieldC(ADS FunctKeysForm, FctKey, FunctionKey, ADS LabelData[1],
                    LabelData.Len);
   IF Attribute <> 0
      THEN
         CheckErc(SetFieldAttrs(ADS FunctKeysForm, ADS FctKey, Upper(FctKey),
         FunctionKey, Attribute));
END;

{
 Asks user to enter data file name and verifies 
 this file exists and is of the correct format. 
 Displays error messages if the file can not be 
 opened successfully.                           
}
PROCEDURE GetEditFileSpec;

CONST 
   BadFileSpec =  'Bad file Specification ';
   BadSpec   =  205;
   Bar       =  0;
   CompareOk =  FFFF;
   Editing   =  True;
   ErCode    =  'BTOS Error Code = ';
   F10       =  31;
   FieldName =  'DataFile';
   FileSuffix =  '.Dat';
   Invalid   =  9;
   InvalidType =  'File not of correct format  Press any key to continue';
   Line      =  3;
   ModeRead  =  ReType(WORD,'mr');
   NLine     =  2;
   NoFile    =  203;
   NoDir     =  204;
   NoVol     =  215;
   NotMtd    =  216;
   NoSuchFile = 'No such file or not a Quick Graph data file';
   NoSuchDir =  'No such Directory ';
   NoSuchVol =  'No such Volume ';
   Ok        =  0;
   Pie       =  1;

VAR [EXTERN]
   EditFileForm :  WORD;

VAR 
   cBytes    :  WORD;
   Check     :  BOOLEAN;
   DataFileSpec :  LSFileSpec;
   ErrorCode :  LSTRING(5);
   HdrByte   :  BYTE;
   I         :  Integer;
   StatusLine:  LSTRING(80);

BEGIN
   DisplayFKeys;
   DisplayFunctionKey(10,'Return',0);
   CheckErc(DisplayForm(ADS EditFileForm,0 ,255 ,255));
   ExitState.ch := 0;
   Erc := 0;

   REPEAT
      StatusLine := Null;
      Read_the_FieldC(ADS EditFileForm, FieldName, 0,
                      DataFileSpec, Upper(DataFileSpec), ADS ExitState);

      WriteStatusLine(ADS EditFileForm, Null,0,False);

      CASE ExitState.ch OF
         Cancel :  Erc := 4;
         Finish :
                   BEGIN
                      ConfirmFinish;
                      Erc := 4
                   END;
         F10    :  Erc := Ok;
      OTHERWISE
         BEGIN
            RemoveBlanks(DataFileSpec,DataFileSpec);
            cBytes := ULCMPB(ADS DataFileSpec[Ord(DataFileSpec.Len3)],
                      ADS FileSuffix,4);
            IF cBytes <> CompareOk
               THEN CONCAT(DataFileSpec,FileSuffix);

            Erc := OpenByteStream(ADS BSWA[1],
                   ADS DataFileSpec[1], DataFileSpec.Len,
                   ADS NIL,0, ModeRead,
                   ADS BsBuf[1], SizeOf(BsBuf));
            CASE Erc OF
               Ok      : ;
               NoFile  : BEGIN
                             CONCAT(StatusLine,NoSuchFile);
                             WriteStatusLine(ADS EditFileForm, StatusLine,0,
                                             False);
                             Beep
                          END;

               NoDir   : BEGIN
                             CONCAT(StatusLine,NoSuchDir);
                             WriteStatusLine(ADS EditFileForm, StatusLine,0,
                                             False);
                             Beep
                          END;

               BadSpec : BEGIN
                             CONCAT(StatusLine,BadFileSpec);
                             WriteStatusLine(ADS EditFileForm, StatusLine,0,
                                             False);
                             Beep
                          END;

               NoVol   : BEGIN
                             CONCAT(StatusLine,NoSuchVol);
                             WriteStatusLine(ADS EditFileForm, StatusLine,0,
                                             False);
                             Beep
                          END;

               NotMtd  : BEGIN
                             CONCAT(StatusLine,NoSuchVol);
                             WriteStatusLine(ADS EditFileForm, StatusLine,0,
                                             False);
                             Beep
                          END;

            OTHERWISE
               BEGIN
                  CONCAT(StatusLine,ErCode);
                  Check := Encode(ErrorCode,Erc:5);
                  CONCAT(StatusLine,ErrorCode);
                  WriteStatusLine(ADS EditFileForm, StatusLine,
                                  0, False);
                  Beep
               END;
            END;{Case}
         END;{Otherwise}
      END;{Case}
   UNTIL Erc = Ok;


   IF ExitState.ch <> F10
      THEN
         BEGIN
            CheckErc(ReadBsRecord(ADS BSWA, ADS GraphType, 2, ADS cBytes));
            FOR I := 1 TO 16 DO
               BEGIN
                  CheckErc(ReadByte(ADS BSWA, ADS HdrByte));
                  IF HdrByte <> FF
                     THEN GraphType := Invalid;
               END;
            CloseDataFile;

            CASE GraphType OF
               Bar   : BEGIN
                          CheckErc(UnDisplayForm(ADS EditFileForm));
                          Bar_Chart(Editing,DataFileSpec)
                       END;
               Pie   : BEGIN
                          CheckErc(UnDisplayForm(ADS EditFileForm));
                          Pie_Chart(Editing,DataFileSpec,fBTOSIIGraphics)
                       END;
               NLine : BEGIN
                          CheckErc(UnDisplayForm(ADS EditFileForm));
                          LINE_CHART(Editing,DataFileSpec)
                       END;
               Line  : BEGIN
                          CheckErc(UnDisplayForm(ADS EditFileForm));
                          AlphaLine_Chart(Editing,DataFileSpec)
                       END;
            OTHERWISE
               BEGIN
                  CONCAT(StatusLine,InvalidType);
                  Beep;
                  WriteStatusLine(ADS EditFileForm, StatusLine,0,True);
                  CheckErc(UnDisplayForm(ADS EditFileForm))
               END;

            END;
         END
      ELSE
         CheckErc(UnDisplayForm(ADS EditFileForm));
END;

{
 Sets Exit Run File to this program and chains      
 the resident graphics program.                     
}
PROCEDURE ZipBGP[PUBLIC];

CONST 
   ExitRunFile  =  '[sys]<Sys>QuickGraph.Run';
   BGP          =  '[sys]<sys>BGP.run';
   OFISGraphics =  '[sys]<sys>OFISGraphics.Run';

BEGIN
   CheckErc(SetExitRunFile(ADS ExitRunFile, Upper(ExitRunFile),
   ADS NIL, 0, 128));

   IF fBTOSIIGraphics = FALSE
      THEN CheckErc(Chain(ADS BGP, Upper(BGP),
         ADS NIL,0,128,0,False));

   IF fBTOSIIGraphics = TRUE
      THEN CheckErc(Chain(ADS OFISGraphics,
                    Upper(OFISGraphics),
         ADS NIL,0,128,0,False));
END;

{
 Finds what graphics package is installed. 
}
PROCEDURE ChkGraType;

CONST 
   BGP          =  '[sys]<sys>BGP.run';
   OFISGraphics =  '[sys]<sys>OFISGraphics.Run';
   ArtDesigner  =  '[sys]<sys>ArtDesigner.Run';

VAR 
   LocalErc :  WORD;
   FileHandle:  WORD;

BEGIN
   LocalErc := OpenFile(ADS FileHandle, ADS BGP, Upper(BGP),
               ADS NIL, 0, ModeRead);
   IF LocalErc = 0
      THEN
         BEGIN
            CheckErc(CloseFile(FileHandle));
            fBTOSIIGraphics := False;
            RETURN
         END;

   LocalErc := OpenFile(ADS FileHandle, ADS OFISGraphics,
                        Upper(OFISGraphics), ADS NIL, 0, ModeRead);
   IF LocalErc = 0
      THEN
         BEGIN
            CheckErc(CloseFile(FileHandle));
            fBTOSIIGraphics := True;
            RETURN
         END;
   LocalErc := OpenFile(ADS FileHandle, ADS ArtDesigner,
                        Upper(ArtDesigner), ADS NIL, 0, ModeRead);
   IF LocalErc = 0
      THEN
         BEGIN
            CheckErc(CloseFile(FileHandle));
            fBTOSIIGraphics := True;
            RETURN
         END
       ELSE 
          ErrorExitString(LocalErc,
                          ADS 'Can''t find BGP.Run, OFISGraphics.Run or ArtDesigner.Run.',56);
END;

{}
PROCEDURE RemoveWelcomeForm;
{}
BEGIN
   IF WsType = B21
      THEN CheckErc(UnDisplayForm( ADS B21WelcomeForm ))
      ELSE CheckErc(UnDisplayForm( ADS WelcomeForm ));
END;

{
Main Program
}
BEGIN
   Erc := NotifyCM(0, ADS NIL, 0);
   IF Erc = 0
      THEN CheckErc(SetExitRunFile(ADS CMExitRunFile,
                    Upper(CMExitRunFile), ADS NIL, 0, 128))
      ELSE CheckErc(SetExitRunFile(ADS ExecExitRunFile,
                    Upper(ExecExitRunFile), ADS NIL, 0, 128));

   InitVideo;
   ChkGraType;

   WHILE TRUE DO
      BEGIN
         DisplayFKeys;
         DisplayFunctionKey(1,'Create',0);
         DisplayFunctionKey(2,' Edit',0);
         IF WsType = B21
            THEN CheckErc(DisplayForm(ADS B21WelcomeForm,0,255,255))
            ELSE CheckErc(DisplayForm(ADS WelcomeForm,0,255,255));
         CheckErc(PosFrameCursor(0,255,255));
         CheckErc(ReadKbd(ADS KbdByte));
         CASE KbdByte OF

            F1 : BEGIN
                    DisplayFunctionKey(1,'  Pie',0);
                    DisplayFunctionKey(2,'  Bar',0);
                    DisplayFunctionKey(3,'LineA',0);
                    DisplayFunctionKey(4,'LineN',0);
                    DisplayFunctionKey(10,'Return',0);

                    Done := FALSE;
                    WHILE NOT(Done) DO
                       BEGIN
                          CheckErc(ReadKbd( ADS KbdByte));
                          CASE KbdByte OF
                             F1 :  BEGIN
                                      RemoveWelcomeForm;
                                      Pie_Chart(EditNo,Null, fBTOSIIGraphics);
                                      Done := TRUE
                                   END;
                             F2 :  BEGIN
                                      RemoveWelcomeForm;
                                      Bar_Chart(EditNo,Null);
                                      Done := TRUE
                                   END;
                             F3 :  BEGIN
                                      RemoveWelcomeForm;
                                      AlphaLine_Chart(EditNo,Null);
                                      Done := TRUE
                                   END;
                             F4 :  BEGIN
                                      RemoveWelcomeForm;
                                      LINE_CHART(EditNo,Null);
                                      Done := TRUE
                                   END;
                             F10:  BREAK;
                             Finish:  ConfirmFinish;
                           OTHERWISE
                             Beep;

                          END;{Case}
                       END; {While Not(Done) }
                 END;{F1}

            F2 :  BEGIN
                     RemoveWelcomeForm;
                     GetEditFileSpec
                  END;

        Finish :  ConfirmFinish;

         OTHERWISE
            Beep;
         END;{Case}

      END;{While TRUE}
END.
Run File to this program and chains      
 the resident graphics program.                     
}
PROCEDURE ZipBGP[PUBLIC];

CONST 
   ExitRunFile  =  '[sys]<Sys>QuickGraph.Run';
   BGP          =  '[sys]<sys>BGP.run';
   OFISGraphics =  '[sys]<sys>OFISGraphics.Run';

BEGIN
   CheckErc(SetExitRunFile(ADS ExitRunFile, Upper(ExitRunFile),
   ADS NIL, 0, 128));

   IF fBTOSIIGraphics = FALSE
      THEN CheckErc(Chain