C---------------------------------------------------------------------------
	SUBROUTINE SDTREE
C---------------------------------------------------------------------------
*
*	Alan L. Zirkle     Naval Surface Weapons Center
*			   Code K53
*			   Dahlgren, Virginia  22448
*
*  Modified by:                          Sept/Oct 1986 (V4.0A)
*	Dale E. Coy
*	Los Alamos National Laboratory
*
C---------------------------------------------------------------------------

	IMPLICIT INTEGER (A-Z)


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

	If (Do_ID) then
		Print *,'        '//ReVideo//' SDTree Version 4.0A '//Dull
		Return
	End If

	Call SDTree_SMG

	IF (INDEX(Current_Directory(1:CDirLen),'.').EQ.0) THEN

	    CALL DIR1_READ('[000000]'//Current_Directory(2:CDirLen-1))

	ELSE

	    DO I=CDirLen-1,1,-1

		IF (Current_Directory(I:I).EQ.'.') GO TO 10

	    ENDDO

10	    Current_Directory(I:I) = ']'

	    CALL DIR1_READ(Current_Directory(1:CDirLen-1))
                                           
	ENDIF

	If (Bottom_File(1) .GE. Top_File(1)) then    ! we got something

		Call Dirn_Read

		ChgLen = 0
		CALL DISPLAY

C		   Terminate, clearing the screen (SDMAIN will write output).
		Call SMG$Delete_Pasteboard (Pasteboard_ID)
		If (ChgLen .LE. 0) then   ! We should identify.
			Print *
			Print *,'  ',Environment(:EnvLen)
			Print *
		End If
		GoTo 9999

	Else

C			Terminate, clearing only the last lines
		Call SMG$UnPaste_Virtual_Display 
	1			(Level_Display(1), Pasteboard_ID)
		Call SMG$UnPaste_Virtual_Display 
	1			(Normal_Display, Pasteboard_ID)
		Call SMG$Set_Cursor_Abs(Main_Display,4,1)

		Print *,' No SubDirectories in this structure.'
		Print *
		Call SMG$Delete_Pasteboard (Pasteboard_ID,0)
		GoTo 9999
	End If

9999	Continue

	Call SMG$Delete_Virtual_Keyboard (Keyboard_ID)

	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

	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$Put_Chars (Level_Display(1),'Top Level',
	1	2,10,,SMG$M_Bold)
	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,ERR=9999)  

	Call SMG$Begin_Pasteboard_Update (Pasteboard_ID)
	Call SMG$Draw_Line (Level_Display(1),1,2,Top_File(1),2)


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)
	     If (Have_Big_Display(1)) then
		Call SMG$Change_Virtual_Display (Big_Display(1),
	1		Current_Display_Length,B_Width(1))
	     End If
	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 we have a "Big" display for full names?
300	If (Have_Big_Display(1)) then
		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),
	1		%Ref(Bottom_File(1)),1)
		Call SMG$Put_Line(Big_Display(1),
	1		Big_Rec(:Name_Size))
	Else
		If (Name_Size .GT. 17) then
                        B_Width(1) = Name_Size
			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),
	1			'Top Level',2,8,,RU_Mask)

			Do 310 K = Top_File(1), (Bottom_File(1)-1)
		Call SMG$Set_Cursor_Abs
	1		(%Ref(Level_Display(1)),%Ref(K),%Ref(4))
		Call SMG$Read_From_Display
	1		(%Ref(Level_Display(1)),%Descr(String))
		Call STR$Trim (%Descr(String),
	1		%Descr(String),%Ref(SLen))
		Call SMG$Set_Cursor_Abs
	1		(%Ref(Big_Display(1)),%Ref(K),%Ref(1))
		Call SMG$Put_Line(Big_Display(1),String(:SLen))
310			Continue

			GoTo 300   ! To fill it.
		End If
	End If
	
		GoTo 100

        Else
		GoTo 100
	End If


C---------------------------------------------------------------------
                                
900	Close (Unit=1)
	Last_Line = Bottom_File(1) 
	Call SMG$Draw_Line (Level_Display(1),Top_File(1),2,
	1	Bottom_File(1),2)
	Call SMG$End_Pasteboard_Update (Pasteboard_ID)


9999	Return                 
	END

C----------------------------------------------------------------------
C------------------------------------------------------------------------
C	SET UP SMG ENVIRONMENT FOR SDTree PROGRAMS
C		Dale E. Coy         Sept/Oct, 1986
C		Los Alamos National Laboratory
C
C	Used by SDTree
C------------------------------------------------------------------------
	Subroutine SDTree_SMG

        Implicit Integer*4 (A - Z)
	Include 'SD_SMG.Dat'
	Include 'SD_Common.Dat'

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

	
	Call SMG$Create_Pasteboard
     1		 (Pasteboard_ID,,PB_Rows,PB_Columns)


	Call SMG$Create_Virtual_Keyboard (Keyboard_ID,
	1	'TT')

