C*****************************************************************************
C
C	OPERATIONS FOR -
C      	DELETE FILES AND/OR DIRECTORIES
C
C   (Version 6.x)            August, 1986
C	Dale E. Coy
C	Los Alamos National Laboratory
C	(505) 667-3270
C
C*****************************************************************************
C-------------------------------------------------------------------C
C DELETE_ONE_FILE
C Delete a single file at Current_Line (if possible).
C    NOTE: It is the responsibility of the calling routine to make
C	sure that the resultant is "displayable".  However, this
C	routine will make sure that current_line points to something.
C	In practice, the conditions that require adjustment of 
C	TopLine are almost pathological.
C Didit (Logical) is returned if the file was deleted.
C-------------------------------------------------------------------C

        Subroutine Delete_One_File (Didit)
        Implicit Integer*4 (A - Z)
        Logical Didit	
        Character*5 Numbers	
        Character*8 Nblks	
        Include 'Common.Dat'
        Character*(Files_Display_Width) FileName
C-------------------------------------------------------------------C

        Call GetName(Current_Line, FileName, Itsa_Dir)

	If (Itsa_Dir) then
		If ((All_Delete).OR.(Remainder_Delete)) Call Make_Bright
		Exit_Com = 
	1	'SET PROT=(SY:RWED,OW:RWED,GR:RWED,WO:RWED) '//FileName

		Call Do_NoShow_DCL

C		NOTE: If we can write to the file, this will work.
C		Otherwise, it shouldn't change the protection at all,
C		and (because of security features) it doesn't write
C		an error message to the screen.
	End If

C	     	  DELETE ONE FILE
        Didit = Lib$Delete_File (%Descr(FileName))
	If (Didit) then
		Call SMG$Begin_Pasteboard_Update (Pasteboard_ID)

		If (Have_More) then    ! Update Number of Blocks
			Call SMG$Read_From_Display (Attributes_Display,
	1			Numbers,,%Ref(Current_Line))
			If (Numbers(1:1) .NE. '*') then
				Read (Numbers,401) File_Siz
				Total_Blks = Total_Blks - File_Siz
				Write(Nblks,402) Total_Blks
402	Format (I8)
			Call SMG$Put_Chars (Blocks_Display,Nblks,1,1)
			End If
		End If

		Call SMG$Delete_Line (Files_Display,Current_Line)
		Call SMG$Delete_Line (Attributes_Display,Current_Line)

C		Where should we "point", for safety?

		If (Itsa_Dir) then  ! We deleted a Directory file..
			NumDirs = NumDirs - 1
			Write(Numbers,401) NumDirs
401	Format (I5)
			Call SMG$Put_Chars (Files_Display,Numbers,
	1			3,26,,SMG$M_UnderLine)
			First_File = MAX(First_File-1,0)
			Last_File  = MAX(Last_File-1,-1)
			If (NumFiles .GT. 0) FileLine = FileLine - 1

			If (NumDirs .GT. 0) then
				Last_Dir = Last_Dir - 1
				Current_Line = 
	1				MIN(Current_Line, Last_Dir)
			Else
				First_Dir = 0
				Last_Dir  = -1
				If (NumFiles .GT. 0) then
					Current_Line = First_File  ! 6
					FirstUsed    = First_File
				Else
					FirstUsed    = 7
					Current_Line = 7
				End If
			End If
		Else         ! We deleted a regular file...
			NumFiles = NumFiles - 1
			Write(Numbers,401) NumFiles
			Call SMG$Put_Chars (Files_Display,Numbers,
	1			FileLine,26,,SMG$M_UnderLine)
			If (NumFiles .GT. 0) then
				Last_File = Last_File - 1
				Current_Line = 
	1				MIN(Current_Line, Last_File)
			Else
				First_File = 0
				Last_File  = -1
				If (NumDirs .GT. 0) then
					Current_Line = Last_Dir
				Else
					FirstUsed    = 7
					Current_Line = 7
				End If
			End If
		End If


