c
c Program:            Grade
c
c Author:             Mark R. Vevle
c                     X-Ray Crystallographic Core Facility
c                     University of Alabama at Birmingham
c                     244 BHS, THT 79
c                     University Station
c                     Birmingham, Alabama  35294
c                     (205) 934 - 1973/2657
c
c Disclaimer/rights:  This   software  is  in  the  public  domain  and  is
c                     provided  free  though  DECUS or other channels.  The
c                     information  in  this  software  is subject to change
c                     without  notice  and  should  not  be  construed as a
c                     commitment  by the author or his employer. The author
c                     and  his  employer  assumes no responsibility for the
c                     use,  the  correctness,  or  the  reliability of this
c                     software. THIS SOFTWARE IS PROVIDED AS IS.
c
c Environment:        VAX/VMS V3.0 or later
c
c Modifications:      V1.0 -- Original Version. MRV
c
c   25-OCT-1984       V1.1 -- Add class average score for each grade to the
c                             manager record. MRV
c
c   12-NOV-1984       V1.2 -- Add  score  names  and  scales to the manager
c                             record. MRV
c
c   07-JAN-1985       V1.3 -- Add display of version number when creating a
c                             new student database file. MRV
c
c                             Correct  Manager record format (incorrect key
c                             layout, Manager_Key_0 to short, 20 characters
c                             rather than 40 characters which threw off the
c                             Manager_Key_3 key. MRV
c
c   22-JAN-1985       V1.4 -- Modify  the  method  used  to calculate class
c                             averages. Omit any zero scores/averages. MRV
c
c                             Add ROSTER to display options. MRV
c

	Program Grade
c
	Parameter	Maximum_Tests	= 20
	Parameter	Data_File_Lun	= 1
c
c   *** Layout of the student record
c
	Character*20	Last_Name,	First_Name,	Department_Name
	Character*20	Student_Number,	Comment
	Character*20	Test_Comments( Maximum_Tests )
	Character*1	Letter_Grade
c
	Logical*1	Test_Dropped( Maximum_Tests )
	Logical*1	Student_Record( 620 )
c
	Real		Test_Score( Maximum_Tests )
	Real		Average_Needed( 3 )
	Real		Average_Grade
c
	Common / Record /
	1	Last_Name,		!   1	 20
	1	First_Name,		!  21	 40
	1	Student_Number,		!  41	 60
	1	Department_Name,	!  61	 80
	1	Comment,		!  81	100
	1	Test_Comments,		! 101	500
	1	Test_Dropped,		! 501	520
	1	Test_Score,		! 521	600
	1	Average_Needed,		! 601	612
	1	Average_Grade,		! 613	616
	1	Letter_Grade		! 617	618
c
	Equivalence(	Student_Record(   1 ),	Last_Name	)
	Equivalence(	Student_Record(  21 ),	First_Name	)
	Equivalence(	Student_Record(  41 ),	Student_Number	)
	Equivalence(	Student_Record(  61 ),	Department_Name	)
	Equivalence(	Student_Record(  81 ),	Comment		)
	Equivalence(	Student_Record( 101 ),	Test_Comments	)
	Equivalence(	Student_Record( 501 ),	Test_Dropped	)
	Equivalence(	Student_Record( 521 ),	Test_Score	)
	Equivalence(	Student_Record( 601 ),	Average_Needed	)
	Equivalence(	Student_Record( 613 ),	Average_Grade	)
	Equivalence(	Student_Record( 617 ),	Letter_Grade	)
c
c   *** Layout of the managment record. Key is Null ( ASCII 0 ).
c
	Character*40	Manager_Key_0
	Character*20	Manager_Key_1,	Manager_Key_2
	Character*8	Manager_Test_Name( Maximum_Tests )
c
	Integer		Manager_Counts( 5 ),	Manager_Num_Tests
c
	Logical*1	Manager_Dropped( Maximum_Tests )
	Logical*1	Manager_Record( 508 )
c
	Real		Manager_Weights( Maximum_Tests )
	Real		Manager_Scale( Maximum_Tests )
	Real		Manager_Score_Average( Maximum_Tests )
	Real		Manager_Average_Grade
c
	Common / Manager /
	1	Manager_Key_0,		!   1	 40
	1	Manager_Key_1,		!  41	 60
	1	Manager_Key_2,		!  61	 60
	1	Manager_Dropped,	!  81	100
	1	Manager_Weights,	! 101	180
	1	Manager_Counts,		! 181	200
	1	Manager_Average_Grade,	! 201	204
	1	Manager_Num_Tests,	! 205	208
	1	Manager_Scale,		! 209	288
	1	Manager_Score_Average,	! 289	368
	1	Manager_Test_Name	! 369	528
c
	Equivalence(	Manager_Record(   1 ),	Manager_Key_0		)
	Equivalence(	Manager_Record(  41 ),	Manager_Key_1		)
	Equivalence(	Manager_Record(  61 ),	Manager_Key_2		)
	Equivalence(	Manager_Record(  81 ),	Manager_Dropped		)
	Equivalence(	Manager_Record( 101 ),	Manager_Weights		)
	Equivalence(	Manager_Record( 181 ),	Manager_Counts		)
	Equivalence(	Manager_Record( 201 ),	Manager_Average_Grade	)
	Equivalence(	Manager_Record( 205 ),	Manager_Num_Tests	)
	Equivalence(	Manager_Record( 209 ),  Manager_Scale		)
	Equivalence(	Manager_Record( 289 ),	Manager_Score_Average	)
	Equivalence(	Manager_Record( 369 ),	Manager_Test_Name	)
c
	Integer		Student_File_Open
c
	If ( Student_File_Open( Data_File_Lun ) ) Then
	    Call Main_Menu
	    Close ( Unit = Data_File_Lun )
	    Call Lib$Set_Cursor ( 22, 1 )
	End IF
c
	End



	Subroutine Main_Menu
c
	Character*1	Option
c
	Logical*1	Done / .False. /
c
	Do While ( .Not. Done )
c
	    Call Draw_Main_Menu
c
	    Length = 1
	    Option = '?'
c
	    Call Select_Option ( 'CDMU', Option, Length, 20, 33, 1 )
c
	    If ( Option .eq. 'U' ) Then
		Call Update_Menu
	    Else If ( Option .eq. 'D' ) Then
		Call Display_Menu
	    Else If ( Option .eq. 'M' ) Then
		Call Manager_Menu
	    Else If ( Option .eq. 'C' ) Then
		Call Calculate_Grades
	    Else
		Done = .True.
	    End If
c
	End Do
c
	Return
	End



	Subroutine Calculate_Grades
c
	Include		'Student.Rec'
c
	Include		'Manager.Rec'
c
	Character*30	Total_Line
	Character*2	Max_Score
	Character*1	So / 14 /,	Si / 15 /,	Null / 0 /
	Character*1	FF / 12 /,	Cr / 13 /,	Lf / 10 /
	Character*1	Letters( 5 ) / 'A', 'B', 'C', 'D', 'F' /
	Character*1	Option
c
	Integer		Get_Integer,	Student_Count,	Counts( 5 )
	Integer		M( Maximum_Tests ),	Average_Count
	Integer		Class_Count( Maximum_Tests )
c
	Real		Class_Average,		P( Maximum_Tests, 2 )
	Real		S( 3 )
	Real		Class_Score_Average( Maximum_Tests )
c
	Call Draw_Menu_Header ( 'Calculate Grades', 3 )
c
	If ( Get_Integer ( Number_of_Scores,  10, 1, 1, Manager_Num_Tests,
	1	'Enter the number of scores to use for grade ' //
	1	'calculations', ) ) Then
c
	    If ( Number_of_Scores .gt. 1 ) Then
c
		Call Lib$Erase_Line ( 10, 1 )
		Write ( Max_Score, 30 ) Number_of_Scores
c
		If ( Max_Score( 1: 1 ) .eq. ' ' ) Then
		    Max_Score( 1: 1 ) = Null
		    K = 65
		Else
		    K = 66
		End If
c
		If ( .Not. ( Get_Integer ( Number_to_Drop, 10, 1, 0,
	1				   Number_of_Scores,
	1 'Enter the maximum number of scores than can be dropped' ) ) ) Then
		    Number_To_Drop = 0		 
		End If
c
	    Else
		Number_to_Drop = 0
	    End If
c
	    Read (	Data_File_Lun,
	1		Key	= Null,
	1		KeyId	= 0,
	1		IoStat	= Ios ) Manager_Record
c
	    S( 1 ) = 90.0
	    S( 2 ) = 80.0
	    S( 3 ) = 70.0
	    Student_Count = 0
	    Average_Count = 0
	    Class_Average = 0.0
	    Points_Remaining = 0.0
c
	    Do I = ( Number_of_Scores + 1 ), Manager_Num_Tests
		Points_Remaining = Points_Remaining + Manager_Weights( I )
	    End Do
c
	    Do I = 1, Number_of_Scores
		Class_Score_Average( I ) = 0.0
		Class_Count ( I ) = 0
	    End Do
c
	    Do I = 1, 5
		Counts( I ) = 0
	    End Do
c
	    Read (	Data_File_Lun,
	1		KeyGt	= Null,
	1		KeyId	= 0,
	1		IoStat	= Ios ) Student_Record
c
	    Do While ( Ios .eq. 0 )
c
		J = 0
		Total = 0.0
		Total_Weight = 0.0
		Possible_Points = 0.0
	        Student_Count = Student_Count + 1
c
c	**** Calculate the average score
c
		Do I = 1, Number_of_Scores
c
		    If ( Test_Score( I ) .gt. 0 ) Then
			Class_Score_Average( I ) = Class_Score_Average( I ) +
	1					   Test_Score( I ) +
	1					   Manager_Scale( I )
			Class_Count( I ) = Class_Count( I ) + 1
			W = Test_Score( I ) + Manager_Scale( I )
		    Else
			W = 0.0
		    End If

c
		    Test_Dropped( I ) = .True.
		    Y = Manager_Weights( I )
c
		    If ( ( Manager_Dropped( I ) ) .and.
	1		 ( Number_to_Drop .gt. 0 ) ) Then
			J = J + 1
			P( J, 1 ) = W
			P( J, 2 ) = Y
			M( J ) = I
		    Else
			V = Average_Grade 
			X = Possible_Points
			U = W * Y
			Z = X + Y
			Total = Total + U
			Total_Weight = Total_Weight + Y
			Possible_Points = Z
			Average_Grade = ( ( V * X ) + U ) / Z
			Test_Dropped( I ) = .False.
		    End If
c
		End Do
c
		If ( J .gt. 0 ) Then
c
		    Call Shell_Sort ( P, M, J )
c
		    I = 1
c
		    Do While ( ( ( Average_Grade .le.
	1			   Test_Score( M( I ) ) ) .or.
	1			 ( Number_To_Drop .le. ( J - I ) ) ) .and.
	1			( I .le. J ) )
c
			If ( Test_Score( M( I ) ) .gt. 0 ) Then
			    W = Test_Score( M( I ) ) + Manager_Scale( M( I ) )
			Else
			    W = 0.0
			End If
c
			V = Average_Grade 
			X = Possible_Points
			Y = Manager_Weights( M( I ) )
			U = W * Y
			Z = X + Y
			Total = Total + U
			Total_Weight = Total_Weight + Y
			Possible_Points = Z
			Average_Grade = ( ( V * X ) + U ) / Z
			Test_Dropped( M( I ) ) = .False.
			I = I + 1
c
		    End Do
c
		End If
c
c	**** Calculate score necessary to make A, B, C.
c
		If ( Points_Remaining .gt. 0.0 ) Then
		    Total_Weight = Total_Weight + Points_Remaining
		    Do I = 1, 3
			Average_Needed( I ) = ( ( S( I ) * Total_Weight )
	1					- Total ) /
	1					Points_Remaining
		    End Do
		Else
		    Do I = 1, 3
			Average_Needed( I ) = 0.0
		    End Do
		End If
c
c	**** Assign letter grades and count number of A's, B's, C's, D's,
c	**** and F's.
c
		If ( Average_Grade .ge. 90.0 ) Then
		    Letter_Grade = 'A'
		    Counts( 1 ) = Counts( 1 ) + 1
		Else If ( Average_Grade .ge. 80.0 ) Then
		    Letter_Grade = 'B'
		    Counts( 2 ) = Counts( 2 ) + 1
		Else If ( Average_Grade .ge. 70.0 ) Then
		    Letter_Grade = 'C'
		    Counts( 3 ) = Counts( 3 ) + 1
		Else If ( Average_Grade .ge. 60.0 ) Then
		    Letter_Grade = 'D'
		    Counts( 4 ) = Counts( 4 ) + 1
		Else
		    Letter_Grade = 'F'
		    Counts( 5 ) = Counts( 5 ) + 1
		End If
c
		If ( Average_Grade .gt. 0 ) Then
		    Class_Average = Class_Average + Average_Grade
		    Average_Count = Average_Count + 1
		End If
c
		ReWrite ( Data_File_Lun )	Student_Record
c
c	**** Get next student record
c
		Read	( Data_File_Lun,
	1		  IoStat  = Ios )	Student_Record
c
	    End Do
c
	    Read (	Data_File_Lun,
	1		Key	= Null,
	1		KeyId	= 0,
	1		IoStat	= Ios ) Manager_Record
c
	    Manager_Average_Grade = Class_Average / Average_Count
c
	    Do I = 1, Number_of_Scores
		Manager_Score_Average( I ) = Class_Score_Average( I ) / 
	1				     Class_Count( I )
	    End Do
c
	    Do I = 1, 5
		Manager_Counts( I ) = Counts( I )
	    End Do
c
	    ReWrite ( Data_File_Lun )	Manager_Record
c
	End If
c
	Write ( Total_Line, 10 )  Manager_Average_Grade
	Call Lib$Put_Screen ( Total_Line, 12, 27, 1 )
	Call Lib$Put_Screen ( ' Grade          # of students', 14, 27, 1 )
c
	Do I = 1, 5
	    Write ( Total_Line, 20 ) Letters( I ), Manager_Counts( I )
	    Call Lib$Put_Screen ( Total_Line, 14 + I, 27, 1 )
	End Do
c
	Call Lib$Put_Screen ( ' Hit <RETURN> to continue ', 22, 27, 2 )
	Call Lib$Get_Screen ( Option, , )

	Return
c
10	Format (	'Class average: ', F10.2	)
20	Format (	'   ', A, '           ', I7	)
30	Format ( I2 )
c
	End



	Subroutine Shell_Sort ( P, Idx, J )
c
	Integer		J,	Idx( 20 )
c
	Logical		All_Done
c
	Real		P( 20, 2 )
c
	Jump = J
c
	Do While ( Jump .gt. 1 )
	    Jump = Jump / 2
	    All_Done = .False.
	    Do While ( .Not. All_Done )
		All_Done = .True.
		Do M = 1, ( J - Jump )
		    N = M + Jump
		    If ( ( P( M, 1 ) .lt. P( N, 1 ) ) .or.
	1	       ( ( P( M, 1 ) .eq. P( N, 1 ) ) .and.
	1		 ( P( M, 2 ) .gt. P( N, 2 ) ) ) ) Then
			Call Real_Swap ( P( M, 1 ), P( N, 1 )  )
			Call Real_Swap ( P( M, 2 ), P( N, 2 ) )
			Call Intr_Swap ( Idx( M ), Idx( N ) )
			All_Done = .False.
		    End If
		End Do
	    End Do
	End Do
c
	Return
	End



	Subroutine Intr_Swap ( I, J )
c
	Integer		I,	J
c
	K = I
	I = J
	J = K
c
	Return
	End



	Subroutine Real_Swap ( A, B )
c
	Real		A,	B
c
	X = A
	A = B
	B = X
c
	Return
	End



	Subroutine Display_Menu
c
	Character*80	File_Name
	Character*15	Prompt( 0: 2 )
	Character*1	So / 14 /,	Si / 15 /,	Option
c
	Integer		Key,	P_Size( 0: 2 ) / 9, 6, 15 /
c
	Logical*1	Done,		Screen,		Finished
c
	Common / Block_1 /	Screen
c
	Data Prompt /	'LAST name      ',
	1		'NUMBER         ',
	1		'DEPARTMENT name'	/
c
	External	One_Full_Display
c
	Call Draw_Menu_Header ( 'Display Student Records', 1 )
c
	Call Lib$Put_Screen ( 'Enter output specification: ', 8, 1, 1 )
	Call Lib$Get_Screen ( File_Name, , Length )
	Call Str$UpCase ( File_Name( : Length ), File_Name( : Length ) )
c
	If (	( File_Name ( : 10 ) .eq. 'SYS$OUTPUT'	) .or.
	1	( File_Name ( :  3 ) .eq. 'TT:'		) ) Then
	    Screen = .True.
	Else
	    Screen = .False.
	End If
c
	Open (	Unit		= 2,
	1	Name		= File_Name( : Length ),
	1	DefaultFile	= 'Class.Lis',
	1	Status		= 'NEW',
	1	Access		= 'Sequential',
	1	Organization	= 'Sequential',
	1	Form		= 'Formatted',
	1	Recl		= 132,
	1	CarriageControl	= 'LIST' )
c
	Finished = .False.
c
	Do While ( .Not. Finished )
c
	    Call Select_Sort_Menu
c
	    Done = .False.
	    Length = 1
	    Option = '?'
c
	    Call Select_Option ( 'DNS', Option, Length, 17, 33, 1 )
c
	    If ( Length .le. 0 ) Then
		Finished = .True.
	    Else If ( Option .eq. 'D' ) Then
		Key = 2
	    Else If ( Option .eq. 'N' ) Then
		Key = 0
	    Else If ( Option .eq. 'S' ) Then
		Key = 1
	    End If
c
	    Do While ( ( .not. Done ) .and. ( .not. Finished ) )
c
		Call Draw_Display_Screen
c
		Length = 1
		Option = '?'
c
		Call Select_Option ( 'BFMORS', Option, Length, 21, 33, 1 )
c
		If ( Length .le. 0 ) Then
		    Done = .True.
		Else
c
		    Call Lib$Erase_Page (	 6,	 1 )
		    Call Lib$Put_Screen ( So // 'm' // Si, 5,	21, 1 )
		    Call Lib$Put_Screen ( So // 'j' // Si, 5,	60, 1 )
c
		    If ( Option .eq. 'B' ) Then
			Call Brief_Display		( Screen, Key )
		    Else If ( Option .eq. 'F' ) Then
			Call Full_Display		( Screen, Key )
		    Else If ( Option .eq. 'M' ) Then
			Call Manager_Display	( Screen )
		    Else If ( Option .eq. 'O' ) Then
			Call Select_By_Key ( Key,
	1				 Prompt( Key )( : P_Size( Key ) ),
	1				 'displayed', One_Full_Display )
		    Else If ( Option .eq. 'R' ) Then
			Call Student_Roster	( Screen, Key )
		    Else If ( Option .eq. 'S' ) Then
			Call Draw_Score_Sheet	( Screen, Key )
		    End If
c
		End If
c
	    End Do
c
	End Do
c
	Close ( Unit = 2 )
c
	Return
	End



	Subroutine Draw_Score_Sheet ( Screen, Key )
c
	Include		'Student.Rec'
c
	Include		'Manager.Rec'
c
	Integer		Key,		Page,		Get_Integer 
c
	Logical*1	Screen,		Toggle
c
	Character*64	Title
	Character*30	Name
	Character*1	So / 14 /,	Si / 15 /,	Null / 0 /
	Character*1	FF / 12 /,	Cr / 13 /,	Lf / 10 /
	Character*1	Option
c
	Call Lib$Put_Screen (
	1	'Enter the title for the score sheet below ',
	1			8,	 1, 1 )
	Call Lib$Put_Screen ( So //
	1	'oooooooooooooooooooooooooooooooo' //
	1	'oooooooooooooooooooooooooooooooo' // Si,
	1			11,	 2, 1 )
	Call Lib$Set_Cursor (	10,	 2 )
	Call Lib$Get_Screen ( Title,	, Length )
c
	If ( .Not. Get_Integer ( Number,  12, 1, 0, Manager_Num_Tests,
	1	'Enter the score to be displayed (0 for a blank sheet)'
	1	) ) Number = 0
c
	Read (	Data_File_Lun,
	1	KeyGt	= Null,
	1	KeyId	= Key,
	1	IoStat	= Ios ) Student_Record
c
	If ( Screen ) Then
	    Call Lib$Erase_Page (  6,  1 )
	    Call Lib$Set_Scroll ( 11, 24 )
	    Call Lib$Set_Cursor (  6,  1 )
	    Write ( 2, 10 ) Cr // Lf, Title( : Length ) // Cr // Lf
	    Write ( 2, 15 )
	    Write ( 2, 20 ) Cr // Lf
	End If
c
	Toggle = .True.
	Line_Number = 28
	Page = 1
c
	Do While ( Ios .eq. 0 )
c
	    If ( ( .not. Screen ) .and. ( Line_Number .ge. 28 ) ) Then
		Write ( 2, 10 ) FF // Cr // Lf,
	1			Title ( : Length ), Page, Cr // Lf
		Page = Page + 1
		Write ( 2, 15 )
		Write ( 2, 20 ) Cr // Lf
		Line_Number = 0
	    End If
c
	    II = Index ( Last_Name,  '  ' ) - 1
	    If ( II .le. 0 ) II = 20
	    JJ = Index ( First_Name, '  ' ) - 1
	    If ( JJ .le. 0 ) JJ = 20
	    If ( ( II + JJ ) .gt. 20 ) JJ = 20 - II
c
	    If ( Toggle ) Then
		Toggle = .False.
		Name   = Last_Name( : II ) // ', ' // First_Name( : JJ )
		Name_Size = II + JJ + 2
		If ( Number .gt. 0 ) Score = Test_Score( Number )
	    Else
		Toggle = .True.
		Line_Number = Line_Number + 1
		If ( Number .le. 0 ) Then
		    Write ( 2, 30 )	Name( : Name_Size ),
	1				Last_Name( : II ) // ', ' //
	1				First_Name( : JJ ),
	1				Cr // Lf
		Else
		    Write ( 2, 40 )	Name( : Name_Size ), Score,
	1				Last_Name( : II ) // ', ' //
	1				First_Name( : JJ ),
	1				Test_Score( Number ),
	1				Cr // Lf
		End If
	    End If
c
	    Read (	Data_File_Lun,
	1		IoStat	= Ios ) Student_Record
c
	End Do
c
	If ( .not. Toggle ) Then
	    If ( Number .le. 0 ) Then
		Write ( 2, 30 ) Name( : Name_Size ), Cr // Lf
	    Else
		Write ( 2, 40 ) Name( : Name_Size ), Score, Cr // Lf
	    End If
	End If

	If ( Screen ) Then
	    Call Lib$Put_Screen ( Cr // Lf // Lf //
	1			  ' Hit <RETURN> to continue ', , , 2 )
	    Call Lib$Get_Screen ( Option, , )
	    Call Lib$Set_Scroll ( 1, 24 )
	End If
c
	Return
c
10	Format ( A, < ( 76 - Length ) / 2 >X, A, T75, 'Page ', I2 )
15	Format ( 'Student Name            ', 2X, 'Score', 13X,
	1	 'Student Name            ', 2X, 'Score' )
		  
20	Format ( 78( '-' ), A )
30	Format ( A, <24 - Name_Size>X, 10( '_' ),10X, A,
	1	:, <22 - II - JJ>X, 10( '_' ), A )
40	Format ( A, <24 - Name_Size>X, F7.2, 13X, A,
	1	:, <22 - II - JJ>X, F7.2, A )
c
	End



	Subroutine Manager_Display ( Screen )
c
	Parameter	Maximum_Tests	= 20
c
	Include		'Manager.Rec'
c
	Logical*1	Screen
c
	Character*1	Cr / 13 /,	Lf / 10 /
	Character*1	FF / 12 /,	Null / 0 /,	Option
c
	If ( Screen ) Then
	    Call Lib$Erase_Page (  6,  1 )
	    Call Lib$Set_Scroll ( 11, 24 )
	    Call Lib$Set_Cursor (  7,  1 )
	Else
	    Write ( 2, 5) FF
	End If
c
	Write ( 2, 10 )
c
	Do I = 1, Manager_Num_Tests
c
	    Write ( 2, 20 )	I,
	1			Manager_Test_Name( I ),
	1			Manager_Weights( I ),
	1			Manager_Scale( I ),
	1			Manager_Dropped( I ),
	1			Manager_Score_Average( I )
c
	End Do
c
	If ( Screen ) Then
	    Call Lib$Put_Screen ( Cr // Lf // Lf //
	1			  ' Hit <RETURN> to continue ', , , 2 )
	    Call Lib$Get_Screen ( Option, , )
	    Call Lib$Set_Scroll ( 1, 24 )
	End If
c
	Return
c
 5	Format ( A, // )
10	Format ( 31X, 'Score Descriptions', //,
	1	 'Number      Name          Weight      Scale      ',
	1	 'Drop      Class Average', /,
	1	 '-------------------------------------------------',
	1	 '-----------------------', / )
c
20	Format ( I4, '. ', 6X, A8, 6X, F6.2, 6X, F5.2, 6X, L3, 6X, F9.2 )
c
	End



	Subroutine One_Full_Display ( String, Key )
c
	Include		'Student.Rec'
	Include		'Manager.Rec'
c
	Character	String*(*)
c
	Integer		Get_Integer,	Start,	Finish
	Integer		Key
c
	Logical*1	Screen
c
	Common / Block_1 /	Screen
c
	Character*1	FF / 12 /,	Cr / 13 /,	Lf / 10 /
	Character*1	Null / 0 /,	Option
c
	If ( Get_Integer ( Number,  15, 1, 1, Manager_Num_Tests,
	1	'Enter the number of scores to be displayed' ) ) Then
c
	    If ( Screen ) Then
		Call Lib$Erase_Page (  6,  1 )
		Call Lib$Set_Scroll ( 11, 24 )
		Call Lib$Set_Cursor (  1,  1 )
	    End If
c
	    If ( .not. Screen ) Write ( 2, 60 ) FF
c
	    II = Index ( Last_Name,  '  ' ) - 1
	    If ( II .le. 0 ) II = 20
	    JJ = Index ( First_Name, '  ' ) - 1
	    If ( JJ .le. 0 ) JJ = 20
	    KK = Index ( Student_Number, '  ' ) - 1
	    If ( KK .le. 0 ) KK = 20
	    LL = Index ( Department_Name, '  ' ) - 1
	    If ( LL .le. 0 ) LL = 20
c
	    Write ( 2, 10 )		First_Name( : JJ ),
	1				Last_Name( : II ),
	1				Student_Number( : KK ),
	1				Department_Name( : LL ),
	1				Comment
	    Write ( 2, 20 )
	    Write ( 2, 30 ) ( (	Test_Score( I ),
	1				Manager_Scale( I ),
	1				Manager_Weights( I ),
	1				Test_Comments( I ),
	1				Manager_Score_Average( I ),
	1				Test_Dropped( I )	),
	1				I = 1, Number )
	    Write ( 2, 40 )
c
	    If ( Letter_Grade .eq. Null ) Letter_Grade = 'F'
c
	    Write ( 2, 50 )		Average_Grade,
	1				Letter_Grade,
	1				( Average_Needed ( I ), I = 1, 3 )
c
	End If
c
	If ( Screen ) Then
	    Call Lib$Put_Screen ( Cr // Lf // Lf //
	1			  ' Hit <RETURN> to continue ', , , 2 )
	    Call Lib$Get_Screen ( Option, , )
	    Call Lib$Set_Scroll ( 1, 24 )
	End If
c
	Call Lib$Erase_Page ( 6, 1 )
c
	Return
c
10	Format ( /////,
	1	 'Student:    ', A, ' ', A, T57, A, /,
	1	 'Department: ', A, T57, A )
20	Format ( /,
	1	 T4, 'Score', T15, 'Scale', T25, 'Weight', T34, 'Comment',
	1	T54, 'Class Average', T70, 'Dropped', /,
	1	 76( '-' ) )
30	Format ( <Number>( F8.2, T12, F8.2, T23, F8.2, T34, A, T55, F8.2,
	1		   T73, L1, / ) )
40	Format ( '    Average        Letter',
	1	 '    Average needed for remaining scores to make:', /
	1	 '     Score         Grade', T39, 'A', TR12, 'B',
	1	 TR12, 'C' )
50	Format ( F10.2, T22, A, T34, F8.2, TR5, F8.2, TR5, F8.2 )
60	Format ( 4(' ', / ), A )
c		  
	End



	Subroutine Full_Display ( Screen, Key )
c
	Include		'Student.Rec'
	Include		'Manager.Rec'
c
	Integer		Get_Integer,	Start,	Finish
	Integer		Key
c
	Logical*1	Screen
c
	Character*1	FF / 12 /,	Cr / 13 /,	Lf / 10 /
	Character*1	Null / 0 /,	Option
c
	If ( Get_Integer ( Number,  10, 1, 1, Manager_Num_Tests,
	1	'Enter the number of scores to be displayed' ) ) Then
		 
c
	    New_Page = 60 / ( Number + 14 )
	    Line_Count = New_Page
c
	    Read (	Data_File_Lun,
	1		KeyGt	= Null,
	1		KeyId	= Key,
	1		IoStat	= Ios ) Student_Record
c
	    If ( Screen ) Then
		Call Lib$Erase_Page (  6,  1 )
		Call Lib$Set_Scroll (  8, 24 )
		Call Lib$Set_Cursor (  6,  1 )
	    Else
		Write ( 2, 70 ) FF
	    End If
c
	    Do While ( Ios .eq. 0 )
c
		Line_Count = Line_Count + 1
c
		If (	( .not. Screen ) .and.
	1		( Line_Count .gt. New_Page )	) Then
		    Write ( 2, 60 ) FF
		    Line_Count = 1
		End If
c
		II = Index ( Last_Name,  '  ' ) - 1
		If ( II .le. 0 ) II = 20
		JJ = Index ( First_Name, '  ' ) - 1
		If ( JJ .le. 0 ) JJ = 20
		KK = Index ( Student_Number, '  ' ) - 1
		If ( KK .le. 0 ) KK = 20
		LL = Index ( Department_Name, '  ' ) - 1
		If ( LL .le. 0 ) LL = 20
c
		Write ( 2, 10 )		First_Name( : JJ ),
	1				Last_Name( : II ),
	1				Student_Number( : KK ),
	1				Department_Name( : LL ),
	1				Comment
		Write ( 2, 20 )
		Write ( 2, 30 ) ( (	Test_Score( I ),
	1				Manager_Scale( I ),
	1				Manager_Weights( I ),
	1				Test_Comments( I ),
	1				Manager_Score_Average( I ),
	1				Test_Dropped( I )	),
	1				I = 1, Number )
		Write ( 2, 40 )
c
		If ( Letter_Grade .eq. Null ) Letter_Grade = 'F'
c
		Write ( 2, 50 )		Average_Grade,
	1				Letter_Grade,
	1				( Average_Needed ( I ), I = 1, 3 )
c
		Read (	Data_File_Lun,
	1		IoStat	= Ios ) Student_Record
c
	    End Do
c
	End If
c
	If ( Screen ) Then
	    Call Lib$Put_Screen ( Cr // Lf // Lf //
	1			  ' Hit <RETURN> to continue ', , , 2 )
	    Call Lib$Get_Screen ( Option, , )
	    Call Lib$Set_Scroll ( 1, 24 )
	End If
c
	Return
c
10	Format ( /////,
	1	 'Student:    ', A, ' ', A, T57, A, /,
	1	 'Department: ', A, T57, A )
20	Format ( /,
	1	 T4, 'Score', T15, 'Scale', T25, 'Weight', T34, 'Comment',
	1	T54, 'Class Average', T70, 'Dropped', /,
	1	 76( '-' ) )
30	Format ( <Number>( F8.2, T12, F8.2, T23, F8.2, T34, A, T55, F8.2,
	1		   T73, L1, / ) )
40	Format ( '    Average        Letter',
	1	 '    Average needed for remaining scores to make:', /
	1	 '     Score         Grade', T39, 'A', TR12, 'B',
	1	 TR12, 'C' )
50	Format ( F10.2, T22, A, T34, F8.2, TR5, F8.2, TR5, F8.2 )
60	Format ( A )
70	Format ( 4(' ', / ), A )
c
	End



	Subroutine Brief_Display ( Screen, Key )
c
	Include		'Student.Rec'
	Include		'Manager.Rec'
c
	Integer		Get_Integer,	Start,	Finish,	Key
	Integer		A,	B,	C,	D,	F
c
	Logical*1	Screen
c
	Character*22	Ident
	Character*1	Null / 0 /
	Character*1	FF / 12 /,	Cr / 13 /,	Lf / 10 /
	Character*1	Option,		Aster( Maximum_Tests )
c
	If ( (	( Get_Integer ( Start,  10, 1, 1, Manager_Num_Tests,
	1	'Enter the first score to be displayed' ) ) .and.
	1	( Get_Integer ( Finish, 11, 1, Start,
	1	Min ( Manager_Num_Tests, Start + 4 ),
	1	'Enter the last score to be displayed' ) ) ) ) Then
c
	    Number = Finish - Start + 1
c
	    Line_length = ( 34 + ( 9 * Number ) )
c
	    Read (	Data_File_Lun,
	1		KeyGt	= Null,
	1		KeyId	= Key,
	1		IoStat	= Ios ) Student_Record
c
	    If ( Screen ) Then
		Call Lib$Erase_Page (  6,  1 )
		Call Lib$Set_Scroll (  9, 24 )
		Call Lib$Set_Cursor (  6,  1 )
		Write ( 2, 10 ) Null, ( Manager_Test_Name( I ),
	1				I = Start, Finish )
		Write ( 2, 20 ) ( Manager_Weights( I ),	I = Start, Finish )
		Write ( 2, 40 ) Cr // Lf
	    End If
c
	    Line_Number = -1
c
	    Do While ( Ios .eq. 0 )
c
		If ( ( .not. Screen ) .and. ( Line_Number .ge. 54 ) ) Then
		    Write ( 2, 60 )
		    Write ( 2, 10 ) FF, ( Manager_Test_Name( I ),
	1				I = Start, Finish )
		    Write ( 2, 20 ) ( Manager_Weights( I ),
	1				I = Start, Finish )
		    Write ( 2, 40 ) Cr // Lf
		    Line_Number = 0
		Else If ( ( .not. Screen ) .and. ( Line_Number .lt. 0 ) ) Then
		    Write ( 2, 10 ) FF, ( Manager_Test_Name( I ),
	1				I = Start, Finish )
		    Write ( 2, 20 ) ( Manager_Weights( I ),
	1				I = Start, Finish )
		    Write ( 2, 40 ) Cr // Lf
		    Line_Number = 0
		End If
c
		Line_Number = Line_Number + 1
c
		If ( Key .eq. 0 ) Then
		    II = Index ( Last_Name, '  ' ) - 1
		    If ( II .le. 0 ) II = 20
		    JJ = Index ( First_Name, '  ' ) - 1
		    If ( JJ .le. 0 ) JJ = 20
		    If ( ( II + JJ ) .gt. 20 ) JJ = 20 - II
		    Ident = Last_Name( : II ) // ', ' // First_Name( : JJ )
		    Ident_Size = Min ( 22, II + JJ + 2 )
		Else If ( Key .eq. 1 ) Then
		    Ident = Student_Number // '  '
		    Ident_Size = 22
		Else If ( Key .eq. 2 ) Then
		    Ident = Department_Name // '  '
		    Ident_Size = 22
		End If
c
		Do K = Start, Finish
		   If ( Test_Dropped( K ) ) Then
			Aster( K ) = '*'
		   Else
			Aster( K ) = ' '
		   End If
		End Do
c
		Write ( 2, 30 ) Ident( : Ident_Size ),
	1	      ( ( Test_Score( K ) + Manager_Scale( K ),
	1		  Aster( K ) ), K = Start, Finish ),
	1	      Average_Grade, Letter_Grade, Cr
c
		Read (	Data_File_Lun,
	1		IoStat	= Ios ) Student_Record
c
	    End Do
c
	    Ident_Size = 15
c
	    Write ( 2, 30 ) 'CLASS AVERAGES:',
	1	      ( ( Manager_Score_Average( K ), ' ' ),
	1	      K = Start, Finish ),
	1	      Manager_Average_Grade, ' ', Cr // Lf
c
	    Write ( 2, 60 )
c
	    If ( Screen ) Then
		Write ( 2, 50 ) Null
		Call Lib$Set_Scroll (  6, 24 )
		Call Hist ( 2,
	1		Manager_Counts( 1 ),
	1		Manager_Counts( 2 ),
	1		Manager_Counts( 3 ),
	1		Manager_Counts( 4 ),
	1		Manager_Counts( 5 ), 18 )
	    Else
		Write ( 2, 50 ) FF
		Call Hist ( 2,
	1		Manager_Counts( 1 ),
	1		Manager_Counts( 2 ),
	1		Manager_Counts( 3 ),
	1		Manager_Counts( 4 ),
	1		Manager_Counts( 5 ), 50 )
	    End If
c
	    If ( Screen ) Then
		Call Lib$Put_Screen ( Cr // Lf // Lf //
	1			  ' Hit <RETURN> to continue ', , , 2 )
		Call Lib$Get_Screen ( Option, , )
		Call Lib$Set_Scroll ( 1, 24 )
	    End If
c
	End If
c
	Return
c
10	Format ( A, 'Student                  ',
	1		<Number>( A8, ' ' ), '   Grade' )
20	Format ( 25X, <Number>( 'W:', F6.2, ' '   ), '  Average' )
30	Format ( A, <24 - Ident_Size>X, <Number>(F8.2, A1), F8.2, X, A, A )
40	Format ( <Line_Length>( '-' ), A )
50	Format ( ///, A, ///, 14X,
	1	'Histogram of Letter Grade Distributions',/ )
60	Format ( '_______________________', //,
	1	 ' * This score dropped.' )
c
	End



	Subroutine Hist ( Lun, A, B, C, D, F, Len )
c
	Integer		A,	B,	C,	D,	F
	Integer		Lun,	Len
c
	Integer		Max_Cnt,	Basic_Units
	Integer		Inter_Unit_Step_Size
c
	Character*9	CA, CB, CC, CD, CF
c
	Basic_Units = ( Max( A, B, C, D, F) + 4 ) / 5 
	Max_Cnt = Basic_Units * 5
	Inter_Unit_Step_Size = Max( ((Len - 2) / Max_Cnt) , 1)
	CA = '          '
	CB = '          '
	CC = '          '
	CD = '          '
	CF = '          '
c
	Do I = Max_Cnt, 1, -5
c
	    If ( A .ge. I ) CA = '#########'
	    If ( B .ge. I ) CB = '#########'
	    If ( C .ge. I ) CC = '#########'
	    If ( D .ge. I ) CD = '#########'
	    If ( F .ge. I ) CF = '#########'
c
	    Write( Lun, 10 ) I, CF, CD, CC, CB, CA
c
	    Do K = 1, Inter_Unit_Step_Size - 1
		Write( Lun, 20 ) CF, CD, CC, CB, CA
	    End Do
c
	    Do J = 1, 4
c
		L = I - J
		If ( A .ge. L ) CA = '#########'
		If ( B .ge. L ) CB = '#########'
		If ( C .ge. L ) CC = '#########'
		If ( D .ge. L ) CD = '#########'
		If ( F .ge. L ) CF = '#########'
c
		Do K = 1, Inter_Unit_Step_Size
		    Write( Lun, 20 ) CF, CD, CC, CB, CA
		End Do
	    End Do
	End Do
c
	Write ( Lun, 30 )
	Write ( Lun, 40 ) 'F', 'D', 'C', 'B', 'A'
	Write ( Lun, 50 ) F, D, C, B, A
c
	Return
c
10	Format ( I5, ' --+', 5(A,' ' ) )
20	Format ( 5X, '   |', 5(A,' ' ) )
30	Format ( 4X, '0 --+', 5('---------+'))
40	Format ( 5X, '   |', 5( '    ', A ,'    |' ) )
50	Format ( 5X, '   |', 5( '   (', I2 ,')  |' ) )
c
	End



	Subroutine Student_Roster ( Screen, Key )
c
	Include		'Student.Rec'
	Include		'Manager.Rec'
c
	Integer		Key,	Student_Count,	Page_Number
c
	Logical*1	Screen
c
	Character*40	Full_Name
	Character*15	Key_Name
	Character*1	FF / 12 /,	Cr / 13 /,	Lf / 10 /
	Character*1	Null / 0 /,	Option
c
	Student_Count = 0
c
	If ( Key .eq. 0 ) Then
	     Key_Name = 'Student Name'
	     LL = 12
	Else If ( Key .eq. 1 ) Then
	     Key_Name = 'Student Number'
	     LL = 14
	Else
	     Key_Name = 'Department Name'
	     LL = 15
	End If
c
	Read (	Data_File_Lun,
	1		KeyGt	= Null,
	1		KeyId	= Key,
	1		IoStat	= Ios ) Student_Record
c
	Page_Number = 1
c
	If ( Screen ) Then
	    Call Lib$Erase_Page (  6,  1 )
	    Call Lib$Set_Scroll (  9, 24 )
	    Call Lib$Set_Cursor (  7,  1 )
	Else
	    Write ( 2, 10 ) FF, Page_Number, Key_Name( : LL )
	End If
c
	Write ( 2, 15 )
	Write ( 2, 20 ) Cr // Lf
c
	Line_Number = -1
c
	Do While ( Ios .eq. 0 )
c
	    If ( ( .not. Screen ) .and. ( Line_Number .ge. 54 ) ) Then
		Line_Number = 0
		Page_Number = Page_Number + 1
		Write ( 2, 10 ) FF, Page_Number, Key_Name( : LL )
		Write ( 2, 15 )
		Write ( 2, 20 ) Cr // Lf
	    End If
c
	    Line_Number = Line_Number + 1
	    Student_Count = Student_Count + 1
c
	    II = Index( Last_Name, '  ' ) - 1
	    JJ = Index( First_Name, '  ' ) - 1
	    If ( II .lt. 1 ) II = 20
	    If ( JJ .lt. 1 ) JJ = 20
	    Full_Name = Last_Name( : II ) // ', ' // First_Name( : JJ )
	    KK = JJ + II + 2
	    If ( KK .gt. 30 ) KK = 30
c		
	    Write ( 2, 30 )	Student_Count, Full_Name( : KK ),
	1			Student_Number, Department_Name
c
	    Read (	Data_File_Lun,
	1		IoStat	= Ios ) Student_Record
c
	End Do
c
	If ( Screen ) Then
	    Call Lib$Put_Screen ( Cr // Lf // Lf //
	1			  ' Hit <RETURN> to continue ', , , 2 )
	    Call Lib$Get_Screen ( Option, , )
	    Call Lib$Set_Scroll ( 1, 24 )
	End If
c
	Return
c
10	Format ( A, /, T33, 'Student Roster', T69, 'Page', I3, /,
	1	 T<(80-(LL+10))/2>, 'Sorted By ', A )
			 
15	Format ( T6, 'Student Name', T37, 'Student Number',
	1	 T58, 'Department Name' )
20	Format ( 75( '-' ), A )
30	Format ( I3, '. ', A, T37, A, T58, A )
c
	End



	Subroutine Manager_Menu
c
	Parameter	Maximum_Tests	= 20
c
	Include		'Manager.Rec'
c
	Character*1	Option
c
	Logical*1	Done
c
	Done = .False.
c
	If ( Manager_Num_Tests .lt. 1 ) Call Change_Test_Count( 8 )
c
	Do While ( .Not. Done )
c
	    Call Draw_Manager_Menu
c
	    Length = 1
	    Option = '?'
c
	    Call Select_Option ( 'ABCLN', Option, Length, 21, 33, 1 )
c
	    If ( Length .le. 0 ) Then
		Done = .True.
	    Else If ( Option .eq. 'A' ) Then
		Call Add_Test_Weights
	    Else If ( Option .eq. 'B' ) Then
		Call Build_Flat_File
	    Else If ( Option .eq. 'C' ) Then
		Call Modify_Test_Weights
	    Else If ( Option .eq. 'L' ) Then
		Call Load_Flat_File
	    Else If ( Option .eq. 'N' ) Then
		Call Change_Test_Count( 7 )
	    End If
c
	End Do
c
	Return
	End



	Subroutine Load_Flat_File
c
	Include		'Student.Rec'
	Include		'Manager.Rec'
c
	Logical*1	Screen
c
	Character*80	File_Name
	Character*1	So / 14 /,	Si / 15 /,	Null / 0 /
	Character*1	FF / 12 /,	Cr / 13 /,	Lf / 10 /
	Character*1	Option
c
	Call Lib$Erase_Page (	 8,	 1 )
	Call Lib$Put_Screen ( So // 'm' // Si,	 7,	21, 1 )
	Call Lib$Put_Screen ( So // 'j' // Si,	 7,	60, 1 )
c
	Call Lib$Put_Screen ( 'Enter input specification: ', 9, 1, 1 )
	Call Lib$Get_Screen ( File_Name, , Length )
	Call Str$UpCase ( File_Name( : Length ), File_Name( : Length ) )
c
	If (	( File_Name ( :  9 ) .eq. 'SYS$INPUT'	) .or.
	1	( File_Name ( :  3 ) .eq. 'TT:'		) ) Then
	    Screen = .True.
	Else
	    Screen = .False.
	End If
c
	Call Lib$Erase_Page ( 8,  1 )
	Call Lib$Set_Scroll ( 10, 24 )
	Call Lib$Put_Screen (
	1	' Loading student database from the flat file... ',
	1			9,	16,	2 )
c
	Open (	Unit		= 2,
	1	Name		= File_Name( : Length ),
	1	DefaultFile	= 'Flat.Dat',
	1	Status		= 'OLD',
	1	Access		= 'Sequential',
	1	Organization	= 'Sequential',
	1	Form		= 'Formatted',
	1	Err		= 100,
	1	CarriageControl	= 'LIST' )
c
	Read (	Data_File_Lun,
	1	Key	= Null,
	1	KeyId	= 0,
	1	IoStat	= Ios ) Manager_Record
c
	Read ( 2, 10, End = 200 ) Option
	Read ( 2, 11 )	( Manager_Counts( I ), I = 1, 5 ), Manager_Num_Tests,
	1		  Manager_Average_Grade
	Read ( 2, 12 )	( Manager_Dropped( I ), I = 1, Maximum_Tests )
	Read ( 2, 13 )	( Manager_Weights( I ), I = 1, Maximum_Tests )
	Read ( 2, 13 )  ( Manager_Scale( I ),   I = 1, Maximum_Tests )
	Read ( 2, 13 )	( Manager_Score_Average( I ), I = 1, Maximum_Tests )
	Read ( 2, 14,
	1IoStat = Jos )	( Manager_Test_Name( I ), I = 1, Maximum_Tests )
c
	Rewrite ( Data_File_Lun, IoStat = Ios ) Manager_Record
c
	Do While ( Jos .eq. 0 )
c
	    Read ( 2, 20, End = 300 ) Last_Name, First_Name,
	1				Student_Number,
	1				Department_Name
	    Read ( 2, 20 ) ( Test_Comments( I ), I = 1, Maximum_Tests )
	    Read ( 2, 21 ) Comment, Letter_Grade
	    Read ( 2, 22 ) ( Test_Dropped( I ), I = 1, Maximum_Tests )
	    Read ( 2, 23 ) ( Test_Score( I ), I = 1, Maximum_Tests )
	    Read ( 2, 24, IoStat = Jos ) Average_Grade,
	1				( Average_Needed( I ), I = 1, 3 )
c
	    Write (	Data_File_Lun,
	1		IoStat	= Ios ) Student_Record
c
	    If ( Ios .ne. 0 ) Then
		Call Lib$Erase_Page (	18,	1 )
		Call Lib$Put_Screen ( '%GRADE-E-ADDERR, error adding ',
	1				18,	1,	1  )
		Call Display_Current_Record ( 18, 31 )
		Call Lib$Put_Screen ( ' Continue? ',	21,	34, 2 )
		Call Lib$Get_Screen ( Option, , )
		If ( ( Option .ne. 'Y' ) .and. ( Option .ne. 'y' ) ) Jos = -1
	    End If
c
	End Do
c
	Close ( Unit = 2 )
c
	Call Lib$Set_Scroll ( 1, 24 )
c
	Return
c
100	Call Lib$Erase_Page (	18,	1 )
	Call Lib$Put_Screen ( '%GRADE-F-FNF, file not found',
	1				18,	1,	1  )
	Call Lib$Put_Screen ( ' Hit <RETURN> to continue ', 20, 1, 2 )
	Call Lib$Get_Screen ( Option, , )
	Call Lib$Set_Scroll ( 1, 24 )
	Return
c
200	Call Lib$Erase_Page (	18,	1 )
	Call Lib$Put_Screen ( '%GRADE-E-FLEMPTY, student flat file is empty',
	1				18,	1,	1  )
	Call Lib$Put_Screen ( ' Hit <RETURN> to continue ', 20, 1, 2 )
	Call Lib$Get_Screen ( Option, , )
	Call Lib$Set_Scroll ( 1, 24 )
	Close ( Unit = 2 )
	Return
c
300	Close ( Unit = 2 )
	Call Lib$Set_Scroll ( 1, 24 )
	Return
c
10	Format ( A )
11	Format ( 6I10, F10.3 )
12	Format ( <Maximum_Tests>L3 )
13	Format ( 5F10.3 )
14	Format ( 10A8 )
c
20	Format ( 4A20 )
21	Format ( A20, A1 )
22	Format ( <Maximum_Tests>L3 )
23	Format ( 5F10.3 )
24	Format ( 4F10.3 )
c
	End



	Subroutine Build_Flat_File
c
	Include		'Student.Rec'
	Include		'Manager.Rec'
c
	Logical*1	Screen
c
	Character*80	File_Name
	Character*1	So / 14 /,	Si / 15 /,	Null / 0 /
	Character*1	FF / 12 /,	Cr / 13 /,	Lf / 10 /
	Character*1	Option
c
	Call Lib$Erase_Page (	 8,	 1 )
	Call Lib$Put_Screen ( So // 'm' // Si,	 7,	21, 1 )
	Call Lib$Put_Screen ( So // 'j' // Si,	 7,	60, 1 )
c
	Call Lib$Put_Screen ( 'Enter output specification: ', 9, 1, 1 )
	Call Lib$Get_Screen ( File_Name, , Length )
	Call Str$UpCase ( File_Name( : Length ), File_Name( : Length ) )
c
	If (	( File_Name ( : 10 ) .eq. 'SYS$OUTPUT'	) .or.
	1	( File_Name ( :  3 ) .eq. 'TT:'		) ) Then
	    Screen = .True.
	Else
	    Screen = .False.
	End If
c
	Call Lib$Erase_Page ( 8,  1 )
	Call Lib$Set_Scroll ( 10, 24 )
	Call Lib$Put_Screen ( ' Putting student database into a flat file... ',
	1			9,	17,	2 )
c
	Open (	Unit		= 2,
	1	Name		= File_Name( : Length ),
	1	DefaultFile	= 'Flat.Dat',
	1	Status		= 'NEW',
	1	Access		= 'Sequential',
	1	Organization	= 'Sequential',
	1	Form		= 'Formatted',
	1	Recl		= 80,
	1	CarriageControl	= 'LIST' )
c
	Read (	Data_File_Lun,
	1	Key	= Null,
	1	KeyId	= 0,
	1	IoStat	= Ios ) Manager_Record
c
	Write ( 2, 10 )
	Write ( 2, 11 ) ( Manager_Counts( I ), I = 1, 5 ), Manager_Num_Tests,
	1		  Manager_Average_Grade
	Write ( 2, 12 ) ( Manager_Dropped( I ), I = 1, Maximum_Tests )
	Write ( 2, 13 ) ( Manager_Weights( I ), I = 1, Maximum_Tests )
	Write ( 2, 13 )	( Manager_Scale( I ),   I = 1, Maximum_Tests )
	Write ( 2, 13 )	( Manager_Score_Average( I ), I = 1, Maximum_Tests )
	Write ( 2, 14 )	( Manager_Test_Name( I ), I = 1, Maximum_Tests )
c
	Read (	Data_File_Lun,
	1	IoStat	= Ios ) Student_Record
c
	Do While ( Ios .eq. 0 )
c
	    Write ( 2, 20 ) Last_Name, First_Name, Student_Number,
	1			Department_Name
	    Write ( 2, 20 ) ( Test_Comments( I ), I = 1, Maximum_Tests )
	    Write ( 2, 21 ) Comment, Letter_Grade
	    Write ( 2, 22 ) ( Test_Dropped( I ), I = 1, Maximum_Tests )
	    Write ( 2, 23 ) ( Test_Score( I ), I = 1, Maximum_Tests )
	    Write ( 2, 24 ) Average_Grade, ( Average_Needed( I ), I = 1, 3 )
c
	    Read (	Data_File_Lun,
	1		IoStat	= Ios ) Student_Record
c
	End Do
c
	Close ( Unit = 2 )
c
	If ( Screen ) Then
	    Call Lib$Put_Screen ( Cr // Lf // Lf //
	1			  ' Hit <RETURN> to continue ', , , 2 )
	    Call Lib$Get_Screen ( Option, , )
	End If
c
	Call Lib$Set_Scroll ( 1, 24 )
c
	Return
c
10	Format ( '****** File Management Record (Keys are all NULL) ******' )
11	Format ( 6I10, F10.3 )
12	Format ( <Maximum_Tests>L3 )
13	Format ( 5F10.3 )
14	Format ( 10A8 )
c
20	Format ( 4A20 )
21	Format ( A20, A1 )
22	Format ( <Maximum_Tests>L3 )
23	Format ( 5F10.3 )
24	Format ( 4F10.3 )
c
	End



	Subroutine Add_Test_Weights
c
	Parameter	Maximum_Tests	= 20
	Parameter	Data_File_Lun	= 1
c
	Include		'Manager.Rec'
c
	Character*1	Null / 0 /
c
	Read (	Data_File_Lun,
	1	Key	= Null,
	1	KeyId	= 0,
	1	IoStat	= Ios ) Manager_Record
c
	Call Draw_Menu_Header ( 'Add Test Weights', 3 )
	Call Setup_Add_Test_Weights( 13, 16 )
c
	Do I = 1, Manager_Num_Tests
	    Call Get_Test_Weights( I )
	End Do
c
	ReWrite ( Data_File_Lun ) Manager_Record
	Return
c
	End


	Subroutine Modify_Test_Weights
c
	Parameter	Maximum_Tests	= 20
	Parameter	Data_File_Lun	= 1
c
	Include		'Manager.Rec'
c
	Integer		Get_Integer
c
	Character*1	Null / 0 /
c
	Read (	Data_File_Lun,
	1	Key	= Null,
	1	KeyId	= 0,
	1	IoStat	= Ios ) Manager_Record
c
	Call Draw_Menu_Header ( 'Modify Test Weights', 3 )
c
	Call Setup_Add_Test_Weights( 13, 16 )
c
	Do While ( Get_Integer ( I, 9, 1, 1, Manager_Num_Tests,
	1	'Enter the number of the score to be modified' ) )
c
	    Call Get_Test_Weights( I )
c
	End Do
c
	ReWrite ( Data_File_Lun ) Manager_Record
	Return
c
	End



	Subroutine Change_Test_Count ( Row )
c
	Parameter	Maximum_Tests	= 20
	Parameter	Data_File_Lun	= 1
c
	Include		'Manager.Rec'	
c
	Integer		Row,	Get_Integer
c
	Character*2	Number,		Input
	Character*1	So / 14 /,	Si / 15 /,	Null / 0 /
c
	Call Lib$Erase_Page (				Row + 1,   1 )
	Call Lib$Put_Screen ( So // 'm' // Si,	 Row,	21, 1 )
	Call Lib$Put_Screen ( So // 'j' // Si,	 Row,	60, 1 )
	Call Lib$Put_Screen ( So // 'oo' // Si,		Row + 5, 43, 1 )
c
	Write ( Number, 10 ) Manager_Num_Tests
	Call Lib$Erase_Line (		Row + 7,	 1 )
	Call Lib$Put_Screen ( Number,	Row + 7,	43, 2 )
c
	If ( Manager_Num_Tests .gt. 0 ) Then
	    K = Manager_Num_Tests
	Else
	    K = 1
	End If
c
	Do While ( Get_Integer ( K, Row + 4, 1, 1, Maximum_Tests,
	1	'Enter the total number of tests' ) .or. ( K .le. 0 ) )
c
	    Write ( Number, 10 ) K
	    Call Lib$Erase_Line (		Row + 7,	 1 )
	    Call Lib$Put_Screen ( Number,	Row + 7,	43, 2 )

	End Do			
c
	Read (	Data_File_Lun,
	1	Key	= Null,
	1	KeyId	= 0,
	1	IoStat	= Ios )   Manager_Record
c
	Manager_Num_Tests = K
c
	ReWrite ( Data_File_Lun ) Manager_Record
c
	Return
c
10	Format ( I2 )
c
	End



	Subroutine Get_Test_Weights( I )
c
	Parameter	Maximum_Tests	= 20
	Parameter	Data_File_Lun	= 1
c
	Include		'Manager.Rec'
c
	Character*10	Current_Weight,		Input_Weight
	Character*10	Current_Scale,		Input_Scale
	Character*5	Current_Drop
	Character*2	Number
	Character*1	So / 14 /,	Si / 15 /,	Null / 0 /
	Character*1	Bell / 7 /,	Cr / 13 /,	Lf / 10 /
	Character*1	Option
c
	Write ( Number, 10 ) I
	Call Lib$Put_Screen ( 'Score ' // Number,	13,	 1,	1 )
c
	Write ( Current_Weight, 20 ) Manager_Weights( I )
	Write ( Current_Scale, 20 ) Manager_Scale( I )
	If ( Manager_Dropped( I ) ) Then
	    Current_Drop = ' True'
	Else
	    Current_Drop = 'False'
	End If
c
	Call Lib$Erase_Line ( 17,	 1 )
	Call Lib$Put_Screen ( Current_Weight,	17,	11,	2 )
	Call Lib$Put_Screen ( Current_Scale,	17,	31,	2 )
	Call Lib$Put_Screen ( Manager_Test_Name(I), 17,	51,	2 )
	Call Lib$Put_Screen ( Current_Drop,	17,	71,	2 )
c
	Call Lib$Erase_Line (	15,	1 )
	Call Get_Real ( Manager_Weights( I ), 15, 11 )
	Call Get_Real ( Manager_Scale( I ),  15, 31 )
	Call Get_Test_Name ( Manager_Test_Name( I ), 15, 51 )
	Call Get_Logi ( Manager_Dropped( I ), 15, 71 )
c
	Return
c
 10	Format ( I2 )
 20	Format ( F10.2 )
 30	Format ( F10.0 )
c
	End



	Subroutine Get_Test_Name ( Default, Row, Col )
c
	Character*8	Default,	Option
c
	Integer		Row,	Col
c
	Call Lib$Set_Cursor (	Row,	Col )
	Call Get_Option( Option, Length )
c
	If ( Length .gt. 0 ) Default = Option
c
	Call Lib$Erase_Line (	Row,	Col )
	Call Lib$Put_Screen ( Default,	Row,	Col,	1 )
c
	Return
	End



	Subroutine Get_Real ( Value, Row, Col )
c
	Real		Value
c
	Character*10	String
c
	Integer		Row,	Col
c
	Ios = -1
c
	Do While ( Ios .ne. 0 )
c
	    Call Lib$Set_Cursor (	Row,	Col )
	    Call Lib$Get_Screen ( String, , Length )
	    If ( Length .gt. 0 ) Then
		Read (	String( : Length ), 30,	IOStat = Ios ) X
	    Else
		Ios = 0
	    End If
c
	End Do
c
	If ( Length .gt. 0 ) Then
	    Value = X
	Else
	    X = Value
	End If
c
	Write ( String, 20 ) X
	Call Lib$Erase_Line (	Row,	Col )
	Call Lib$Put_Screen ( String,	Row,	Col,	1 )
c
 20	Format ( F10.2 )
 30	Format ( F10.0 )
c
	Return
	End



	Subroutine Get_Logi ( Value, Row, Col )
c
	Logical*1		Value,	X
c
	Character*5	String
	Character*1	Option
c
	Integer		Row,	Col
c
	Ios = -1
c
	Do While ( Ios .ne. 0 )
c
	    Call Lib$Set_Cursor (	Row,	Col )
	    Call Get_Option( Option, Length )
c
	    If ( ( Length .gt. 0 ) .and. ( Option .eq. 'T' ) )Then
		Value = .True.
		String = ' True'
		Ios = 0
	    Else If ( ( Length .gt. 0 ) .and. ( Option .eq. 'F' ) )Then
		Value = .False.
		String = 'False'
		Ios = 0
	    Else If ( ( Value ) .and. ( Length .lt. 1 ) ) Then
		String = ' True'
		Ios = 0
	    Else If ( ( .Not. Value ) .and. ( Length .lt. 1 ) ) Then
		String = 'False'
		Ios = 0
	    End If
c
	End Do
c
	Call Lib$Erase_Line (	Row,	Col )
	Call Lib$Put_Screen ( String,	Row,	Col,	1 )
c
	Return
	End



	Subroutine Setup_Add_Test_Weights ( I, J )
c
	Character*1	So / 14 /,	Si / 15 /
c
	Call Lib$Put_Screen ( 'Weight',		I,	13, 1 )
	Call Lib$Put_Screen ( 'Scale',		I,	33, 1 )
	Call Lib$Put_Screen ( 'Name',		I,	53, 1 )
	Call Lib$Put_Screen ( 'Droppable',	I,	69, 1 )
c
	Call Lib$Put_Screen ( So // 'oooooooooo' // Si,
	1					J,	11,	1 )
	Call Lib$Put_Screen ( So // 'oooooooooo' // Si,
	1					J,	31,	1 )
	Call Lib$Put_Screen ( So // 'oooooooo' // Si,
	1					J,	51,	1 )
	Call Lib$Put_Screen ( So // 'ooooo' // Si,
	1					J,	71,	1 )
c
	Return
	End



	Subroutine Update_Menu
c
	Character*1	Option
c
	Logical*1	Done
c
	External	Delete_Student

	Done = .False.
c
	Do While ( .Not. Done )
c
	    Call Draw_Update_Menu
c
	    Length = 1
	    Option = '?'
c
	    Call Select_Option ( 'ADMR', Option, Length, 19, 33, 1 )
c
	    If ( Option .eq. 'A' ) Then
		Call Add_Student
	    Else If ( Option .eq. 'D' ) Then
		Call Select_Student_Menu (	'Delete  Menu',
	1					'deleted',
	1					'Delete Students',
	1					Delete_Student	)
	    Else If ( Option .eq. 'M' ) Then
		Call Modify_Student_Menu
	    Else If ( Option .eq. 'R' ) Then
		Done = .False.
	    Else
		Done = .True.
	    End If
c
	End Do
c
	Return
	End



	Subroutine Modify_Student_Menu
c
	Character*1	Option
c
	Logical*1	Done
c
	Integer		Key
c
	External	Modify_Student
c
	Done = .False.
c
	Do While ( .Not. Done )
c
	    Call Draw_Modify_Menu
c
	    Length = 1
	    Option = '?'
c
	    Call Select_Option ( 'AC', Option, Length, 17, 33, 1 )
c
	    If ( Length .le. 0 ) Then
		Done = .True.
	    Else If ( Option .eq. 'A' ) Then
		Call Add_Grades
	    Else If ( Option .eq. 'C' ) Then
		Call Draw_Menu_Header ( 'Change Students', 1 )
		Call Select_By_Key ( 0, 'LAST name',
	1				'modified', Modify_Student )
	    End If
c
	End Do
c
	Return
	End



	Subroutine Modify_Student ( Key_Value, Key_Number )
c
	Character	Key_Value*(*)
	Character*1	So / 14 /,	Si / 15 /,	Option
c
	Integer		Key_Number
c
	Logical*1	Done
c
	Done = .False.
c
	Do While ( .not. Done )
c
	    Call Draw_Modify_Screen
c
	    Length = 1
	    Option = '?'
c
	    Call Select_Option ( 'CDLNST', Option, Length, 21, 33, 1 )
c
	    If ( Length .eq. 0 ) then
		Done = .True.
	    Else If ( Option .eq. 'C' ) Then
		Call Modify_Student_Comment ( Key_Value, Key_Number )
	    Else If ( Option .eq. 'D' ) Then
		Call Modify_Department_Name ( Key_Value, Key_Number )
	    Else If ( Option .eq. 'L' ) Then
		Call Modify_Letter_Grade ( Key_Value, Key_Number )
	    Else If ( Option .eq. 'N' ) Then
		Call Modify_Student_Number ( Key_Value, Key_Number )
	    Else If ( Option .eq. 'S' ) Then
		Call Modify_Test_Scores ( Key_Value, Key_Number )
	    Else If ( Option .eq. 'T' ) Then
		Call Modify_Test_Comment ( Key_Value, Key_Number )
	    End If
c
	End Do
c
	Call Lib$Erase_Page ( 6, 1 )
	Call Lib$Put_Screen ( So // 'm' // Si,	 5,	21, 1 )
	Call Lib$Put_Screen ( So // 'j' // Si,	 5,	60, 1 )
c
	Return
	End



	Subroutine Modify_Test_Comment ( Key_Value, Key_Number )	
c
	Include		'Student.Rec'
c
	Character	Key_Value*(*)
	Character*20	New_Comment
	Character*2	Number
	Character*1	So / 14 /,	Si / 15 /,	Null / 0 /
c
	Integer		Key_Number,	Grade_Number,	Get_Integer
c
	Call Lib$Erase_Page ( 6, 1 )
	Call Lib$Put_Screen ( So // 'm' // Si,	 5,	21, 1 )
	Call Lib$Put_Screen ( So // 'j' // Si,	 5,	60, 1 )
c
	Do While ( Get_Integer ( Grade_Number, 10, 1, 1, 20,
	1	'Enter the number of the comment to be modified' ) )
c
	    Write ( Number, 10 ) Grade_Number
	    If ( Number( 1: 1 ) .eq. ' ' ) Number ( 1: 1 ) = Null
	    Call Lib$Erase_Line ( 15, 1 )
	    Call Lib$Put_Screen ( 'Comment for grade ' // Number,
	1					15,	31, 1 )
	    Call Lib$Put_Screen ( So // 'oooooooooooooooooooo' // Si,
	1					18,	31, 1 )
c
	    Length = 1
c
	    Do While ( Length .gt. 0 )
		Call Lib$Erase_Line (		13,	 1 )
		Call Display_Current_Record (	13,	 1 )
c
		Call Lib$Put_Screen ( Test_Comments( Grade_Number ),
	1					19,	31, 2 )
c
		Call Lib$Set_Cursor ( 17, 31 )
		Call Lib$Erase_Line ( 17, 31 )
		Call Lib$Get_Screen ( New_Comment, , Length )
c
		If ( Length .gt. 0 ) Then
		    Call Str$UpCase (	Test_Comments( Grade_Number ),
	1				New_Comment )
		    Call Update_Record
		    Call ReRead_Record ( Key_Value, Key_Number )
		End If
c
	    End Do
c
	End Do
c
	Return
c
 10	Format ( I2 )
c
	End



	Subroutine Modify_Test_Scores ( Key_Value, Key_Number )	
c
	Include		'Student.Rec'
c
	Character	Key_Value*(*)
	Character*10	Default_Score,	Input_Score
	Character*2	Number
	Character*1	So / 14 /,	Si / 15 /,	Null / 0 /
c
	Integer		Key_Number,	Grade_Number,	Score_Ios
	Integer		Score_Length,	Get_Integer
c
	Call Lib$Erase_Page ( 6, 1 )
	Call Lib$Put_Screen ( So // 'm' // Si,	 5,	21, 1 )
	Call Lib$Put_Screen ( So // 'j' // Si,	 5,	60, 1 )
c
	Do While ( Get_Integer ( Grade_Number, 10, 1, 1, 20,
	1	'Enter the number of the grade to be modified' ) )
c
	    Call Display_Current_Record ( 13, 1 )
	    Write ( Number, 10 ) Grade_Number
	    If ( Number( 1: 1 ) .eq. ' ' ) Number ( 1: 1 ) = Null
	    Call Lib$Erase_Line ( 15, 1 )
	    Call Lib$Put_Screen ( 'Score for grade ' // Number,
	1					15,	31, 1 )
	    Call Lib$Put_Screen ( So // 'oooooooooo' // Si,
	1					18,	35, 1 )
c
	    Score_Length = 1
c
	    Do While ( Score_Length .gt. 0 )
c
		Write ( Default_Score, 20 ) Test_Score( Grade_Number )
		Call Lib$Put_Screen ( Default_Score,
	1					19,	35, 2 )
c
		Score_Ios = -1
c
		Do While ( Score_Ios .ne. 0 )
c
		    Call Lib$Erase_Line (	17,	35 )
		    Call Lib$Set_Cursor (	17,	35 )
		    Call Lib$Get_Screen ( Input_Score, , Score_Length )
c
		    If ( Score_Length .gt. 0 ) Then
			Read (	Input_Score( : Score_Length ), 30,
	1			IOStat = Score_Ios ) X
		    Else
			Score_Ios = 0
		    End If
c
		End Do
c
	    If ( Score_Length .gt. 0 ) Then
		Test_Score( Grade_Number ) = X
		Call Update_Record
		Call ReRead_Record ( Key_Value, Key_Number )
	    End If
c
	    End Do
c
	End Do
c
	Return
c
 10	Format ( I2 )
 20	Format ( F10.2 )
 30	Format ( F10.0 )
c
	End



	Subroutine Modify_Student_Number ( Key_Value, Key_Number )	
c
	Include		'Student.Rec'
c
	Character	Key_Value*(*)
	Character*20	New_Number
	Character*1	So / 14 /,	Si / 15 /
c
	Integer		Key_Number
c
	Call Lib$Erase_Page ( 6, 1 )
	Call Lib$Put_Screen ( So // 'm' // Si,	 5,	21, 1 )
	Call Lib$Put_Screen ( So // 'j' // Si,	 5,	60, 1 )
c
	Length = 1
c
	Do While ( Length .gt. 0 )
	    Call Display_Current_Record ( 10, 1 )
	    Call Lib$Put_Screen ( 'Student Number',
	1					12,	33, 1 )
	    Call Lib$Put_Screen ( So // 'oooooooooooooooooooo' // Si,
	1					15,	30, 1 )
	    Call Lib$Put_Screen ( Student_Number,
	1					16,	30, 2 )
c
	    Call Lib$Set_Cursor ( 14, 30 )
	    Call Lib$Erase_Line ( 14, 30 )
	    Call Lib$Get_Screen ( New_Number, , Length )
c
	    If ( Length .gt. 0 ) Then
		Call Str$UpCase ( Student_Number, New_Number )
		Call Update_Record
		Call ReRead_Record ( Key_Value, Key_Number )
	    End If
	End Do
c
	Return
	End



	Subroutine Modify_Letter_Grade ( Key_Value, Key_Number )	
c
	Include		'Student.Rec'
c
	Character	Key_Value*(*)
	Character*10	Grade_Average
	Character*1	So / 14 /,	Si / 15 /,	New_Letter
c
	Integer		Key_Number
c
	Call Lib$Erase_Page ( 6, 1 )
	Call Lib$Put_Screen ( So // 'm' // Si,	 5,	21, 1 )
	Call Lib$Put_Screen ( So // 'j' // Si,	 5,	60, 1 )
c
	Length = 1
c
	Do While ( Length .gt. 0 )
	    Call Display_Current_Record ( 10, 1 )
c
	    Write ( Grade_Average, 10 ) Average_Grade
	    Call Lib$Put_Screen ( 'Average Score',
	1					12,	14, 1 )
	    Call Lib$Put_Screen ( 'Letter Grade',
	1					12,	34, 1 )
	    Call Lib$Put_Screen ( Grade_Average,
	1					14,	16, 1 )
	    Call Lib$Put_Screen ( So // 'o' // Si,
	1					15,	40, 1 )
	    Call Lib$Put_Screen ( Letter_Grade,	16,	40, 2 )
c
	    New_Letter = '?'
c
	    Do While (( ( New_Letter .lt. 'A' ) .or.
	1		( New_Letter .gt. 'F' ) ) .and.
	1		( Length .gt. 0 ) )
		Call Lib$Set_Cursor ( 14, 40 )
		Call Lib$Erase_Line ( 14, 40 )
		Call Lib$Get_Screen ( New_letter, , Length )
		Call Str$UpCase ( New_letter, New_Letter )
	    End Do
c
	    If ( Length .gt. 0 ) Then
		Letter_Grade = New_Letter
		Call Update_Record
		Call ReRead_Record ( Key_Value, Key_Number )
	    End If
	End Do
c
	Return
c
 10	Format ( F10.2 )
c
	End



	Subroutine Modify_Student_Comment ( Key_Value, Key_Number )	
c
	Include		'Student.Rec'
c
	Character	Key_Value*(*)
	Character*20	New_Comment
	Character*1	So / 14 /,	Si / 15 /
c
	Integer		Key_Number
c
	Call Lib$Erase_Page ( 6, 1 )
	Call Lib$Put_Screen ( So // 'm' // Si,	 5,	21, 1 )
	Call Lib$Put_Screen ( So // 'j' // Si,	 5,	60, 1 )
c
	Length = 1
c
	Do While ( Length .gt. 0 )
	    Call Display_Current_Record ( 10, 1 )
	    Call Lib$Put_Screen ( 'Student  Comment',
	1					12,	32, 1 )
	    Call Lib$Put_Screen ( So // 'oooooooooooooooooooo' // Si,
	1					15,	30, 1 )
	    Call Lib$Put_Screen ( Comment,	16,	30, 2 )
c
	    Call Lib$Set_Cursor ( 14, 30 )
	    Call Lib$Erase_Line ( 14, 30 )
	    Call Lib$Get_Screen ( New_Comment, , Length )
c
	    If ( Length .gt. 0 ) Then
		Call Str$UpCase ( Comment, New_Comment )
		Call Update_Record
		Call ReRead_Record ( Key_Value, Key_Number )
	    End If
	End Do
c
	Return
	End



	Subroutine Modify_Department_Name ( Key_Value, Key_Number )
c
	Include		'Student.Rec'
c
	Character	Key_Value*(*)
	Character*20	New_Department
	Character*1	So / 14 /,	Si / 15 /
c
	Integer		Key_Number
c
	Call Lib$Erase_Page ( 6, 1 )
	Call Lib$Put_Screen ( So // 'm' // Si,	 5,	21, 1 )
	Call Lib$Put_Screen ( So // 'j' // Si,	 5,	60, 1 )
c
	Length = 1
c
	Do While ( Length .gt. 0 )
	    Call Display_Current_Record ( 10, 1 )
	    Call Lib$Put_Screen ( 'Department  Name',
	1					12,	32, 1 )
	    Call Lib$Put_Screen ( So // 'oooooooooooooooooooo' // Si,
	1					15,	30, 1 )
	    Call Lib$Put_Screen ( Department_Name,
	1					16,	30, 2 )
c
	    Call Lib$Erase_Line ( 14, 30 )
	    Call Lib$Set_Cursor ( 14, 30 )
	    Call Lib$Get_Screen ( New_Department, , Length )
c
	    If ( Length .gt. 0 ) Then
		Call Str$UpCase ( Department_Name, New_Department )
		Call Update_Record
		Call ReRead_Record ( Key_Value, Key_Number )
	    End If
	End Do
c
	Return
	End



	Subroutine Display_Current_Record ( Line, Column )
c
	Include		'Student.Rec'
c
	Integer		Line,	Column
c
	I = Index ( Last_Name, '  ' ) - 1
	If ( I .le. 0 ) I = 20
	J = Index ( First_Name, '  ' ) - 1
	If ( J .le. 0 ) J = 20
	K = Index ( Student_Number, '  ' ) - 1
	If ( K .le. 0 ) K = 20
	L = Index ( Department_Name, '  ' ) - 1
	If ( L .le. 0 ) L = 20
c
	Call Lib$Erase_Line (	Line,	Column )
	Call Lib$Put_Screen (	' Using ' //
	1			First_Name( : J )	//	' '	//
	1			Last_Name( : I )	//	' / '	//
	1			Student_Number( : K )	//	' / '	//
	1			Department_Name( : L )	//	' ... ',
	1					Line,	Column,	2 )
c
	Return
	End
	


	Subroutine ReRead_Record ( Key_Value, Key_Number )
c
	Include		'Student.Rec'
c
	Character	Key_Value*(*)
c
	Integer		Key_Number
c
	Read (	Data_File_Lun,
	1	Key	= Key_Value,
	1	KeyId	= Key_Number,
	1	IoStat	= Ios,
	1	Err	= 200 ) Student_Record
c
200	Return
	End



	Subroutine Add_Grades
c
	Integer		Grade_Number,	Get_Integer
c
	Character*2	Number
	Character*1	Null / 0 /
c
	Call Draw_Menu_Header ( 'Add Grades', 3 )
c
	Call Lib$Erase_Line ( 10, 1 )
c
	Do While ( Get_Integer ( Grade_Number, 10, 1, 1, 20,
	1	'Enter the number of the grade to be added' ) )
c
	    Write ( Number, 10 ) Grade_Number
	    If ( Number( 1: 1 ) .eq. ' ' ) Number ( 1: 1 ) = Null
	    Call Lib$Erase_Line ( 15, 1 )
	    Call Lib$Put_Screen (	'Score for grade ' // Number,
	1				15,	17,	1 )
	    Call Lib$Put_Screen (	'Comment for grade ' // Number,
	1				15,	41,	1 )
	    Call Add_Scores ( Grade_Number )
c
	End Do
	Return
c
 10	Format ( I2 )
c
	End



	Subroutine Add_Scores ( Grade_Number )
c
	Include		'Student.Rec'
c
	Integer		Grade_Number,		Score_Ios
	Integer		Score_Length,		Comment_Length
c
	Character*20	Default_Comment,	Input_Comment
	Character*10	Default_Score,		Input_Score
	Character*1	Null_Plus_1 / 1 /,		Opt
c
	Call Display_Add_Grades_Screen
c
	Default_Score	= '      0.00'
	Default_Comment	= '                    '
c
	Read (	Data_File_Lun,
	1	KeyGt	= Null_Plus_1,
	1	KeyId	= 0,
	1	IoStat	= Ios,
	1	Err	= 200 ) Student_Record
c
 	Do While ( .True. )
c
	    Call Display_Add_Score_Defaults ( Default_Score, Default_Comment )
c
	    Score_Ios = -1
c
	    Do While ( Score_Ios .ne. 0 )
c
		Call Lib$Set_Cursor (	17,	21 )
		Call Lib$Get_Screen ( Input_Score, , Score_Length )
c
		If ( Score_Length .le. 0 ) Then
		    Input_Score		= Default_Score
		    Score_Length	= 10
		End If
c
		Read (	Input_Score( : Score_Length ), 10,
	1		IOStat = Score_Ios ) X
c
	    End Do
c
	    Write ( Input_Score, 20 ) X
	    Default_Score = Input_Score
	    Call Lib$Put_Screen ( Input_Score,	17,	21, 1 )
	    Test_Score( Grade_Number ) = X
c
	    Call Lib$Set_Cursor ( 17, 41 )
	    Call Lib$Get_Screen ( Input_Comment, , Comment_Length )
c
	    If ( Comment_Length .le. 0 ) Then
		Input_Comment = Default_Comment
	    Else
		Call Str$Upcase ( Input_Comment, Input_Comment )
		Default_Comment = Input_Comment
	    End If
c
	    Call Lib$Put_Screen ( Input_Comment,	17,	41, 1 )
	    Test_Comments( Grade_Number ) = Input_Comment
c
	    Call Update_Record
c
	    Read (	Data_File_Lun,
	1		IoStat	= Ios,
	1		Err	= 200 ) Student_Record
c
	End Do
c
200	Continue
	Return
c
 10	Format ( F10.0 )
 20	Format ( F10.2 )
c
	End



	Subroutine Update_Record
c
	Include		'Student.Rec'
c
	I = Index ( Last_Name, '  ' ) - 1
	If ( I .le. 0 ) I = 20
	J = Index ( First_Name, '  ' ) - 1
	If ( J .le. 0 ) J = 20
	K = Index ( Student_Number, '  ' ) - 1
	If ( K .le. 0 ) K = 20
	L = Index ( Department_Name, '  ' ) - 1
	If ( L .le. 0 ) L = 20
c
	Call Lib$Erase_Line (	23,	1 )
	Call Lib$Put_Screen (	' Updating ' //
	1			First_Name( : J )	//	' '	//
	1			Last_Name( : I )	//	' / '	//
	1			Student_Number( : K )	//	' / '	//
	1			Department_Name( : L )	//	' ... ',
	1					23,	 1,	2 )
c
	ReWrite ( Data_File_Lun ) Student_Record
c
200	Return
c
	End



	Integer Function Get_Integer ( Number, Row, Column, Min, Max,
	1				    Prompt )
c
	Integer		Number,		Ios,	Length
	Integer		Column,		Row,	Min,	Max
c
	Character	Prompt*(*)
	Character*10	Value
	Character*2	Maximum,	Minimum
	Character*1	Null / 0 /
c
	Ios = 1
	Length = 1
c
	Write ( Maximum, 20 ) Max
	Write ( Minimum, 20 ) Min
	If ( Maximum( 1: 1 ) .eq. ' ' ) Maximum( 1: 1 ) = Null
	If ( Minimum( 1: 1 ) .eq. ' ' ) Minimum( 1: 1 ) = Null
c
	Do While ( ( Ios .ne. 0 ) .and. ( Length .gt. 0 ) )
c
	    Call Lib$Put_Screen ( Prompt // ' [R:' // Minimum // '-' //
	1			  Maximum // ']: ',   Row,	Column, 1 )
	    Call Lib$Erase_Line
	    Call Lib$Get_Screen ( Value, , Length )
c
	    If ( Length .gt. 0 ) Then
		Read ( Value( : Length ), 10, IOStat = Ios ) X
		If (	( X .lt. Float( Min ) ) .or.
	1		( X .gt. Float( Max ) ) ) Ios = -1
	    End If
c
	End Do
c
	If ( ( Length .le. 0 ) .or.
	1    ( X .lt. Float( Min ) ) .or.
	1    ( X .gt. Float( Max ) ) ) Then
	    Get_Integer = .False.
	Else
	    Get_Integer = .True.
	    Number = X
	End If
c
	Return
10	Format ( F10.0 )
20	Format ( I2 )
	End



	Subroutine Select_Student_Menu (	Menu_Name,
	1					Prompt,
	1					Screen_Name,
	1					Action_Routine )
c
	Character	Menu_Name*(*),	Screen_Name*(*),	Prompt*(*)
c
	Character*1	Option
c
	Logical*1	Done
c
	Integer		Key
c
	External	Action_Routine
c
	Done = .False.
c
	Do While ( .Not. Done )
c
	    Call Draw_Select_Menu ( Menu_Name )
c
	    Length = 1
	    Option = '?'
c
	    Call Select_Option ( 'DNS', Option, Length, 19, 33, 1 )
c
	    If ( Length .le. 0 ) then
		Done = .True.
	    Else
		Call Draw_Menu_Header ( Screen_Name, 3 )
		If ( Option .eq. 'N' ) Then
		    Call Select_By_Key ( 0, 'LAST name',
	1				  Prompt, Action_Routine )
		Else If ( Option .eq. 'S' ) Then
		    Call Select_By_Key ( 1, 'NUMBER',
	1				  Prompt, Action_Routine )
		Else If ( Option .eq. 'D' ) Then
		    Call Select_By_Key ( 2, 'DEPARTMENT name',
	1				  Prompt, Action_Routine )
		End If
	    End If
c
	End Do
c
	Return
	End



	Subroutine Select_By_Key (	Key_Value,
	1				Prompt_1,
	1				Prompt_2,
	1				Action_Routine	)
c
	Character*20	String
c
	Character	Prompt_1*(*),	Prompt_2*(*)
c
	Integer		Key_Value
c
	External	Action_Routine
c
	Length = 1
c
	Do While ( Length .gt. 0 )
c
	    Call Lib$Put_Screen (
	1	'Enter the ' // Prompt_1 //
	1	' of the student to be ' // Prompt_2 // ': ', 9, 1, 1 )
c
	    Call Lib$Get_Screen ( String, , Length )
c
	    If ( Length .gt. 0 ) Then
		Call Lib$Erase_Page ( 8, 1 )
		Call Str$UpCase ( String, String )
		Call Read_Students ( 	String( : Length ), Key_Value,
	1				Action_Routine )
	    End If
c
	End Do
c
	Return
	End



	Subroutine Delete_Student ( Key_Value, Key_Number )
c
	Include		'Student.Rec'
c
	Character	Key_Value*(*)
	Character*1	Option
c
	Integer		Ios,	Key_Number
c
	I = Index ( Last_Name, '  ' ) - 1
	If ( I .le. 0 ) I = 20
	J = Index ( First_Name, '  ' ) - 1
	If ( J .le. 0 ) J = 20
	K = Index ( Student_Number, '  ' ) - 1
	If ( K .le. 0 ) K = 20
c
	Call Lib$Erase_Page ( 14, 1 )
	Call Lib$Put_Screen ( 'Are you sure you want to delete ', 15, 1, 1 )
	Call Lib$Put_Screen ( 	First_Name( : J )	//	' '	//
	1			Last_Name( : I )	//	' / '	//
	1			Student_Number( : K ),		  15, 33, 2 )
	Call Lib$Put_Screen ( '? ', 15, 38 + I + J + K, 1 )
	Call Lib$Get_Screen ( Option, , Len )
c
	If ( Len .gt. 0 ) Then
	    Call Str$UpCase( Option, Option )
	    If ( ( Option .eq. 'Y' ) .or. ( Option .eq. 'T' ) ) Then
		Delete ( Data_File_Lun, Err = 200 )
		Call Lib$Put_Screen(
	1			First_Name( : J )	//	' '	//
	1			Last_Name( : I )	//	' / '	//
	1			Student_Number( : K )	//
	1			' has been deleted.', 18, 1, 1 )
	    End If
	End If
c
	Call Lib$Erase_Line ( 15, 1 )
	Return
c
200	Continue
	Call Lib$Put_Screen( 'Error', 18, 1, 2 )
	Return
	End



	Subroutine Read_Students( Key_Value, Key_Number, Action_Routine )
c
	Character	Key_Value*(*)
	Character*40	Key
	Character*1	Cont
c
	Integer		Student_Count,	Key_Number,	Done
c
c   *** Student Record Common Block Definitions
c
	Parameter	Data_File_Lun	= 1
c
	Character*20	Student_Key( 0: 3 )
c
	Logical*1	Student_Record( 620 )
c
	Common / Record /	Student_Record
c
	Equivalence(	Student_Record,		Student_Key	)
c
c   *** End Of Student Record Definitions
c
	External Action_Routine
c
	Length = Len ( Key_Value )
c
	Cont = '?'
c
	If ( Key_Number .gt. 0 ) Then
	    Key_Pointer = Key_Number + 1
	Else
	    Key_Pointer = Key_Number
	End If
c
	Read (	Data_File_Lun,
	1	Key	= Key_Value,
	1	KeyId	= Key_Number,
	1	IoStat	= Ios,
	1	Err	= 200 ) Student_Record
c
	Done = .False.
c
	Do While (	( Key_Value( : Length ) .eq.
	1		Student_Key( Key_Pointer )( : Length ) )
	1	 	.and. ( .not. Done )	)
c
	    Call Lib$Erase_Line ( 11, 1 )
	    Call Lib$Erase_Line ( 13, 1 )
c
	    I = Index ( Student_Key( 1 ), '  ' ) - 1
	    If ( I .le. 0 ) I = 20
	    J = Index ( Student_Key( 0 ), '  ' ) - 1
	    If ( J .le. 0 ) J = 20
	    K = Index ( Student_Key( 2 ), '  ' ) - 1
	    If ( K .le. 0 ) K = 20
	    L = Index ( Student_Key( 3 ), '  ' ) - 1
	    If ( L .le. 0 ) L = 20
c
	    Call Lib$Put_Screen (	' ' //
	1			Student_Key( 1 )( : I )	// 	' '	//
	1			Student_Key( 0 )( : J )	//	' / '	//
	1			Student_Key( 2 )( : K )	// 	' / '	//
	1			Student_Key( 3 )( : L )	//	' ',
	1			11, 1, 2 )
c
	    Call Lib$Set_Cursor ( 13, 1 )
	    Call Lib$Get_Screen ( Cont,
	1			  'Select this student [y/n/q]? ', I_Size )
c
	    If	( I_Size .gt. 0 ) Then
c
		Call Str$UpCase ( Cont, Cont )
		If ( ( Cont .eq. 'Y' ) .or. ( Cont .eq. 'T' ) ) Then
		    If ( Key_Number .eq. 0 ) Then
			Key = Student_Key( 0 ) // Student_Key( 1 )
			I_Length = 40
		    Else
			Key = Student_Key( Key_Pointer )
			I_Length = 20
		    End If
		    Call Action_Routine ( Key( : I_Length ), Key_Number )
		Else If ( Cont .eq. 'Q' ) Then
		    Done = .True.
		End If
c
	    End If
c
	    If ( .not. Done ) Then
		Read (	Data_File_Lun,
	1		IoStat	= Ios,
	1		Err	= 200 ) Student_Record
	    End If
c
	End Do
c
	Return
c
200	Continue
c
	If ( Cont .eq. '?' ) Then
	    Call Lib$Put_Screen ( '%GRADE-I-NOTFOUND, "' // Key_Value //
	1			  '" not found.', 11, 1, 2 )
	End If
c
	Return
	End



	Subroutine Add_Student
c
	Character*1	Option
c
	Integer		Add_A_Record
	Logical*1	Done,	First_Pass
c
	First_Pass = .True.
	Done = .False.
	Call Draw_Add_Screen
c
	Do While ( .Not. Done )
c
	    Length = 1
	    Option = '?'
c
	    Call Select_Option ( 'CD', Option, Length, 3, 57, 1 )
c
	    Call Lib$Erase_Page ( 20, 1 )
c
	    If ( Option .eq. 'C' ) Then
		First_Pass = .True.
		Call Display_Add_Defaults
	    Else If ( Option .eq. 'D' ) Then
		If ( First_Pass ) Then
		    Done = .True.
		Else
		    Istat = Add_A_Record( )
		    If ( Istat ) Then
			Done = .True.
		    Else
			First_Pass = .True.
		    End If
		End If
	    Else
		If ( First_Pass ) Then
		    First_Pass = .False.
		    Call Get_Student_Info
		Else
		    Istat = Add_A_Record( )
		    If ( Istat ) Then
			Call Get_Student_Info
		    Else
			First_Pass = .True.
		    End If
		End If
	    End If
c
	End Do
c
	Return
	End



	Integer Function Add_A_Record( )
c
	Include 'Student.Rec'
c
	I = Index ( Last_Name, '  ' ) - 1
	If ( I .le. 0 ) I = 20
	J = Index ( First_Name, '  ' ) - 1
	If ( J .le. 0 ) J = 20
	K = Index ( Student_Number, '  ' ) - 1
	If ( K .le. 0 ) K = 20
	L = Index ( Department_Name, '  ' ) - 1
	If ( L .le. 0 ) L = 20
c
	Call Lib$Put_Screen (	' Adding record ' //
	1			First_Name( : J )	//	' '	//
	1			Last_Name( : I )	//	' / '	//
	1			Student_Number( : K )	//	' / '	//
	1			Department_Name( : L )	//	' ',
	1					20,	 1,	2 )
c
	Do I = 101, 500
	    Student_Record( I ) = 32
	End Do
c
	Do I = 501, 620
	    Student_Record( I ) = 0
	End Do
c
	Write (	Data_File_Lun,
	1	Err	= 200,
	1	Iostat	= istat )	Student_Record
c
	Add_A_Record = .True.
c
	Return
c
200	Continue
c
	Add_A_Record = .False.
	Call Lib$Put_Screen ( '%GRADE-E-', 21, 1, 1 )
	If ( Istat .eq. 50 ) then
		Call Lib$Put_Screen (	'INCKEYCHG, attempt to ' //
	1				'duplicate a record, record ' //
	1				'not added',  21, 10, 1 )
	Else
		Call Lib$Put_Screen (	'UNKOWN, unexpected error during ' //
	1				'write, record not added', 21, 10, 1 )
		I = Mrk$_ErrRec ( '-GRADE-', Istat, ' ' )
	End If
	Return
	End



	Subroutine Get_Student_Info 
c
	Include 'Student.Rec'
c
	Character*20	Input_Line
c
	Call Display_Add_Defaults
c
	Call Lib$Set_Cursor (	 9,	 1 )
	Call Lib$Get_Screen ( Input_Line, , Length )
	If ( Length .gt. 0 ) Call Str$UpCase ( Last_Name , Input_Line )
	Call Lib$Erase_Line (	 9,	 1 )	
	Call Lib$Put_Screen ( Last_Name,	 9,	 1, 1 )
c
	Call Lib$Set_Cursor (	 9,	31 )
	Call Lib$Get_Screen ( Input_Line, , Length )
	If ( Length .gt. 0 ) Call Str$UpCase ( First_Name, Input_Line )
	Call Lib$Erase_Line (	 9,	31 )	
	Call Lib$Put_Screen ( First_Name,	 9,	31, 1 )
c
	Call Lib$Set_Cursor (	 9,	61 )
	Call Lib$Get_Screen ( Input_Line, , Length )
	If ( Length .gt. 0 ) Call Str$UpCase ( Student_Number, Input_Line )
	Call Lib$Erase_Line (	 9,	61 )	
	Call Lib$Put_Screen ( Student_Number,	 9,	61, 1 )
c
	Call Lib$Set_Cursor (	16,	 1 )
	Call Lib$Get_Screen ( Input_Line, , Length )
	If ( Length .gt. 0 ) Call Str$UpCase ( Department_Name, Input_Line )
	Call Lib$Erase_Line (	16,	 1 )	
	Call Lib$Put_Screen ( Department_Name,	16,	 1, 1 )
c
	Call Lib$Set_Cursor (	16,	31 )
	Call Lib$Get_Screen ( Input_Line, , Length )
	If ( Length .gt. 0 ) Call Str$UpCase ( Comment, Input_Line )
	Call Lib$Erase_Line (	16,	31 )	
	Call Lib$Put_Screen ( Comment,		16,	31, 1 )
c
	Return
	End



	Subroutine Display_Add_Score_Defaults( Default_1, Default_2 )
c
	Include		'Student.Rec'
c
	Character	Default_1*(*),	Default_2*(*)
c
	Call Lib$Erase_Line ( 13, 1 )
	Call Lib$Erase_Line ( 17, 1 )
	Call Lib$Erase_Line ( 19, 1 )
c
	I = Index ( Last_Name, '  ' ) - 1
	If ( I .le. 0 ) I = 20
	J = Index ( First_Name, '  ' ) - 1
	If ( J .le. 0 ) J = 20
	K = Index ( Student_Number, '  ' ) - 1
	If ( K .le. 0 ) K = 20
	L = Index ( Department_Name, '  ' ) - 1
	If ( L .le. 0 ) L = 20
c
	Call Lib$Put_Screen (	' ' //
	1			First_Name( : J )	//	' '	//
	1			Last_Name( : I )	//	' / '	//
	1			Student_Number( : K )	//	' / '	//
	1			Department_Name( : L )	//	' ',
	1					13,	 1,	2 )
	Call Lib$Put_Screen (	Default_1,	20,	21,	2 )
	Call Lib$Put_Screen (	Default_2,	20,	41,	2 )
c
	Return
	End



	Subroutine Display_Add_Defaults
c
	Include 'Student.Rec'
c
	Call Lib$Erase_Line (  9, 1 )
	Call Lib$Erase_Line ( 11, 1 )
	Call Lib$Put_Screen ( Last_Name,	11,	 1, 2 )
	Call Lib$Put_Screen ( First_Name,	11,	31, 2 )
	Call Lib$Put_Screen ( Student_Number,	11,	61, 2 )
c
	Call Lib$Erase_Line ( 16, 1 )
	Call Lib$Erase_Line ( 18, 1 )
	Call Lib$Put_Screen ( Department_Name,	18,	 1, 2 )
	Call Lib$Put_Screen ( Comment,		18,	31, 2 )
c
	Return
	End



	Subroutine Display_Add_Grades_Screen
c
	Character*1	So / 14 /,	Si / 15 /
c
	Call Lib$Erase_Page ( 16, 1 )
	Call Lib$Put_Screen ( So // 'oooooooooo' // Si,	18,	21, 1 )
	Call Lib$Put_Screen ( So // 'oooooooooooooooooooo' // Si,
	1						18,	41, 1 )
c
	Return
	End


	Subroutine Draw_Menu_Header ( Screen_Name, Row )
c
	Character*(*)	Screen_Name
	Character*1	So / 14 /,	Si / 15 /
c
	Integer		Row
c
	I = Len ( Screen_Name )
c
	Call Lib$Erase_Page ( 1, 1 )
	Call Lib$Put_Screen ( So //
	1	'lqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqk' // Si,
	1					Row,	21, 1 )
c
	Do K = ( Row + 1 ), ( Row + 3 )
	    Call Lib$Put_Screen ( So // 'x' // Si,	 K,	21, 1 )
	    If ( K .eq. ( Row + 2 ) ) Then
		Call Lib$Put_Screen ( Screen_Name,	 K,
	1				( ( 82 - I ) / 2 ), 1 )
	    End If
	    Call Lib$Put_Screen ( So // 'x' // Si,	 K,	60, 1 )
	End Do
c
	Call Lib$Put_Screen ( So //
	1	'mqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqj' // Si,
	1					   Row + 4,	21, 1 )
c
	Return
	End



	Subroutine Draw_Menu_Body ( Start, End )
c
	Integer		Start,		End
c
	Character*1	So / 14 /,	Si / 15 /
c
	Call Lib$Erase_Page (  Start, 1 )
c
	Call Lib$Put_Screen ( So // 't' // Si,	 Start - 1,	21, 1 )
	Call Lib$Put_Screen ( So // 'u' // Si,	 Start - 1,	60, 1 )
c
	Do I = Start, ( End - 1 )
	    Call Lib$Put_Screen ( So // 'x' // Si,	 I,	21, 1 )
	    Call Lib$Put_Screen ( So // 'x' // Si,	 I,	60, 1 )
	End Do
c
	Call Lib$Put_Screen ( So //
	1	'mqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqj' // Si,
	1						End,	21, 1 )
c	
	Return
	End



	Subroutine Draw_Menu_Trailer ( Begin, End )
c
	Integer		Begin,		End
c
	Character*1	So / 14 /,	Si / 15 /
c
	Call Lib$Erase_Page ( Begin )
c
	Call Lib$Put_Screen ( So // 't' // Si,	Begin - 1,	21, 1 )
	Call Lib$Put_Screen ( So // 'u' // Si,	Begin - 1,	60, 1 )
c
	Do I = Begin, End - 1
	    Call Lib$Put_Screen ( So // 'x' // Si,	I,	21, 1 )
	    Call Lib$Put_Screen ( So // 'x' // Si,	I,	60, 1 )
	End Do
c
	Call Lib$Put_Screen ( So //
	1	'mqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqj' // Si,
	1					End,	21, 1 )
c
	Return
	End



	Subroutine Draw_Display_Screen
c
	Call Draw_Menu_Body ( 6, 19 )
	Call Draw_Menu_Trailer ( 20, 23 )
c
	Call Lib$Put_Screen ( 'B = Brief Score Listing', 7,	31, 0 )
	Call Lib$Put_Screen ( 'F = Full Score Listing',	 9,	31, 0 )
	Call Lib$Put_Screen ( 'M = Manager Listing',	11,	31, 0 )
	Call Lib$Put_Screen ( 'O = One Student Listing',13,	31, 0 )
	Call Lib$Put_Screen ( 'R = Student Roster',	15,	31, 0 )
	Call Lib$Put_Screen ( 'S = Score Sheet',	17,	31, 0 )
c
	Return
	End



	Subroutine Draw_Modify_Screen
c
	Call Draw_Menu_Body ( 6, 19 )
	Call Draw_Menu_Trailer ( 20, 23 )
c
	Call Lib$Put_Screen ( 'C = Student Comment',	 7,	31, 0 )
	Call Lib$Put_Screen ( 'D = Department Name',	 9,	31, 0 )
	Call Lib$Put_Screen ( 'L = Letter Grade',	11,	31, 0 )
	Call Lib$Put_Screen ( 'N = Student Number',	13,	31, 0 )
	Call Lib$Put_Screen ( 'S = Test Scores',	15,	31, 0 )
	Call Lib$Put_Screen ( 'T = Test Comments',	17,	31, 0 )
c
	Return
	End



	Subroutine Draw_Modify_Menu
c
	Call Draw_Menu_Header ( 'Modify  Menu',	 5 )
	Call Draw_Menu_Body ( 10, 15 )
	Call Draw_Menu_Trailer ( 16, 19 )
c
	Call Lib$Put_Screen ( 'A = Add Grades',		11,	33, 0 )
	Call Lib$Put_Screen ( 'C = Change A Record',	13,	33, 0 )
c
	Return
	End



	Subroutine Select_Sort_Menu
c
	Call Draw_Menu_Body ( 6, 15 )
	Call Draw_Menu_Trailer ( 16, 19 )
c
	Call Lib$Put_Screen ( 'Sort by',	 7,	35, 1 )
	Call Lib$Put_Screen ( 'D = Department',	 9,	33, 0 )
	Call Lib$Put_Screen ( 'N = Name',	11,	33, 0 )
	Call Lib$Put_Screen ( 'S = Number',	13,	33, 0 )
c
	Return
	End



	Subroutine Draw_Select_Menu ( Menu_Name )
c
	Character	Menu_Name*(*)
c
	I = Len ( Menu_Name )
c
	Call Draw_Menu_Header ( Menu_Name, 3 )
	Call Draw_Menu_Body ( 8, 17 )
	Call Draw_Menu_Trailer ( 18, 21 )
c
	Call Lib$Put_Screen ( 'Select  by',	 9,	35, 1 )
	Call Lib$Put_Screen ( 'D = Department',	11,	33, 0 )
	Call Lib$Put_Screen ( 'N = Name',	13,	33, 0 )
	Call Lib$Put_Screen ( 'S = Number',	15,	33, 0 )
c
	Return
	End



	Subroutine Draw_Add_Screen
c
	Character*1	So / 14 /,	Si / 15 /
c
	Call Lib$Erase_Page ( 1, 1 )	
	Call Lib$Put_Screen ( So // 'lqqqqqqqqqqqqqqqqqqqqqqw' // Si,
	1					 1,	 5, 1 )
	Call Lib$Put_Screen ( So // 'x' // Si,	 2,	 5, 1 )
	Call Lib$Put_Screen ( So // 'x' // Si,	 2,	28, 1 )
	Call Lib$Put_Screen ( So // 'x' // Si,	 3,	 5, 1 )
	Call Lib$Put_Screen ( 'Add Students',	 3,	10, 1 )
	Call Lib$Put_Screen ( So // 'x' // Si,	 3,	28, 1 )
	Call Lib$Put_Screen ( So // 'x' // Si,	 4,	 5, 1 )
	Call Lib$Put_Screen ( So // 'x' // Si,	 4,	28, 1 )
	Call Lib$Put_Screen ( So // 'mqqqqqqqqqqqqqqqqqqqqqqv' // Si,
	1					 5,	 5, 1 )
	Call Lib$Put_Screen ( So // 'qqqqqqqqqqqqqqqqqqqqqqqw' // Si,
	1					 1,	29, 1 )
	Call Lib$Put_Screen ( So // 'x' // Si,	 2,	52, 1 )
	Call Lib$Put_Screen ( 'C = Cancel   D = Done',
	1					 3,	30, 0 )
	Call Lib$Put_Screen ( So // 'x' // Si,	 3,	52, 1 )
	Call Lib$Put_Screen ( So // 'x' // Si,	 4,	52, 1 )
	Call Lib$Put_Screen ( So // 'qqqqqqqqqqqqqqqqqqqqqqqv' // Si,
	1					 5,	29, 1 )
	Call Lib$Put_Screen ( So // 'qqqqqqqqqqqqqqqqqqqqqqqk' // Si,
	1					 1,	53, 1 )
	Call Lib$Put_Screen ( So // 'x' // Si,	 2,	76, 1 )
	Call Lib$Put_Screen ( So // 'x' // Si,	 3,	76, 1 )
	Call Lib$Put_Screen ( So // 'x' // Si,	 4,	76, 1 )
	Call Lib$Put_Screen ( So // 'qqqqqqqqqqqqqqqqqqqqqqqj' // Si,
	1					 5,	53, 1 )
c
	Call Lib$Put_Screen ( 'Last  Name',	 7,	 6, 1 )
	Call Lib$Put_Screen ( So // 'oooooooooooooooooooo' // Si,
	1					10,	 1, 1 )
	Call Lib$Put_Screen ( 'First Name',	 7,	36, 1 )
	Call Lib$Put_Screen ( So // 'oooooooooooooooooooo' // Si,
	1					10,	31, 1 )
	Call Lib$Put_Screen ( 'Student Number',	 7,	64, 1 )
	Call Lib$Put_Screen ( So // 'oooooooooooooooooooo' // Si,
	1					10,	61, 1 )
	Call Lib$Put_Screen ( 'Department',	14,	 6, 1 )
	Call Lib$Put_Screen ( So // 'oooooooooooooooooooo' // Si,
	1					17,	 1, 1 )
	Call Lib$Put_Screen ( 'Comment',	14,	37, 1 )
	Call Lib$Put_Screen ( So // 'oooooooooooooooooooo' // Si,
	1					17,	31, 1 )
c
	Return
	End
	

	Subroutine Draw_Manager_Menu
c
	Call Draw_Menu_Header ( 'Managment Menu', 3 )
	Call Draw_Menu_Body ( 8, 19 )
	Call Draw_Menu_Trailer ( 20, 23 )
c
	Call Lib$Put_Screen ( 'A = Add Test Weights',		 9,	30, 0 )
	Call Lib$Put_Screen ( 'B = Build a Flat File',		11,	30, 0 )
	Call Lib$Put_Screen ( 'C = Change Test Weights',	13,	30, 0 )
	Call Lib$Put_Screen ( 'L = Load From a Flat File',	15,	30, 0 )
	Call Lib$Put_Screen ( 'N = Change Number of Tests',	17,	30, 0 )
c
	Return
	End



	Subroutine Draw_Update_Menu
c
	Call Draw_Menu_Header ( 'Update  Menu', 3 )
	Call Draw_Menu_Body ( 8, 17 )
	Call Draw_Menu_Trailer ( 18, 21 )
c
	Call Lib$Put_Screen ( 'A = Add',	 9,	36, 0 )
	Call Lib$Put_Screen ( 'D = Delete',	11,	36, 0 )
	Call Lib$Put_Screen ( 'M = Modify',	13,	36, 0 )
	Call Lib$Put_Screen ( 'R = Rename',	15,	36, 0 )
c
	Return
	End


	Subroutine Draw_Main_Menu
c
	Call Draw_Menu_Header ( 'Main  Menu', 4 )
	Call Draw_Menu_Body ( 9, 18 )
	Call Draw_Menu_Trailer ( 19, 22 )
c
	Call Lib$Put_Screen ( 'D = Display',	10,	34, 0 )
	Call Lib$Put_Screen ( 'C = Calculate',	12,	34, 0 )
	Call Lib$Put_Screen ( 'M = Management',	14,	34, 0 )
	Call Lib$Put_Screen ( 'U = Update',	16,	34, 0 )
c
	Return
	End



	Subroutine Select_Option (	Possible_Options,
	1				Option,
	1				Length,
	1				Row,
	1				Column,
	1				Flag			)
c
	Character	Possible_Options*(*),	Option*(*)
c
	Integer		Length,		Row,	Column,		Flag
c
	Do While (	( Index ( Possible_Options, Option ) .eq. 0 ) .and.
	1		( Length .gt. 0 ) )
c
	    Call Display_Prompt( Row, Column, Flag )
	    Call Get_Option( Option, Length )
c
	End Do
c
	Return
	End



	Subroutine Display_Prompt ( Line, Column, Flag )
c
	Integer		Line,	Column,		Flag
c
	Call Lib$Put_Screen ( '   ', Line, Column + 14, Flag )
	Call Lib$Put_Screen ( 'Enter option: ',	Line,	Column,	Flag )
c
	Return
	End



	Subroutine Get_Option ( Option, Length )
c
	Character	Option*(*)
c
	Call Lib$Get_Screen( Option, , Length )
	Call Str$UpCase ( Option, Option )
c
	Return
	End



	Integer Function Student_File_Open( Lun )
c
	Parameter	Maximum_Tests	= 20
	Parameter	Data_File_Lun	= 1
c
	Include		'Manager.Rec'
c
	Character*255	File_Name
	Character*1	Cr / 13 /,	Lf / 10 /,	Escape / 27 /
	Character*1	Null / 0 /
c
	Integer		Lun,	Name_Length,	Status
c
	Call Lib$Erase_Page ( 1, 1 )
	Call Lib$Put_Screen ( Escape // '(B' // Escape // ')0', 23, 1, 0 )
	Istat = Lib$Get_Screen (	File_Name, Cr // Lf //
	1				'Student data file name:	',
	1				Name_Length )
c
	If ( Istat ) then
c
	    Open (	Unit		= Lun,
	1		File		= File_Name,
	1		DefaultFile	= 'Class.Dat',
	1		Status		= 'Unknown',
	1		Organization	= 'Indexed',
	1		Access		= 'Keyed',
	1		Form		= 'Unformatted',
	1		RecL		= 155,
	1		Key		= (  1: 40: Character,
	1				    41: 60: Character,
	1				    61: 80: Character ),
	1		IoStat		= Status,
	1		Err		= 200 )
c
	    Student_File_Open = .True.
c
	    Read (	Lun,
	1		Key	= Null,
	1		KeyId	= 0,
	1		IoStat	= Ios,
	1		Err	= 300 ) Manager_Record
c
	Else
	    Student_File_Open = .False.
	End If
c
	Return
c
200	Continue
c
	    IStat = Mrk$_ErrRec( '%GRADE-F', Status, ' ' )
	    Student_File_Open = .False.
	    Return
c
300	Continue
c
	Call Lib$Erase_Page ( 1, 1 )
	Call Lib$Put_Screen ( 'GRADE', 8, 37, 9 )
	Call Lib$Put_Screen ( 'Version 1.4  --  07-JAN-1985', 10, 26, 9 )
	Call Lib$Put_Screen ( 'from', 12, 38, 9 )
	Call Lib$Put_Screen ( 'The University of Alabama at Birmingham',
	1			14, 20, 9 )
	Call Lib$Put_Screen ( ' Creating new file... ',	23,	29, 6 )
c
	Do I = 1, 368
	    Manager_Record( I ) = 0
	End Do
	Do I = 369, 528
	    Manager_Record( I ) = 32
	End Do
	Write ( Lun ) Manager_Record
	Return
c
	End