C------------------------------------------------------------------
             
	Current_Display_Length = 22

	Call SMG$Create_Virtual_Display
     1		 (Current_Display_Length,20, Level_Display(1),
	1		SMG$M_Trunc_Icon)
        Have_Display(1) = .TRUE.
	Last_Line = 0
	


	Call SMG$Create_Virtual_Display
     1		 (1,80, Top_Display,,SMG$M_REVERSE)

	Call SMG$Create_Virtual_Display
     1		 (2,80, Bottom_Display,,SMG$M_REVERSE)

	Call SMG$Create_Virtual_Display
     1		 (1,13, Normal_Display,,BR_Mask)



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$Paste_Virtual_Display
     1		 (Top_Display,Pasteboard_ID,1,1)
  
	Call SMG$Put_Line(Top_Display,' Structure of '
	1		//Environment(:EnvLen))
                                                                       

	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.')


	Call SMG$End_Pasteboard_Update (Pasteboard_ID)
	
	
9999	Return
        End

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

	IMPLICIT INTEGER (A-Z)

	Byte BSize


	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

	If (Have_Big_Display(1)) then
		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)))
        Else
		Call SMG$Set_Cursor_Abs
	1		(%Ref(Level_Display(1)),%Ref(Current_File(1)),%Ref(4))
		Call SMG$Read_From_Display
	1		(%Ref(Level_Display(1)),%Descr(DirName(1)))
	End If

	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      Open(Unit=Current_Level, File= String(:SLen),
	1	Access = 'SEQUENTIAL', Carriagecontrol = 'NONE',
	2	Recl = 512, RecordType = 'VARIABLE',
	3	NoSpanBlocks, Status='OLD', READONLY,ERR=300)  


	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


CZ	Call SMG$Begin_Pasteboard_Update (Pasteboard_ID)


C
C	UNTIL MATCH BETWEEN WILDCARD 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---------------------------------------------------------------------
                                
200	Close (Unit=Current_Level)


	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


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

CZ	Call SMG$End_Pasteboard_Update (Pasteboard_ID)

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)	

		If (Have_Big_Display(N)) then
			Call SMG$Change_Virtual_Display (Big_Display(N),
	1			Current_Display_Length,B_Width(N))
		End If
	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'                        

	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'/
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

	Call SMG$Begin_Pasteboard_Update (Pasteboard_ID)

	Call SMG$Put_Chars (Level_Display(N),LID(N),
	1	2,7,,SMG$M_Bold)

	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)

		If (Have_Big_Display(N)) then
			Call SMG$Change_Virtual_Display (Big_Display(N),
	1			Current_Display_Length,B_Width(N))
		End If
	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 we have a "Big" display for full names?
300	If (Have_Big_Display(N)) then
		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),
	1		%Ref(Current_File(N)),1)
		Call SMG$Put_Line(Big_Display(N),
	1		Big_Rec(:Name_Length(N)))
	Else
		If (Name_Length(N) .GT. 17) then
                        B_Width(N) = Name_Length(N)
			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),
	1			Lid(N),2,5,,RU_Mask)

			Do 310 K = 4, (Bottom_File(N)-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))
		Call SMG$Set_Cursor_Abs
	1		(%Ref(Big_Display(N)),%Ref(K),%Ref(1))
		Call SMG$Put_Line(Big_Display(N),String(:SLen))
310			Continue

			GoTo 300   ! To fill it.
		End If
	End If

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
C					????? Next Line OK?????
CX		Current_File(K) = Current_File(K) +1

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

		If (Have_Big_Display(N)) then
		Call SMG$Insert_Line (%Ref(Big_Display(K)),
	1		%Ref(Current_File(N)),' ',SMG$M_DOWN)
		End If
	    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)
	Max_Left = MAX (1, Highest_Level-3)
	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)
  

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

	KK = Name_Length(Dis_Col)
	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. 23) then  !  RePaint

			Call SMG$Repaint_Screen (Pasteboard_ID)
			GoTo 200


		Else If (Terminator .EQ. 256) 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)
				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)
				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
                                GoTo 9000   ! Exit
			End If


C			CR or either Select Key:
		Else If ((Terminator .EQ. SMG$k_trm_cr) .OR.
	1		 (Terminator .EQ.          273) .OR.
	2		 (Terminator .EQ.          314))  then

			Call Make_Change_Name
			GoTo 9999
		End If


C		Exit without selecting
9000	Continue


9999    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)
		Call SMG$Change_Rendition (Level_Display(Dis_Col),
	1		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)
		Call SMG$Change_Rendition (Level_Display(Dis_Col),
	1		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)
		Call SMG$Change_Rendition (Level_Display(Dis_Col),
	1		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. 2) 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)
		Call SMG$Change_Rendition (Level_Display(Dis_Col),
	1		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)

	If (Have_Big_Display(Dis_Col)) then  ! Re-Do this name

		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 If

	Our_Level = Dis_Col

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

C			Now, check for an "overflow" file.
		If (Have_Big_Display(Dis_Col)) then 

			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 If
	End Do 

	Do N = 1, Our_Level
		Change (ChgLen+1:) = '.'//DirName(N)
		ChgLen = ChgLen + Name_Length(N) +1
	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