C		Trim the display back to minimum.

		LastLine = LastLine - 1
		Current_Display_Length = LastLine

	    	Call SMG$Change_Virtual_Display
	1		(Files_Display,Current_Display_Length,
	2		 %Ref(Current_Files_Width))

    		Call SMG$Change_Virtual_Display
	1		(Attributes_Display,Current_Display_Length,
	2		 Attributes_Display_Width)

		Call SMG$End_Pasteboard_Update (Pasteboard_ID)

	Else
    	     Call Mess_Wait(' Can''t delete '//FileName)
	     If ((All_Delete).OR.(Remainder_Delete)) Call Make_Dull

	End If	
	Return
	End

C-------------------------------------------------------------------C
C DELETE ONE DIRECTORY 
C	Always prompts for All/Confirm/Quit.  
C-------------------------------------------------------------------C
        Subroutine Delete_One_Directory (Didit)
        Implicit Integer*4 (A - Z)
        Logical Didit	
        Character*1 Answer
        Include 'Common.Dat'
        Character*(Files_Display_Width) FileName
C-------------------------------------------------------------------C

	Didit            = .FALSE.

	If ((WildCard_Length.GT.1) .OR. (WildCard(1:1).NE.'*')) then
		Files_Only_Delete = .TRUE.
	Else
		Files_Only_Delete = .FALSE.
	End If

	Remainder_Delete = .FALSE.
	All_Delete =       .FALSE.
	Quit_Delete =      .FALSE.
	Confirm_Delete =   .FALSE.

	Call Paste_Delete_Windows

	If (Files_Only_Delete) then
		Call SMG$Put_Chars (Delete_Operation_Display, 
	1		'e   Wildcard Files in .DIR Tree?  ',1,7)
	Else
		Call SMG$Put_Chars (Delete_Operation_Display, 
	1		'e   Directory Tree?               ',1,7)
	End If
	Call SMG$Change_Rendition (Delete_Operation_Display,
	1	1,11,1,14,SMG$M_Bold)

        Call GetName(Current_Line, FileName, Itsa_Dir)
	Call SMG$Put_Chars (Delete_File_Display,FileName,
	1	1,%Ref(Name_Pos))
	Call SMG$Paste_Virtual_Display (Delete_File_Display,
	1	Pasteboard_ID,4,1)

100	Call Delete_Answer1

	If (All_Delete) then
		Call SMG$Begin_Pasteboard_Update (Pasteboard_ID)

	    If (Files_Only_Delete) then
		Call SMG$Put_Chars (Delete_Operation_Display, 
	1		'ing Wildcard Files in .DIR Tree   ',1,7)
		Call SMG$Change_Rendition (Delete_Operation_Display,
	1		1,11,1,14,SMG$M_Bold)
	    Else
		Call SMG$Put_Chars (Delete_Operation_Display, 
	1		'ing Directory Tree                ',1,7)
	     	Call SMG$Change_Rendition (Delete_Operation_Display,
	1		1,11,1,9,SMG$M_Bold)
	    End If


		Call SMG$UnPaste_Virtual_Display (Delete_Menu_Underlay_Display,
	1    		Pasteboard_ID)

		Call SMG$UnPaste_Virtual_Display (Delete_Menu1_Display,
	1		Pasteboard_ID)

		Call SMG$UnPaste_Virtual_Display (Delete_Menu2_Display,
	1		Pasteboard_ID)

		Call SMG$UnPaste_Virtual_Display (Delete_File_Display,
	1		Pasteboard_ID)

		Call SMG$UnPaste_Virtual_Display 
	1		(Delete_Op_Underlay_Display, Pasteboard_ID)

		Call SMG$End_Pasteboard_Update (Pasteboard_ID)


	Else If (Confirm_Delete) then
        
		If (Files_Only_Delete) then
			Call SMG$Put_Chars (Delete_Operation_Display, 
	1			'ing Confirmed Wildcard Files      ',1,7)
		Else
			Call SMG$Put_Chars (Delete_Operation_Display, 
	1			'ing Confirmed Directory Tree      ',1,7)
		End If

		Call SMG$Change_Rendition (Delete_Operation_Display,
	1		1,11,1,7,SMG$M_Bold)

		Call SMG$UnPaste_Virtual_Display (Delete_Menu1_Display,
	1		Pasteboard_ID)

	Else
		GoTo 600    ! Quit
	End If

C		WE GET HERE ONLY IF WE'RE DOING CONFIRM_DELETES
C		OR ALL_DELETES

	Save_Current = Current_Line

      	Call Delete_Directory_Tree (Didit)

	If (Didit) then
		If (NumDirs .GT. 0) then
			Current_Line = MIN(Save_Current, Last_Dir)
		Else If (NumFiles .GT. 0) then
			Current_Line = First_File
		Else
			Current_Line = FirstUsed
		End If
	Else
		Current_Line = Save_Current
	End If



600	Return
	End

C-------------------------------------------------------------------C
C Delete tagged file(s)
C-------------------------------------------------------------------C
        Subroutine Delete_Tagged_Files
        Implicit Integer*4 (A - Z)
        Logical Didit	
        Character*1 Answer
        Include 'Common.Dat'
C-------------------------------------------------------------------C

	Remainder_Delete = .FALSE.
	All_Delete =       .FALSE.
	Quit_Delete =      .FALSE.
	Confirm_Delete =   .FALSE.

	Call Paste_Delete_Windows

	Call SMG$Put_Chars (Delete_Operation_Display, 
	1	'e   Tagged Regular Files?         ',1,7)

100	Call Delete_Answer1

	If (All_Delete) then
		Call SMG$Begin_Pasteboard_Update (Pasteboard_ID)

		Call SMG$UnPaste_Virtual_Display (Delete_Op_Underlay_Display,
	1		Pasteboard_ID)
		Call SMG$Put_Chars (Delete_Operation_Display, 
	1		'ing All Tagged Regular Files      ',1,7)
		Call SMG$Change_Rendition (Delete_Operation_Display,
	1		1,11,1,3,SMG$M_Bold)

		Call SMG$UnPaste_Virtual_Display 
	1		(Delete_Menu_Underlay_Display,Pasteboard_ID)

		Call SMG$UnPaste_Virtual_Display (Delete_Menu1_Display,
	1		Pasteboard_ID)

		Call SMG$UnPaste_Virtual_Display (Delete_Menu2_Display,
	1		Pasteboard_ID)

		Call SMG$End_Pasteboard_Update (Pasteboard_ID)

	Else If (Confirm_Delete) then
		Call SMG$Put_Chars (Delete_Operation_Display, 
	1		'ing Confirmed Regular Files       ',1,7)
		Call SMG$Change_Rendition (Delete_Operation_Display,
	1		1,11,1,7,SMG$M_Bold)
		Call SMG$UnPaste_Virtual_Display (Delete_Menu1_Display,
	1		Pasteboard_ID)
		Call SMG$Paste_Virtual_Display (Delete_File_Display,
	1		Pasteboard_ID,4,1)

	Else
		Return    ! Quit
   	End If

	Save_Current = Current_Line


	If (Confirm_Delete) GoTo 200

C		TAGGED FILES ARE DELETED IN THE "REVERSE" DIRECTION
C		FOR EFFICIENCY OF SCREEN PAINTING (MOVEMENT OF LINES
C		IS LESS AS FILES ARE DELETED), IF ALL_DELETE IS USED.  

  	Do 150 I = IncluCount,1,-1

	Line = IncluLines(I)

	If ((Line .GE. First_File) .AND. 
	1   (Line .LE. Last_File))  then
		Current_Line = Line

	      	Call Delete_One_File (Didit)

		If (Didit) then
			Do J = I, IncluCount - 1
				IncluLines(J) = IncluLines(J + 1) -1
			End Do
			IncluCount = MAX(IncluCount - 1,0)
		End If
	Else
		GoTo 500    ! Through with regular file deletes
        End If

150	CONTINUE
	GoTo 500     ! Through with deletes



C		THIS SECTION FOR CONFIRM_DELETES (DONE IN FORWARD DIRECTION).

200	I = 1            !Do 1, IncluCount
250	Line = IncluLines(I)                                      

	If ((Line .GE. First_File) .AND. 
	1   (Line .LE. Last_File))  then
		Current_Line = Line
 		If (Confirm_Delete) then
			Call Confirm_Delete_File (Didit)
			If (Quit_Delete) GoTo 500
			If (Remainder_Delete) then
			     	All_Delete = .TRUE.
				Confirm_Delete = .FALSE.
C-----------------------------------------------------------------------
		Call SMG$Begin_Pasteboard_Update (Pasteboard_ID)

		Call SMG$Put_Chars (Delete_Operation_Display, 
	1		'ing Remaining Tagged Regular Files',1,7)
		Call SMG$Change_Rendition (Delete_Operation_Display,
	1		1,11,1,9,SMG$M_Bold)

		Call SMG$UnPaste_Virtual_Display 
	1		(Delete_Menu_Underlay_Display,Pasteboard_ID)

		Call SMG$UnPaste_Virtual_Display (Delete_Menu2_Display,
	1		Pasteboard_ID)

		Call SMG$UnPaste_Virtual_Display (Delete_File_Display,
	1		Pasteboard_ID)

		Call SMG$End_Pasteboard_Update (Pasteboard_ID)
C-----------------------------------------------------------------------
                        End If

		Else
		      	Call Delete_One_File (Didit)
		End If

		If (Didit) then
			Do J = I, IncluCount - 1
				IncluLines(J) = IncluLines(J + 1) -1
			End Do
			IncluCount = MAX(IncluCount - 1,0)
		Else
			I = I + 1
		End If
	Else
		I = I + 1
        End If
	If (I .LE. IncluCount) GoTo 250      ! to try the next entry.


C		NOW FINISH UP
500	If (.NOT.ReLoad) then
		If (NumFiles .GT. 0) then
			Current_Line = MIN(Save_Current, Last_File)
			Current_Line = MAX(Current_Line, First_File)
			Current_Line = MAX(Current_Line, TopLine)
  		Else
			If (NumDirs .GT. 0) then
				Current_Line = Last_Dir
			Else
				Current_Line = FirstUsed
			End If
		End If
	Else
		Current_Line = FirstUsed
	End If


	Call SMG$UnPaste_Virtual_Display (Delete_File_Display,
	1		Pasteboard_ID)
	Call SMG$Put_Line (Delete_Operation_Display, ' Delete',0)

	Return
	End                  

C-------------------------------------------------------------------C
C Delete tagged directory(s)
C	Note: Each top-level directory will be handled with it's own
C		menu.
C-------------------------------------------------------------------C
        Subroutine Delete_Tagged_Directories
        Implicit Integer*4 (A - Z)
        Logical Didit
        Character*1 Answer
        Include 'Common.Dat'
	Integer*2 XncluLines (Max_Tags)
	Integer*4 XncluCount
C-------------------------------------------------------------------C

	XncluCount = IncluCount
	Do K = 1, XncluCount
		XncluLines(K) = IncluLines(K)
	End Do


	Save_Current = Current_Line

C		DIRECTORIES ARE DELETED IN THE "FORWARD" DIRECTION.
	I = 1            !Do 1, XncluCount
150	Line = XncluLines(I)

	If ((Line .GE. First_Dir) .AND. 
	1   (Line .LE. Last_Dir))  then
		Current_Line = Line
		All_Delete       = .FALSE.
		Remainder_Delete = .FALSE.
		Confirm_Delete   = .FALSE.
		Quit_Delete      = .FALSE.

		Call Delete_One_Directory (Didit) 

		If ((Didit) .OR. (Files_Only_Delete)) then
			Do J = I, XncluCount - 1
				XncluLines(J) = XncluLines(J + 1) -1
			End Do
	     		XncluCount = MAX(XncluCount - 1,0)
		Else
			I = I + 1
		End If
	Else
		I = I + 1
        End If
	If (I .LE. XncluCount) GoTo 150      ! to try the next entry.


500	If (XncluCount .GT. 0) then
		Do K = 1, XncluCount
			Current_Line = XncluLines(K)
			Call Include
		End Do
	End If

	If (.NOT.ReLoad) then
		If (NumFiles .GT. 0) then
			Current_Line = MIN(Save_Current, Last_File)
			If (Current_Line .LT. First_File) then
				If (NumDirs .GT. 0) then
				  Current_Line = 
	1				MIN (Current_Line, Last_Dir)
				  Current_Line = 
	1				MAX (Current_Line, First_Dir)
				Else
				  Current_Line = First_File
				End If	
			End If
 		Else
			If (NumDirs .GT. 0) then
				  Current_Line = 
	1				MIN (Current_Line, Last_Dir)
				  Current_Line = 
	1				MAX (Current_Line, First_Dir)
			Else
				  Current_Line = FirstUsed
			End If
		End If
	Else
		Current_Line = FirstUsed
	End If

	Call SMG$UnPaste_Virtual_Display (Delete_File_Display,
	1		Pasteboard_ID)
	Call SMG$Put_Line (Delete_Operation_Display, ' Delete',0)



	Return
	End

C-------------------------------------------------------------------C
C Confirm and (possibly) Delete File (Regular file or Directory file)
C-------------------------------------------------------------------C
        Subroutine Confirm_Delete_File (Didit)
        Implicit Integer*4 (A - Z)
        Logical Didit	
        Character*1 Answer
        Include 'Common.Dat'
        Character*(Files_Display_Width) FileName
C-------------------------------------------------------------------C

        Call GetName(Current_Line, FileName, Itsa_Dir)

100	Call Delete_Answer2 (FileName, Answer)

	If ((Answer .EQ. 'Y').OR.(Remainder_Delete))    then
		Call Delete_One_File (Didit)

	Else If (Answer .EQ. 'N') then
		Didit = .FALSE.
		
		
	Else If (Quit_Delete) then
		Didit = .FALSE.

	Else ! Should never happen.
		GoTo 100
	End If


500	Return
	End

C-------------------------------------------------------------------C
C DELETE_ONE_FILE
C Delete a single file or directory at Current_Line (if possible).
C    NOTE: It is the responsibility of the calling routine to make
C	sure that the resultant is "displayable".  However, this
C	routine will make sure that current_line points to something.
C	In practice, the conditions that require adjustment of 
C	TopLine are almost pathological.
C Didit (Logical) is returned if the file was deleted.
C THIS ROUTINE IS ONLY USED BY THE F6 (Delete Line) FUNCTION.  IT
C	SHOULD NOT BE CALLED BY ANOTHER SUBROUTINE.  
C	This routine updates tags, if required.
C-------------------------------------------------------------------C

        Subroutine Delete_This_File
        Implicit Integer*4 (A - Z)
        Logical Didit	
        Character*1 Answer
        Include 'Common.Dat'
        Character*(Files_Display_Width) FileName
C-------------------------------------------------------------------C


	If (InCluCount .LT. 1) then		! No Tags

		Call DM_Delete

	Else
C		DANGER !! We are faking out include stuff here

C	IncluCount_Save = InCluCount
C	InCluCount = 0
	Call SMG$Read_From_Display (Files_Display,FileName
	1		,,Current_Line)
        If (FileName(Name_Pos:Name_Pos) .EQ. ' ') GoTo 900


		If ((Current_Line .GE. First_File) .AND.
	1	    (Current_Line .LE. Last_File )) then
		        Call GetName(Current_Line, FileName, Itsa_Dir)
		        J = MAX( Lib$MatchC (' ',FileName), 1)
	 	        Answer = 'N'
	                Call Mess_Get1Char
	1			(' Do you really want to delete '//
	2		        FileName(1:J)//'? (Y/N) [N] ',Answer)
	                If ((Answer .NE. 'Y') .AND. 
	1		    (Answer .NE. 'y'))      Return
C			     	  DELETE ONE FILE
			Call Delete_One_File (Didit)
		Else
C		       DELETE ONE DIRECTORY

			Call Delete_One_Directory (Didit)
		    	Call UnPaste_Delete_Windows
		End If

C		InCluCount = InCluCount_Save


	    If (Didit) then
	        If (FileName(Flag_Pos:Flag_Pos) .NE. Tag_Char) then
C				Didn't delete a tagged file
		   If ( IncluLines(IncluCount) .GT. Current_Line) then
			Do J = 1, IncluCount 
				If (IncluLines(J) .GT. Current_Line)
	1			IncluLines(J) = IncluLines(J) -1
			End Do
		   End If

		Else			! Deleted a tagged line
		    Do J = 1, IncluCount-1 
			If (IncluLines(J) .GE. Current_Line)
	1		IncluLines(J) = IncluLines(J+1) -1
		    End Do
		    IncluCount = MAX(IncluCount - 1,0)

		End If

	    End If

	End If

900	Return
	End

