C----------------------------------------------------------------------
C	SDTREE_SUBS  (Common subroutines for SDTree and DM_Tree
C----------------------------------------------------------------------
C------------------------------------------------------------------------
C	SET UP SMG Displays for SDTree PROGRAMS
C		Dale E. Coy         Sept/Oct, 1986
C		Los Alamos National Laboratory
C
C	Used by SDTree and DMTree
C------------------------------------------------------------------------
	Subroutine SDTree_Displays (PBID,KBID)

        Implicit Integer*4 (A - Z)
	Character*23 Date

	Include 'SD_SMG.Dat'
	Include 'SD_Common.Dat'

C--------------------------------------------------------------------
             
	Pasteboard_ID = PBID
	Keyboard_ID   = KBID
	Current_Display_Length = 22
	Last_Line = 0

	Call SMG$Create_Virtual_Display
	1		 (Current_Display_Length,20, Level_Display(1),
	2		SMG$M_Trunc_Icon)

        Have_Display(1) = .TRUE.
	
C		Make a place to put the names, without drawing lines.
        B_Width(1) = 14
	Call SMG$Create_Virtual_Display
	1	(Current_Display_Length,B_Width(1),
	2	Big_Display(1),SMG$M_BORDER,SMG$M_Bold)

	Have_Big_Display(1) = .TRUE.
	Call SMG$Put_Chars (Big_Display(1),'Top Level',2,7,,RU_Mask)

	If (SD_VT300) then
	    Call SMG$Create_Virtual_Display
     1		 (1,80, Top_Display,,BR_Mask)
	Else
	    Call SMG$Create_Virtual_Display
     1		 (1,80, Top_Display,,SMG$M_REVERSE)
	End If

	If (SD_VT300) then
	    Call SMG$Create_Virtual_Display
     1		 (2,80, Bottom_Display,,BR_Mask)
	Else
	    Call SMG$Create_Virtual_Display
     1		 (2,80, Bottom_Display,,SMG$M_REVERSE)
	End If

	If (SD_VT300) then
	    Call SMG$Create_Virtual_Display
     1		 (1,13, Normal_Display,,SMG$M_Reverse)
	Else
	    Call SMG$Create_Virtual_Display
     1		 (1,13, Normal_Display,,BR_Mask)
	End If
	

C	NOW SET UP THE INITIAL SCREEN
C----------------------------------------------------------------------

	Call SMG$Begin_Pasteboard_Update (Pasteboard_ID)

	Call SMG$Paste_Virtual_Display
     1		 (Level_Display(1),Pasteboard_ID,1,1)
  


	Call SMG$Put_Line(Top_Display,' Structure of '
	1		//Environment(:EnvLen))
                                                                       
	If (EnvLen .LT. 47) then
		Call Lib$Date_Time (Date)
		Call SMG$Put_Chars (Top_Display,
	1		Date(:17),1,63)
	End If

	Call SMG$Paste_Virtual_Display
     1		 (Top_Display,Pasteboard_ID,1,1)
  

	Call SMG$Paste_Virtual_Display
     1		 (Normal_Display,Pasteboard_ID,1,1)
  
	Call SMG$Put_Line(Normal_Display,'   Reading   ')
                                                                       

C		NOTE: BOTTOM DISPLAY NOT PASTED YET!!!!!!!!
	Call SMG$Put_Line(Bottom_Display,'  Press Arrow keys to '//
	1	'move.  Press Select or Return Key to choose Directory.')
        
	Call SMG$Put_Line(Bottom_Display,
	1'  Any other key will Quit.   '//
	2'        (Press PF2 for Other Commands and Help)')


	Call SMG$End_Pasteboard_Update (Pasteboard_ID)
	
	
9999	Return
        End

                                  
C------------------------------------------------------------------

	SUBROUTINE DIR1_READ (DIR_To_Read)

	IMPLICIT INTEGER (A-Z)

	CHARACTER*(*) DIR_To_Read

	Byte BSize

	Integer*2 Name_Size

	Logical Check_Name

	External Is_Dir

	Include 'SD_Common.Dat'
        Include 'SD_SMG.Dat'
	
C---------------------------------------------------------------------

	Top_File(1) = 4
	Bottom_File(1) = 3
	DirName(1) = ' '
	Name_Length(1) = 0
	Highest_Level = 1

	Call SMG$Set_Cursor_Abs(Level_Display(1),%Ref(Bottom_File(1)),1)

	If (DIR_To_Read.EQ.'[000000]000000') then
		Check_Name = .TRUE.
	Else
		Check_Name = .FALSE.
	End If

C-------------------------------------------------------------------C

C		Open with all parameters of a "real" .DIR, so that
C		an error will probably indicate an invalid .dir file
        Open(Unit=1, File= DIR_To_Read//'.DIR',
	1	Access = 'SEQUENTIAL', Carriagecontrol = 'NONE',
	2	Recl = 512, RecordType = 'VARIABLE',
	3	NoSpanBlocks, Status='OLD', READONLY, Shared, 
C 	3	NoSpanBlocks, Status='OLD', READONLY, 
	4	UserOpen = Is_Dir, ERR=9999)  
C
C --NOTE-- Opening SHARED seems to crash on CLOSE with V4.4
C BUT does not crash using VMS 4.5 and FORTRAN 4.6
C

	Call SMG$Begin_Pasteboard_Update (Pasteboard_ID)


C
C	UNTIL MATCH BETWEEN WILDCARD AND FILE NAME
C
                                                  
100    Read(1,200,End=900,Err=900) RecSize, BSize, Big_Rec(1:RecSize-4)
200    Format(Q, 3X, A1, A) ! Read Variable sized rec from dir file
                      
	If (BSize .LT. 5) GoTo 100         

	If (Big_Rec(BSize-3:BSize) .EQ. '.DIR') then
		       Name_Size = BSize - 4	
		IF (Check_Name) then
		   If (Big_Rec(:Name_Size).EQ.'000000') GO TO 100
		END IF

C		OK - we have something.

	Bottom_File(1) = Bottom_File(1) + 1

	If (Bottom_File(1) .GT. Current_Display_Length) then
		Current_Display_Length = Current_Display_Length + 24
		Call SMG$Change_Virtual_Display (Level_Display(1),
	1		Current_Display_Length,20)
		Call SMG$Change_Virtual_Display (Big_Display(1),
	1		Current_Display_Length,B_Width(1))
	End If

C		Put stuff on the visible display
	Call SMG$Set_Cursor_Abs(Level_Display(1),%Ref(Bottom_File(1)),4)
	Call SMG$Put_Line(Level_Display(1),Big_Rec(:Name_Size))
	Call SMG$Draw_Line (Level_Display(1),Bottom_File(1),2,
	1		Bottom_File(1),3)

C		Now, do the "Big" display for full names.
	If (Name_Size .GT. B_Width(1)) then    ! B_Width initially 999999
		B_Width(1) = Name_Size
		Call SMG$Change_Virtual_Display (Big_Display(1),
	1		Current_Display_Length,B_Width(1))
	End If

	Call SMG$Set_Cursor_Abs(Big_Display(1),%Ref(Bottom_File(1)),1)
	Call SMG$Put_Line(Big_Display(1),Big_Rec(:Name_Size))
	
		GoTo 100

        Else
		GoTo 100
	End If


C---------------------------------------------------------------------
                                
900	Close (Unit=1)
	Last_Line = Bottom_File(1) 

	If (Bottom_File(1) .GE. Top_File(1)) then
		Call SMG$Put_Chars (Level_Display(1),'Top Level',
	1		2,9,,SMG$M_Bold)
		Call SMG$Draw_Line (Level_Display(1),1,2,
	1		Bottom_File(1),2)
	End If

	Call SMG$End_Pasteboard_Update (Pasteboard_ID)


9999	Return                 
	END

C----------------------------------------------------------------------
	SUBROUTINE DIRN_READ

	IMPLICIT INTEGER (A-Z)

	Byte BSize

	External Is_Dir

	Include 'SD_Common.Dat'
        Include 'SD_SMG.Dat'
	
C---------------------------------------------------------------------

	Current_File(1) = Top_File(1) - 1


C		Read the "next" name from Level 1
10	Continue

	Current_File(1) = Current_File(1) + 1
	If (Current_File(1) .GT. Bottom_File(1)) GoTo 9900

	Call SMG$Set_Cursor_Abs
	1	(%Ref(Big_Display(1)),%Ref(Current_File(1)),%Ref(1))
	Call SMG$Read_From_Display
	1	(%Ref(Big_Display(1)),%Descr(DirName(1)))

	Call STR$Trim (%Descr(DirName(1)),
	1	%Descr(DirName(1)),%Ref(Name_Length(1)))

 	If (Name_Length(1) .LE. 0) GoTo 10
	If (DirName(1)(:Name_Length(1)) .EQ. ' ') GoTo 10

	Call Make_Appended_Name (1)

C		We found a non-blank line in Top Level display!

	Current_Level = 2

C-------------------------------------------------------------------C

C		Open with all parameters of a "real" .DIR, so that
C		an error will probably indicate an invalid .dir file
50	Continue
9898	FORMAT (A, I6)
	Open(Unit=Current_Level, File= String(:SLen),
	1	Access = 'SEQUENTIAL', Carriagecontrol = 'NONE',
	2	Recl = 512, RecordType = 'VARIABLE',
	3	NoSpanBlocks, Status='OLD', READONLY, Shared, 
C 	3	NoSpanBlocks, Status='OLD', READONLY, 
	4	UserOpen = Is_Dir, ERR=199, IOSTAT=IIII)  
C
C --NOTE-- Opening SHARED seems to crash on CLOSE with V4.4
C BUT does not crash using VMS 4.5 and FORTRAN 4.6
C

C 		If we're past the maximum directory depth, then we can't
C		have any subdirectories.  No need to read - just close.
	If (Current_Level .GT. Max_VMS_Dir_Depth) GoTo 200
	
	
	Current_File (Current_Level) = Current_File (Current_Level-1) -1
	Top_File(Current_Level) = Current_File (Current_Level) + 1
	Bottom_File(Current_Level) = Top_File(Current_Level) - 1




C
C	UNTIL MATCH BETWEEN .DIR AND FILE NAME
C
                                                  
100    Read(Current_Level,101,End=200,Err=200) 
	1	RecSize, BSize, Big_Rec(1:RecSize-4)
101    Format(Q, 3X, A1, A) ! Read Variable sized rec from dir file
                      
	If (BSize .LT. 5) GoTo 100         
                          
	If (Big_Rec(BSize-3:BSize) .EQ. '.DIR') then
	       Name_Length(Current_Level) = BSize - 4	
	       DirName(Current_Level) = 
	1		Big_Rec(:Name_Length(Current_Level))

C		OK - we have something.

		If (.NOT.Have_Display(Current_Level)) then
			Call Create_Level_Display (Current_Level)
		End If

		Current_File (Current_Level) = 
	1		Bottom_File (Current_Level) +1

		Bottom_File(Current_Level) = 
	1		Bottom_File(Current_Level) + 1
		If (Bottom_File(Current_Level) .GT. 
	1			Current_Display_Length) then
			Call Make_Longer
		End If

C		Put stuff on the visible display
		Call Insert_Line (Current_Level)
C			Now, let's open the next file:

		Call Make_Appended_Name (Current_Level)
		Current_Level = Current_Level + 1
		GoTo 50  ! To open the next level file

        Else
		GoTo 100  ! To read the next file
	End If

C---------------------------------------------------------------------
C		HANDLE OPEN ERROR (PROBABLY A 'x.DIR' FILE WHICH
C			WASN'T REALLY A DIRECTORY)
199	CONTINUE
9899	FORMAT(A,I4)
C		Erase stuff from the visible display      
	CL = Current_Level - 1
C		Include the 'line' in Col 3
	Call SMG$Erase_Chars (Level_Display(CL),19,Current_File(CL),2) 

	Call SMG$Erase_Chars (Big_Display(CL),B_Width(CL),
	1		Current_File(CL),1) 

	GoTo 300

C---------------------------------------------------------------------
                                
200	Close (Unit=Current_Level)


	If (Current_Level .LE. Highest_Level) then
	 If (Current_File(Current_Level) .GE. Top_File(Current_Level)) then
		Call SMG$Draw_Line (%Ref(Level_Display(Current_Level)),
	1		%Ref(Top_File(Current_Level)),%Ref(1),
	2		%Ref(Top_File(Current_Level)),%Ref(3))

  	  If (Bottom_File(Current_Level) .GT. Top_File(Current_Level)) then
		Call SMG$Draw_Line (%Ref(Level_Display(Current_Level)),
	1		%Ref(Top_File(Current_Level)),2,
	2		%Ref(Current_File(Current_Level)),2)
	  End If
	 End If
	End If


300	Current_Level = Current_Level - 1
	If (Current_Level .LE. 1) then
		GoTo 10  ! Read another name from Level 1
	Else
		GoTo 100 ! Continue reading file at previous level
	End If


C---------------------------------------------------------------------
C---------------------------------------------------------------------
C---------------------------------------------------------------------
9900	Continue

	Current_Display_Length = Bottom_File(1)
	Do N = 2, Highest_Level
		Current_Display_Length = 
	1		MAX (Current_Display_Length, Bottom_File(N))
	End Do

	Do N = 1, Highest_Level

		Call SMG$Change_Virtual_Display (Level_Display(N),
	1		Current_Display_Length,20)	

		Call SMG$Change_Virtual_Display (Big_Display(N),
	1		Current_Display_Length,B_Width(N))
	End Do

C---------------------------------------------------------------------
9999	Return                 
	END

C----------------------------------------------------------------------
C  Create regular column for directory display
C----------------------------------------------------------------------
	SUBROUTINE Create_Level_Display (N)

	IMPLICIT INTEGER (A-Z)

        Include 'SD_SMG.Dat'                        
	
	Logical*2    Advanced_Video
	Character*13 LID(8)

	Data Lid(1) /'   Top Level'/
	Data Lid(2) /'Second Level'/
	Data Lid(3) /'Third Level'/
	Data Lid(4) /'Fourth Level'/
	Data Lid(5) /'Fifth Level'/
	Data Lid(6) /'Sixth Level'/
	Data Lid(7) /'Seventh Level'/
	Data Lid(8) /'Eighth Level'/
C---------------------------------------------------------------------


	Call SMG$Create_Virtual_Display
     1		 (Current_Display_Length,20, Level_Display(N),
	2		SMG$M_Trunc_Icon)
        Have_Display(N) = .TRUE.
	Highest_Level = N

C		Make a place to put the names, without drawing lines.
        B_Width(N) = 14
	Call SMG$Create_Virtual_Display
	1	(Current_Display_Length,B_Width(N),
	2	Big_Display(N),SMG$M_BORDER,SMG$M_Bold)

	Have_Big_Display(N) = .TRUE.
	Call SMG$Put_Chars (Big_Display(N),Lid(N),2,4,,RU_Mask)

	If (N .EQ. 5) then	! Do 132-col display if possible
	    Call Lib$GetDVI(DVI$_TT_AVO,, 'TT:', Advanced_Video)
	    If (Advanced_Video) then
		SD_Star_Wide = .TRUE.
		Call SMG$Change_Pbd_Characteristics
	1		(Pasteboard_ID, 132)
		Shift_Point = 4
		Call SMG$Change_Virtual_Display (Top_Display,1,132)
		Call SMG$Change_Virtual_Display (Bottom_Display,2,132)
	    End If
	End If
	
	Call SMG$Put_Chars (Level_Display(N),Lid(N),
	1	2,6,,SMG$M_Bold)

	Call SMG$Begin_Pasteboard_Update (Pasteboard_ID)

	Call SMG$Paste_Virtual_Display
     1		 (Level_Display(N),Pasteboard_ID,1,(20*(N-1))+1)
  

	Call SMG$RePaste_Virtual_Display
     1		 (Top_Display,Pasteboard_ID,1,1)
  

	Call SMG$RePaste_Virtual_Display
     1		 (Normal_Display,Pasteboard_ID,1,1)
  


	Call SMG$End_Pasteboard_Update (Pasteboard_ID)
	
	Return
	End


C----------------------------------------------------------------------
C  Make displays longer
C----------------------------------------------------------------------
	SUBROUTINE Make_Longer

	IMPLICIT INTEGER (A-Z)

        Include 'SD_SMG.Dat'

C---------------------------------------------------------------------

	Current_Display_Length = Current_Display_Length + 24

	Do N = 1,8

	If (Have_Display(N)) then

	    	Call SMG$Change_Virtual_Display (Level_Display(N),
	1		Current_Display_Length,20)

		Call SMG$Change_Virtual_Display (Big_Display(N),
	1		Current_Display_Length,B_Width(N))
	Else
		GoTo 9999
	End If

	End Do	

9999    Return
	End


C----------------------------------------------------------------------
C  Insert a Filename on Line "Bottom_File(N)"
C	Line is in BigRec(:Name_Length(N))
C----------------------------------------------------------------------
	SUBROUTINE Insert_Line (N)

	IMPLICIT INTEGER (A-Z)

	Logical Insert

	Character*12 LID(8)

	Data Lid(1) /'   Top Level'/
	Data Lid(2) /'Second Level'/
	Data Lid(3) /'Third Level'/
	Data Lid(4) /'Fourth Level'/
	Data Lid(5) /'Fifth Level'/
	Data Lid(6) /'Sixth Level'/
	Data Lid(7) /'Seventh Level'/
	Data Lid(8) /'Eighth Level'/

        Include 'SD_SMG.Dat'
	Include 'SD_Common.Dat'

C---------------------------------------------------------------------
                   
C		Put stuff on the visible display      
	Call SMG$Set_Cursor_Abs(Level_Display(N),%Ref(Current_File(N)),4)
	Call SMG$Put_Line(Level_Display(N),Big_Rec(:Name_Length(N)))
	If (Current_File(N) .EQ. Top_File(N)) then
		Call SMG$Draw_Line (Level_Display(N),Current_File(N),1,
	1		Current_File(N),3)
	Else
		Call SMG$Draw_Line (Level_Display(N),Current_File(N),2,
	1		Current_File(N),3)
	End If

C		Now, do the "Big" display for full names.
	If (Name_Length(N) .GT. B_Width(N)) then    ! B_Width initially 999999
	 	B_Width(N) = Name_Length(N)
		Call SMG$Change_Virtual_Display (Big_Display(N),
	1		Current_Display_Length,B_Width(N))
	End If

	Call SMG$Set_Cursor_Abs(Big_Display(N),%Ref(Current_File(N)),1)
	Call SMG$Put_Line(Big_Display(N),Big_Rec(:Name_Length(N)))

C		Now, what do we have to do to the other columns?

	If (Current_File(N) .EQ. Current_File(N-1)) then ! draw line
		If (Name_Length(N-1) .LT. 17) then
			Call SMG$Draw_Line (Level_Display(N-1),
	1			Current_File(N),
	2			%Ref(Name_Length(N-1)+4),
	3			Current_File(N),20)
		End If



 	Else    ! We have to insert a blank line to the left...
		Last_Line = Last_Line + 1  ! This is brute force...
		If (Last_Line .GT. Current_Display_Length) then
			Call Make_Longer
		End If

	    Do K = 1, N-1
		Bottom_File(K) = Bottom_File(K) + 1

		Call SMG$Insert_Line (%Ref(Level_Display(K)),
	1		%Ref(Current_File(N)),' ',SMG$M_DOWN)

		Call SMG$Insert_Line (%Ref(Big_Display(K)),
	1		%Ref(Current_File(N)),' ',SMG$M_DOWN)
	    End Do
	End If

        Return
	End


C----------------------------------------------------------------------
C  Make complete filename from appended levels
C----------------------------------------------------------------------
	SUBROUTINE Make_Appended_Name (Last_Level)

	IMPLICIT INTEGER (A-Z)

        Include 'SD_SMG.Dat'
	Include 'SD_Common.Dat'

C---------------------------------------------------------------------

	String = Environment
	SLen = EnvLen

	If (Last_Level .GT. 1) then

		SLen = SLen - 1    ! to take care of ]
		Do N = 1,Last_Level-1

		String (SLen+1:) = '.'//DirName(N)
		SLen = SLen + Name_Length(N) +1

		End Do	

		K = Lib$MatchC('000000.',String)
		If (K .GT. 0) then
			String(K:) = String(K+7:)
			SLen = SLen - 7
		End If
		
                SLen = SLen + 1
		String(SLen:SLen) = ']'
                        
	Else
		K = Lib$MatchC('[',String)
		If (K .GT. 0) then
			String(K:) = ' '
			SLen = K-1
		End If

	End If          

	String (SLen+1:) = Dirname(Last_Level)
	SLen = SLen + Name_Length(Last_Level)
	String (SLen+1:SLen+4) = '.DIR'
	SLen = SLen + 4

9999    Return
	End


C----------------------------------------------------------------------
C  Control tree movement and selection
C----------------------------------------------------------------------

	SUBROUTINE Display

	IMPLICIT INTEGER (A-Z)

        Include 'SD_SMG.Dat'
	Include 'SD_Common.Dat'

C---------------------------------------------------------------------

	Max_Top  = MAX (1, Current_Display_Length-21)
	Top_Line = 1
	Left_Col = 1
	Dis_Line = 4
	Dis_Col = 1

	Do N = 1, Highest_Level
	    Bottom_File(N) = Current_Display_Length
	    Do K = Current_Display_Length, 4, -1
		Call SMG$Set_Cursor_Abs
	1		(%Ref(Level_Display(N)),%Ref(K),%Ref(4))
		Call SMG$Read_From_Display
	1		(%Ref(Level_Display(N)),%Descr(String))
		Call STR$Trim (%Descr(String),
	1		%Descr(String),%Ref(SLen))
		If (SLen .GT. 0) then
			Bottom_File(N) = K
 			GoTo 10
		End If
	    End Do
10	End Do

	Do N = 1, Highest_Level
	    Top_File(N) = 4
	    Do K = 4, Current_Display_Length
		Call SMG$Set_Cursor_Abs
	1		(%Ref(Level_Display(N)),%Ref(K),%Ref(4))
		Call SMG$Read_From_Display
	1		(%Ref(Level_Display(N)),%Descr(DirName(N)))
		Call STR$Trim (%Descr(DirName(N)),
	1		%Descr(DirName(N)),%Ref(Name_Length(N)))
		If (Name_Length(N) .GT. 0) then
			LL = Lib$MatchC(Char(1),
	1			DirName(N)(:Name_Length(N)))
			If (LL .GT. 1) Name_Length(N) = LL-1
			Top_File(N) = K
 			GoTo 20
		End If
	    End Do
20	End Do

	If (Bottom_File(1) .GT. Top_File(1)) then
		Call SMG$Draw_Line (Level_Display(1),
	1		Top_File(1),2,
	2		Bottom_File(1),2)
	End If


	Call SMG$UnPaste_Virtual_Display
     1		 (Normal_Display,Pasteboard_ID)

	Call SMG$Paste_Virtual_Display
     1		 (Bottom_Display,Pasteboard_ID,23,1)
	
	Cmd = ' '
  
C-----------------------------------------------------------------------
	ENTRY Re_Display   ! Used after an "external" operation.
	
	If (SD_Star_Wide) then
		Max_Left = MAX (1, Highest_Level-5)
	Else
		Max_Left = MAX (1, Highest_Level-3)
	End If
C-----------------------------------------------------------------------

C		Position Cursor and Read Keystroke
200	Call SMG$Set_Cursor_Abs	(Level_Display(Dis_Col),Dis_Line,4)

	KK = Name_Length(Dis_Col)
	
	If (SD_Highlight) Call SMG$Change_Rendition (Level_Display(Dis_Col),
	1	Dis_Line,4,1,KK,SMG$M_Bold)

	Call SMG$Set_Cursor_Abs	(Level_Display(Dis_Col),Dis_Line,2)

	Call SMG$Read_KeyStroke (Keyboard_ID,Terminator)
                                   
 		If (Terminator .EQ. SMG$K_TRM_UP) then

			Call Up_Tree (.TRUE.)
			GoTo 200


		Else If (Terminator .EQ. SMG$K_TRM_DOWN) then
			
			Call Down_Tree (.TRUE.)
			GoTo 200


		Else If (Terminator .EQ. SMG$K_TRM_LEFT) then
			
			Call Left_Tree
			GoTo 200


		Else If (Terminator .EQ. SMG$K_TRM_RIGHT) then
			
			Call Right_Tree
			GoTo 200


		Else If (Terminator .EQ. SMG$K_TRM_E5) then ! Prev Screen
			
1005			KK = Name_Length(Dis_Col)
			If (SD_Highlight) Call SMG$Change_Rendition 
	1			(Level_Display(Dis_Col),
	2			 Dis_Line,4,1,KK,SMG$M_Bold,SMG$M_Bold)

			Dis_Line = 
	1		    MAX( Dis_Line-14, Top_File(Dis_Col) + 1)
			Call Up_Tree (.FALSE.)
			GoTo 200


		Else If (Terminator .EQ. SMG$K_TRM_E6) then ! Next Screen
			
1006			KK = Name_Length(Dis_Col)
			If (SD_Highlight) Call SMG$Change_Rendition 
	1			(Level_Display(Dis_Col),
	2			 Dis_Line,4,1,KK,SMG$M_Bold,SMG$M_Bold)

			Dis_Line = 
	1		    MIN( Dis_Line+14, Bottom_File(Dis_Col) - 1)
			Call Down_Tree (.FALSE.)
			GoTo 200


		Else If (Terminator .EQ. SMG$K_TRM_CTRLW) then  !  RePaint

			Call SMG$Repaint_Screen (Pasteboard_ID)
			GoTo 200


		Else If (Terminator .EQ. SMG$K_TRM_PF1) then  ! Gold
			Call SMG$Read_KeyStroke (Keyboard_ID,Terminator)
			Cmd = Char(Terminator)

			If ((Cmd .EQ. 't') .OR. (Cmd .EQ. 'T')) then
				KK = Name_Length(Dis_Col)
				If (SD_Highlight) Call SMG$Change_Rendition 
	1			(Level_Display(Dis_Col),
	2			 Dis_Line,4,1,KK,SMG$M_Bold,SMG$M_Bold)

				Dis_Line = Top_File(Dis_Col) + 1
				Call Up_Tree (.FALSE.)
				GoTo 200
			Else If ((Cmd .EQ. 'b') .OR. (Cmd .EQ. 'B')) then
				KK = Name_Length(Dis_Col)
				If (SD_Highlight) Call SMG$Change_Rendition 
	1			(Level_Display(Dis_Col),
	2			 Dis_Line,4,1,KK,SMG$M_Bold,SMG$M_Bold)

				Dis_Line = Bottom_File(Dis_Col) - 1
				Call Down_Tree (.FALSE.)
				GoTo 200
			Else If ((Cmd .EQ. 'h') .OR. (Cmd .EQ. 'H')) then
				Call SD_Tree_Help
				GoTo 200
			Else If (Terminator .EQ. SMG$K_TRM_LEFT) then
			    Call SMG$Begin_Pasteboard_Update (Pasteboard_ID)
			    Do While (Dis_Col .GT. 1)
				Call Left_Tree
			    End Do
			    Call SMG$End_Pasteboard_Update (Pasteboard_ID)
			    GoTo 200
			Else If (Terminator .EQ. SMG$K_TRM_RIGHT) then
			    Call SMG$Begin_Pasteboard_Update (Pasteboard_ID)
			    Do While (Dis_Col .LT. Highest_Level)
				Call Right_Tree
			    End Do
			    Call SMG$End_Pasteboard_Update (Pasteboard_ID)
			    GoTo 200
			Else If (Terminator .EQ. SMG$K_TRM_UP) then
			    GoTo 1005  ! Same as Previous Screen
			Else If (Terminator .EQ. SMG$K_TRM_DOWN) then
			    GoTo 1006  ! Same as Next Screen
                        Else
				ChgLen = -1
                                GoTo 9000   ! Exit
			End If


C			Help Key or PF2 or ?
		Else If ((Terminator .EQ. SMG$K_TRM_F15) .OR.
	1		 (Terminator .EQ. SMG$K_TRM_PF2) .OR.
	2		 (Terminator .EQ. SMG$K_TRM_QUESTION_MARK))  then
                        Call SD_Tree_Help
			GoTo 200
			

C			CR or either Select Key or DO or Enter:
		Else If ((Terminator .EQ. SMG$K_TRM_CR)     .OR.
	1		 (Terminator .EQ. SMG$K_TRM_ENTER)  .OR.
	2		 (Terminator .EQ. SMG$K_TRM_PERIOD) .OR.
	3		 (Terminator .EQ. SMG$K_TRM_F16)    .OR.
	4		 (Terminator .EQ. SMG$K_TRM_E4))    then

			Call Make_Change_Name
			GoTo 9999
	
		Else
			Cmd = Char(Terminator)
			ChgLen = -1
			GoTo 9000   ! Exit
		End If


C		Exit without selecting
9000	Continue
                 

9999    Continue
	Return
	End

C----------------------------------------------------------------------
C  Move Down the tree
C----------------------------------------------------------------------

	SUBROUTINE Down_Tree (Make_Dull)

	IMPLICIT INTEGER (A-Z)

	Logical Make_Dull

        Include 'SD_SMG.Dat'

C---------------------------------------------------------------------

	Call SMG$Begin_Pasteboard_Update (Pasteboard_ID)

	If ((Make_Dull) .AND. (Name_Length(Dis_Col) .GT. 0)) then
		KK = Name_Length(Dis_Col)
		If (SD_Highlight) 
	1		Call SMG$Change_Rendition (Level_Display(Dis_Col),
	2		Dis_Line,4,1,KK,SMG$M_Bold,SMG$M_Bold)
	End If

	Do K = Dis_Line+1, Bottom_File(Dis_Col)
		Call SMG$Set_Cursor_Abs
	1		(%Ref(Level_Display(Dis_Col)),%Ref(K),%Ref(4))
		Call SMG$Read_From_Display
	1		(%Ref(Level_Display(Dis_Col)),
	2		 %Descr(DirName(Dis_Col)))
		Call STR$Trim (%Descr(DirName(Dis_Col)),
	1		%Descr(DirName(Dis_Col)),
	2		%Ref(Name_Length(Dis_Col)))
		If (Name_Length(Dis_Col) .GT. 0) then
			LL = Lib$MatchC(Char(1),
	1			DirName(Dis_Col)(:Name_Length(Dis_Col)))
			If (LL .GT. 1) Name_Length(Dis_Col) = LL-1
			Dis_Line = K
			GoTo 100
		End If
	End Do

100	If (((Dis_Line - Top_Line) .GT. 18) .OR.
	1   ((Dis_Line - Top_Line) .LT.  4)) then
	     Top_Temp = Min (Max_Top, Dis_Line-18)
	     Top_Temp = Max (Top_Temp, 1)  ! Avoid Negative
	     If (Top_Line .NE. Top_Temp) then
		Top_Line = Top_Temp
		Do K = 1,Highest_Level
			Call SMG$RePaste_Virtual_Display 
	1			(Level_Display(K),Pasteboard_ID,
	2			 (2-Top_Line),((20*(K-Left_Col))+1))
		End Do

		Call SMG$RePaste_Virtual_Display
     1			 (Bottom_Display,Pasteboard_ID,23,1)
                                                    
		Call SMG$RePaste_Virtual_Display
     1			 (Top_Display,Pasteboard_ID,1,1)
  
	    End If
	End If

	Call SMG$End_Pasteboard_Update (Pasteboard_ID)


9999    Return   
	End


C----------------------------------------------------------------------
C  Move Up the tree
C----------------------------------------------------------------------

	SUBROUTINE Up_Tree (Make_Dull)

	IMPLICIT INTEGER (A-Z)

        Include 'SD_SMG.Dat'

C---------------------------------------------------------------------

	Call SMG$Begin_Pasteboard_Update (Pasteboard_ID)

	If ((Make_Dull) .AND. (Name_Length(Dis_Col) .GT. 0)) then
		KK = Name_Length(Dis_Col)
		If (SD_Highlight) 
	1		Call SMG$Change_Rendition (Level_Display(Dis_Col),
	2		Dis_Line,4,1,KK,SMG$M_Bold,SMG$M_Bold)
	End If

	Do K = Dis_Line-1, Top_File(Dis_Col), -1
		Call SMG$Set_Cursor_Abs
	1		(%Ref(Level_Display(Dis_Col)),%Ref(K),%Ref(4))
		Call SMG$Read_From_Display
	1		(%Ref(Level_Display(Dis_Col)),
	2		 %Descr(DirName(Dis_Col)))
		Call STR$Trim (%Descr(DirName(Dis_Col)),
	1		%Descr(DirName(Dis_Col)),
	2		%Ref(Name_Length(Dis_Col)))
		If (Name_Length(Dis_Col) .GT. 0) then
			LL = Lib$MatchC(Char(1),
	1			DirName(Dis_Col)(:Name_Length(Dis_Col)))
			If (LL .GT. 1) Name_Length(Dis_Col) = LL-1
			Dis_Line = K
			GoTo 100
		End If
	End Do

100	If (((Dis_Line - Top_Line) .LT.  4) .OR.
	1   ((Dis_Line - Top_Line) .GT. 18)) then
	     Top_Temp = MAX (1, Dis_Line-4)
	     If (Top_Line .NE. Top_Temp) then
		Top_Line = Top_Temp	
		Do K = 1,Highest_Level
			Call SMG$RePaste_Virtual_Display 
	1			(Level_Display(K),Pasteboard_ID,
	2			 (2-Top_Line),((20*(K-Left_Col))+1))
		End Do

		Call SMG$RePaste_Virtual_Display
     1			 (Bottom_Display,Pasteboard_ID,23,1)
  
		Call SMG$RePaste_Virtual_Display
     1			 (Top_Display,Pasteboard_ID,1,1)

             End If
	End If

	Call SMG$End_Pasteboard_Update (Pasteboard_ID)



                                             
9999    Return
	End


C----------------------------------------------------------------------
C  Go Right 1 Col
C----------------------------------------------------------------------

	SUBROUTINE Right_Tree 

	IMPLICIT INTEGER (A-Z)

        Include 'SD_SMG.Dat'

C---------------------------------------------------------------------

	If (Dis_Col .GE. Highest_Level) RETURN

	If (Name_Length(Dis_Col) .GT. 0) then
		KK = Name_Length(Dis_Col)
		If (SD_Highlight) 
	1		Call SMG$Change_Rendition (Level_Display(Dis_Col),
	2		Dis_Line,4,1,KK,SMG$M_Bold,SMG$M_Bold)
	End If

	Call SMG$Begin_Pasteboard_Update (Pasteboard_ID)

	Dis_Col = Dis_Col + 1

	If ((Dis_Col - Left_Col) .GT. Shift_Point) then
		Left_Temp = MIN (Max_Left, Dis_Col-2)
		Left_Temp = MAX (Left_Temp, 1)  ! Safety
		If (Left_Temp .NE. Left_Col) then
			Left_Col = Left_Temp

		Do K = 1,Highest_Level
			Call SMG$RePaste_Virtual_Display 
	1			(Level_Display(K),Pasteboard_ID,
	2			 (2-Top_Line),((20*(K-Left_Col))+1))
		End Do

		Call SMG$RePaste_Virtual_Display
     1			 (Bottom_Display,Pasteboard_ID,23,1)
  
		Call SMG$RePaste_Virtual_Display
     1			 (Top_Display,Pasteboard_ID,1,1)
  
	
		End If
	End If

C			OK - check if we see a file...
		Call SMG$Set_Cursor_Abs
	1		(%Ref(Level_Display(Dis_Col)),
	2		 %Ref(Dis_Line),%Ref(4))
		Call SMG$Read_From_Display
	1		(%Ref(Level_Display(Dis_Col)),
	2		 %Descr(DirName(Dis_Col)))
		Call STR$Trim (%Descr(DirName(Dis_Col)),
	1		%Descr(DirName(Dis_Col)),
	2		%Ref(Name_Length(Dis_Col)))
		If (Name_Length(Dis_Col) .GT. 0) then
			LL = Lib$MatchC(Char(1),
	1			DirName(Dis_Col)(:Name_Length(Dis_Col)))
			If (LL .GT. 1) Name_Length(Dis_Col) = LL-1
			GoTo 9000
		End If


C			Not looking at a file - so do something.

	If (Dis_Line .LT. Top_File(Dis_Col)) then
		Dis_Line = Top_File(Dis_Col) + 1
		Call Up_Tree (.FALSE.)
	Else If (Dis_Line .GT. Bottom_File(Dis_Col)) then
		Dis_Line = Bottom_File(Dis_Col) - 1
		Call Down_Tree (.FALSE.)
	Else   ! Always go down
		Call Down_Tree (.FALSE.)
	End If



9000	Call SMG$End_Pasteboard_Update (Pasteboard_ID)

9999    Return
	End


C----------------------------------------------------------------------
C  Go Left 1 Col
C----------------------------------------------------------------------

	SUBROUTINE Left_Tree 

	IMPLICIT INTEGER (A-Z)

        Include 'SD_SMG.Dat'

C---------------------------------------------------------------------

	If (Dis_Col .LE. 1) RETURN

	If (Name_Length(Dis_Col) .GT. 0) then
		KK = Name_Length(Dis_Col)
		If (SD_Highlight) 
	1		Call SMG$Change_Rendition (Level_Display(Dis_Col),
	2		Dis_Line,4,1,KK,SMG$M_Bold,SMG$M_Bold)
	End If

	Call SMG$Begin_Pasteboard_Update (Pasteboard_ID)

	Dis_Col = Dis_Col - 1

	If ((Dis_Col - Left_Col) .LT. 1) then
		Left_Temp = MAX (1, Dis_Col-1)
		If (Left_Temp .NE. Left_Col) then
			Left_Col = Left_Temp

		Do K = 1,Highest_Level
			Call SMG$RePaste_Virtual_Display 
	1			(Level_Display(K),Pasteboard_ID,
	2			 (2-Top_Line),((20*(K-Left_Col))+1))
		End Do

		Call SMG$RePaste_Virtual_Display
     1			 (Bottom_Display,Pasteboard_ID,23,1)
  
		Call SMG$RePaste_Virtual_Display
     1			 (Top_Display,Pasteboard_ID,1,1)
  


		End If
	End If

C			OK - check if we see a file...
		Call SMG$Set_Cursor_Abs
	1		(%Ref(Level_Display(Dis_Col)),
	2		 %Ref(Dis_Line),%Ref(4))
		Call SMG$Read_From_Display
	1		(%Ref(Level_Display(Dis_Col)),
	2		 %Descr(DirName(Dis_Col)))
		Call STR$Trim (%Descr(DirName(Dis_Col)),
	1		%Descr(DirName(Dis_Col)),
	2		%Ref(Name_Length(Dis_Col)))
		If (Name_Length(Dis_Col) .GT. 0) then
			LL = Lib$MatchC(Char(1),
	1			DirName(Dis_Col)(:Name_Length(Dis_Col)))
			If (LL .GT. 1) Name_Length(Dis_Col) = LL-1
		Else
			Call Up_Tree (.FALSE.)
		End If



9000	Call SMG$End_Pasteboard_Update (Pasteboard_ID)

9999    Return
	End


C----------------------------------------------------------------------
C  Make complete pathname from appended levels (to change DIR)
C----------------------------------------------------------------------
	SUBROUTINE Make_Change_Name

	IMPLICIT INTEGER (A-Z)

        Include 'SD_SMG.Dat'
	Include 'SD_Common.Dat'

C---------------------------------------------------------------------

	Change = Environment
	ChgLen = EnvLen


	ChgLen = ChgLen - 1    ! to take care of ]

	Call SMG$Begin_Pasteboard_Update (Pasteboard_ID)

	Call SMG$Set_Cursor_Abs
	1		(%Ref(Big_Display(Dis_Col)),
	2		 %Ref(Dis_Line),%Ref(1))
	Call SMG$Read_From_Display
	1 		(%Ref(Big_Display(Dis_Col)),
	2		 %Descr(DirName(Dis_Col)))
	Call STR$Trim (%Descr(DirName(Dis_Col)),
	1		%Descr(DirName(Dis_Col)),
	2		%Ref(Name_Length(Dis_Col)))


	Our_Level = Dis_Col

	Do N = 1, Our_Level-1   ! Hidden, but we're getting the right stuff
		Call Left_Tree

C			Now, do the "overflow" file.

		Call SMG$Set_Cursor_Abs
	1		(%Ref(Big_Display(Dis_Col)),
	2		 %Ref(Dis_Line),%Ref(1))
		Call SMG$Read_From_Display
	1		(%Ref(Big_Display(Dis_Col)),
	2		 %Descr(DirName(Dis_Col)))
		Call STR$Trim (%Descr(DirName(Dis_Col)),
	1		%Descr(DirName(Dis_Col)),
	2		%Ref(Name_Length(Dis_Col)))

	End Do 

	Do N = 1, Our_Level
		If (DirName(N) .NE. ' ') then
			Change (ChgLen+1:) = '.'//DirName(N)
			ChgLen = ChgLen + Name_Length(N) +1
		End If
	End Do


	K = Lib$MatchC('000000.',Change)
	If (K .GT. 0) then
		Change(K:) = Change(K+7:)
		ChgLen = ChgLen - 7
	End If
		
        ChgLen = ChgLen + 1
	Change(ChgLen:ChgLen) = ']'
                        

9999    Return
	End


C*****************************************************************************
C
C  Help Menu for SDTREE			October, 1986
C	Dale E. Coy
C	Los Alamos National Laboratory
C	(505) 667-3270
C          
C*****************************************************************************

	Subroutine SD_Tree_Help 
	Implicit Integer*4 (A - Z)
	Integer*4 BU_Mask

	Include 'SD_SMG.Dat'

        Parameter (BU_Mask  = SMG$M_Bold .OR. SMG$M_Underline)
C-------------------------------------------------------------------C

	Call SMG$Begin_Pasteboard_Update (Pasteboard_ID)

	Call SMG$Create_Virtual_Display
     1		 (24,80, SDH_Display)

	Call SMG$Paste_Virtual_Display (SDH_Display,
	1	Pasteboard_ID,1,1)

C		LABEL FOR THIS SCREEN
	Call SMG$Put_Line (SDH_Display,
	1	'                                TREE Commands'//
	2	'                                        '
	3	,,BR_Mask)

        Call SMG$Put_Chars (SDH_Display,
	1	'Arrow Keys - Move around in the tree.',3,3)
	Call SMG$Change_Rendition (SDH_Display,3,3,1,10,SMG$M_Bold)

        Call SMG$Put_Chars (SDH_Display,
	1	'Next Screen (VT2xx/3xx) - Move DOWN in Current Column.',
	2		4,3)
	Call SMG$Change_Rendition (SDH_Display,4,3,1,11,SMG$M_Bold)

        Call SMG$Put_Chars (SDH_Display,
	1	'Prev Screen (VT2xx/3xx) - Move UP in Current Column.',
	2		5,3)
	Call SMG$Change_Rendition (SDH_Display,5,3,1,11,SMG$M_Bold)

        Call SMG$Put_Chars (SDH_Display,
	1	'Return/Select/Enter/Do (VT2xx/3xx) - '//
	2	'Select directory to "GoTo".',6,3)
	Call SMG$Change_Rendition (SDH_Display,6, 3,1,6,SMG$M_Bold)
	Call SMG$Change_Rendition (SDH_Display,6,10,1,6,SMG$M_Bold)
	Call SMG$Change_Rendition (SDH_Display,6,17,1,5,SMG$M_Bold)
	Call SMG$Change_Rendition (SDH_Display,6,23,1,2,SMG$M_Bold)



C		LABEL FOR GOLD COMMANDS

	Call SMG$Put_Chars (SDH_Display,
	1	'  Gold Commands:'//
	2	' - Type GOLD (PF1) followed by another key. '
	3	,9,10,,RU_Mask)


        Call SMG$Put_Chars (SDH_Display,
	1	'Gold',11,3,,SMG$M_Reverse)
        Call SMG$Put_Chars (SDH_Display,
	1 'T - Go to TOP of Current Column.'
	2   	,11,8)                                        
	Call SMG$Change_Rendition (SDH_Display,11,8,1,1,SMG$M_Bold)
                 
        Call SMG$Put_Chars (SDH_Display,
	1	'Gold',12,3,,SMG$M_Reverse)
        Call SMG$Put_Chars (SDH_Display,
	1 'B - Go to BOTTOM of Current Column.'
	2   	,12,8)                                        
	Call SMG$Change_Rendition (SDH_Display,12,8,1,1,SMG$M_Bold)

        Call SMG$Put_Chars (SDH_Display,
	1	'Gold',13,3,,SMG$M_Reverse)
        Call SMG$Put_Chars (SDH_Display,
	1 'Left-Arrow  - Go to First Column.'
	2   	,13,8)                                        
	Call SMG$Change_Rendition (SDH_Display,13,8,1,10,SMG$M_Bold)

        Call SMG$Put_Chars (SDH_Display,
	1	'Gold',14,3,,SMG$M_Reverse)
        Call SMG$Put_Chars (SDH_Display,
	1 'Right-Arrow - Go to Last (right) Column.'
	2   	,14,8)                                        
	Call SMG$Change_Rendition (SDH_Display,14,8,1,11,SMG$M_Bold)

        Call SMG$Put_Chars (SDH_Display,
	1	'Gold',15,3,,SMG$M_Reverse)
        Call SMG$Put_Chars (SDH_Display,
	1 'P - Print the Tree display (on your default printer).'
	2   	,15,8)                                        
	Call SMG$Change_Rendition (SDH_Display,15,8,1,1,SMG$M_Bold)

        Call SMG$Put_Chars (SDH_Display,
	1	'Gold',16,3,,SMG$M_Reverse)
        Call SMG$Put_Chars (SDH_Display,
	1 'A - Change your default printer.'
	2   	,16,8)                                        
	Call SMG$Change_Rendition (SDH_Display,16,8,1,1,SMG$M_Bold)



        Call SMG$Put_Chars (SDH_Display,
	1	'Gold',19,3,,SMG$M_Reverse)
        Call SMG$Put_Chars (SDH_Display,
	1 'H/?/PF2/Help (VT2xx/3xx) - Show this Help display.'
	2   	,19,8)                                        
	Call SMG$Change_Rendition (SDH_Display,19, 8,1,1,SMG$M_Bold)
	Call SMG$Change_Rendition (SDH_Display,19,10,1,1,SMG$M_Bold)
	Call SMG$Change_Rendition (SDH_Display,19,12,1,3,SMG$M_Bold)
	Call SMG$Change_Rendition (SDH_Display,19,16,1,4,SMG$M_Bold)

        Call SMG$Put_Chars (SDH_Display,
	1  'Press any other key to exit from the Tree Display.',21,15)
	Call SMG$Change_Rendition (SDH_Display,21,15,1,9,SMG$M_Bold)
	Call SMG$Change_Rendition (SDH_Display,21,25,1,5,   BU_Mask)
	Call SMG$Change_Rendition (SDH_Display,21,31,1,3,SMG$M_Bold)


C		Bottom instructions:
	Call SMG$Set_Cursor_Abs
	1		(%Ref(SDH_Display),%Ref(24),%Ref(1))

	Call SMG$Put_Line (SDH_Display,
	1 '                 Press any key to return to the'//
	2 ' Tree Display.                    '
	3	,,SMG$M_Reverse)


	Call SMG$End_Pasteboard_Update (Pasteboard_ID)

	Call SMG$Set_Cursor_Abs
	1		(%Ref(SDH_Display),%Ref(24),%Ref(1))


	Call SMG$Read_KeyStroke (Keyboard_ID,Terminator)
                                   
500	Call SMG$UnPaste_Virtual_Display (SDH_Display,Pasteboard_ID)
	Call SMG$Delete_Virtual_Display  (SDH_Display)

        Return          
        End
                                               
