 Rem File: IO8X.bas - DndeditC.bas DndeditI.bas
 Rem $Include: 'dndedit.inc'

 Rem Added to DndeditC on 06/15/2022
 Rem Added to DndeditI on 06/20/2022

Sub MultiLineScreenEdit
 On Local Error Goto Error.Trap47
 For Temp2=1 To Max.Lines
    Edit.Data(Temp2)=Rtrim$(Edit.Data(Temp2))
 Next
 Max.File = Max.Lines
 Line.Number = 1
 Inserting=True
 Call ANSI(4,37,44)
 Call ANSI(2,2,67)
 Strng="Insert     "
 Call Scrn(Strng)
 Call ANSI(4,37,40)
 Do While Lost.Carrier=False
    Call ANSI(2,Xcoor,Ycoor)
    IF Inserting = -3 THEN
       Locate Xcoor, Ycoor, 1, 1, 7
    ELSE
       IF Inserting = -1 THEN
          Locate Xcoor,Ycoor,1,3,7
       Else
          Locate Xcoor,Ycoor,1,7,7
       Endif
    Endif
    TempX$=Nul
    Do While TempX$=Nul
       If Lost.Carrier Then
          Exit Do
       Endif
       Call Read.Keyboard(TempX$)

       ' check mouse button pressed
       Call MouseDriver(3)
       If Mouse.Button Then ' left
          TempX$=Chr$(0)+Chr$(82) ' insert
       Endif
       If Mouse.Button2 Then ' right
          TempX$=Chr$(27) ' escape
       Endif
       If Mouse.Button3 Then ' middle
          Call Terminate.Program(True)
          End
       Endif
    Loop
    Select Case Len(TempX$)
    Case 1
       Select Case TempX$
       Case Chr$(13)
          If Line.Number<19 Then
             ' check overstrike
             If Inserting = 0 Then
                Line.Number = Line.Number + 1
                Column = 1
                Xcoor = Xcoor + 1
                Ycoor = 1
                Call ANSI(2,Xcoor,Ycoor)
             Else
                ' enter always extends array
                IF Max.Lines + 1 > Max.File THEN
                   Max.File = Max.Lines + 1
                   Redim Preserve Edit.Data(1 To Max.File) AS STRING
                END IF
                IF Max.Lines < Max.File THEN
                   ' above
                   IF Column + Ycoor - 1 = 1 THEN
                      FOR Temp1 = Max.Lines TO Line.Number STEP -1
                         Edit.Data(Temp1 + 1) = Edit.Data(Temp1)
                      NEXT
                      Edit.Data(Line.Number) = Nul
                      Max.Lines = Max.Lines + 1
                      Line.Number = Line.Number + 1
                      IF Xcoor < 19 THEN
                         Xcoor = Xcoor + 1
                      END IF
                   ELSE
                      ' below
                      IF Column + Ycoor - 1 > LEN(Edit.Data(Line.Number)) THEN
                         Line.Number = Line.Number + 1 ' below
                         FOR Temp1 = Max.Lines TO Line.Number STEP -1
                            Edit.Data(Temp1 + 1) = Edit.Data(Temp1)
                         NEXT
                         Edit.Data(Line.Number) = Nul
                         Max.Lines = Max.Lines + 1
                         IF Xcoor < 19 THEN
                            Xcoor = Xcoor + 1
                         END IF
                      ELSE
                         ' split line
                         FOR Temp1 = Max.Lines TO Line.Number + 1 STEP -1
                            Edit.Data(Temp1 + 1) = Edit.Data(Temp1)
                         NEXT
                         T$ = Edit.Data(Line.Number)
                         U$ = MID$(T$, Column + Ycoor - 1)
                         T$ = LEFT$(T$, Column + Ycoor - 2)
                         Edit.Data(Line.Number) = T$
                         Line.Number = Line.Number + 1 ' below
                         Edit.Data(Line.Number) = U$
                         Max.Lines = Max.Lines + 1
                         IF Xcoor < 19 THEN
                            Xcoor = Xcoor + 1
                         END IF
                      END IF
                   END IF
                END IF
                ' enter always moves to 1,1
                Column = 1
                Ycoor = 1
                GOSUB DisplayScreen
             Endif
          Endif
       Case Chr$(8) ' backspace
          Q = Column + Ycoor - 1
          IF Line.Number <= 1 AND Q <= 1 THEN ' no backspace at 1,1
             Eat$ = Nul
          ELSE
             ' remove current line
             IF Edit.Data(Line.Number) = Nul THEN
                ' pack array
                FOR Temp1 = Line.Number TO Max.Lines - 1
                   Edit.Data(Temp1) = Edit.Data(Temp1 + 1)
                NEXT
                IF Xcoor > 1 THEN
                   Xcoor = Xcoor - 1
                END IF
                Line.Number = Line.Number - 1
                Max.Lines = Max.Lines - 1
                ' position at eol
                End.Line = LEN(Edit.Data(Line.Number))
                IF End.Line >= 80 THEN
                   Column = End.Line - 78
                   Ycoor = End.Line - Column + 2
                ELSE
                   Ycoor = End.Line - Column + 2
                END IF
                GOSUB DisplayScreen
             ELSE
                ' concatenate previous line
                IF Column + Ycoor - 1 <= 1 THEN
                   IF Line.Number > 1 THEN
                      IF Line.Number <= Max.Lines THEN
                         Var=0
                         If Edit.Data(Line.Number-1)=Nul Then
                            If Ycoor=1 Then
                               Var=-1
                            Endif
                         Endif
                         ' position at eol
                         If Var=0 Then
                            End.Line = LEN(Edit.Data(Line.Number-1))
                         Endif
                         Edit.Data(Line.Number - 1) = Edit.Data(Line.Number - 1) + Edit.Data(Line.Number)
                         FOR Temp1 = Line.Number TO Max.Lines - 1
                            Edit.Data(Temp1) = Edit.Data(Temp1 + 1)
                         NEXT
                         If Xcoor > 1 Then
                            Xcoor = Xcoor - 1
                         Endif
                         Line.Number = Line.Number - 1
                         Max.Lines = Max.Lines - 1
                         Column = 1
                         Ycoor = 1
                         ' position at eol
                         If Var=0 Then
                            IF End.Line >= 80 THEN
                               Column = End.Line - 78
                               Ycoor = End.Line - Column + 2
                            ELSE
                               Ycoor = End.Line - Column + 2
                            END IF
                         Endif
                         GOSUB DisplayScreen
                      END IF
                   END IF
                ELSE
                   ' backspace 1 character
                   IF Column + Ycoor - 2 > False THEN
                      ' check overstrike
                      If Inserting = 0 Then
                         If Ycoor > 1 Then
                            Ycoor = Ycoor - 1
                            Call ANSI(2,Xcoor,Ycoor)
                         Endif
                      Else
                         T$ = Edit.Data(Line.Number)
                         T$ = LEFT$(T$, Column + Ycoor - 3) + MID$(T$, Column + Ycoor - 1)
                         Edit.Data(Line.Number) = T$
                         ' move cursor 1 left
                         IF Ycoor > 1 THEN
                            Ycoor = Ycoor - 1
                            GOSUB DisplayScreen
                         ELSE
                            IF Column > 1 THEN
                               Column = Column - 1
                               GOSUB DisplayScreen
                            END IF
                         END IF
                      Endif
                   END IF
                END IF
             END IF
          END IF
       Case Chr$(9) ' tab
          If Inserting=-3 Then ' insert tab
             If Ycoor-Column+8<=Line.Length Then
                Edit.Data(Line.Number)= _
                Left$(Edit.Data(Line.Number),Ycoor-Column)+Space$(8)+ _
                Mid$(Edit.Data(Line.Number),Ycoor-Column+1)

                Edit.Data(Line.Number)= _
                Left$(Edit.Data(Line.Number),Line.Length)

                Strng=Mid$(Edit.Data(Line.Number),Ycoor-Column+1)
                Call ANSI(2,Xcoor,Ycoor)
                Call Scrn(Strng)
                Ycoor=Ycoor+1
             Endif
          Else
             ' advance tab
             If Ycoor-Column+8<=Len(Edit.Data(Line.Number)) Then
                Ycoor=Ycoor+8
             Else
                Ycoor=Len(Edit.Data(Line.Number))+Column
             Endif
          Endif
       Case Chr$(27) ' exit
          Inserting=-2
          Exit Do
       Case Else ' insert character
          If Asc(TempX$)>=32 And Asc(TempX$)<=127 Then ' char
             If Ycoor-Column+1>Line.Length Then
                If Max.Lines>1 Then
                   If Line.Number<19 Then
                      Line.Number=Line.Number+1
                      Xcoor=Xcoor+1
                      Ycoor=Column
                   Endif
                Endif
             Else
                ' check overstrike
                If Inserting=False Then
                   If Ycoor-Column+1>Len(Edit.Data(Line.Number)) Then
                      Edit.Data(Line.Number)=Edit.Data(Line.Number)+TempX$
                   Else
                      Mid$(Edit.Data(Line.Number),Ycoor-Column+1,1)=TempX$
                   Endif
                   Strng=TempX$
                   Call ANSI(2,Xcoor,Ycoor)
                   Call Scrn(Strng)
                   Ycoor=Ycoor+1
                Else
                   Edit.Data(Line.Number)= _
                   Left$(Edit.Data(Line.Number),Ycoor-Column)+TempX$+ _
                   Mid$(Edit.Data(Line.Number),Ycoor-Column+1)
                   Edit.Data(Line.Number)= _
                   Left$(Edit.Data(Line.Number),Line.Length)
                   Strng=Mid$(Edit.Data(Line.Number),Ycoor-Column+1)
                   Call ANSI(2,Xcoor,Ycoor)
                   Call Scrn(Strng)
                   Ycoor=Ycoor+1
                Endif
             Endif
          Endif
       End Select
    Case 2
       Temp=Asc(Mid$(TempX$,2,1))
       Select Case Temp
       Case 0 'ctrl-break
          Inserting=-2
          Exit Do
       Case 82 ' insert
          Select Case Inserting
          Case 0
             Inserting=-1
          Case -1
             Inserting=-3
          Case -3
             Inserting=0
          End Select
          Call ANSI(4,37,44)
          Call ANSI(2,2,67)
          Strng=Space$(11)
          If Inserting=False Then
             Strng="Overstrike "
          Else
             If Inserting=-1 Then
                Strng="Insert     "
             Else
                Strng="BlockInsert"
             Endif
          Endif
          Call Scrn(Strng)
          Call ANSI(4,37,40)
       Case 83, 147 ' delete/control-delete
          Q = Column + Ycoor - 1
          ' no delete at 1,1
          IF (Line.Number <= 1 AND Q < 1) OR Max.Lines < 1 THEN
             Eat$ = Nul
          ELSE
             ' remove line
             IF Edit.Data(Line.Number) = Nul THEN
                IF Line.Number = 1 AND Max.Lines = 1 THEN ' 1,1
                   Eat$ = Nul
                ELSE
                   ' pack array
                   FOR Temp1 = Line.Number TO Max.Lines - 1
                      Edit.Data(Temp1) = Edit.Data(Temp1 + 1)
                   NEXT
                   IF Line.Number = Max.Lines THEN
                      Line.Number = Line.Number - 1
                      IF Xcoor > 1 THEN
                         Xcoor = Xcoor - 1
                      END IF
                   END IF
                   Max.Lines = Max.Lines - 1
                   Column = 1
                   Ycoor = 1
                   GOSUB DisplayScreen
                END IF
             ELSE
                ' delete line
                IF LEN(Edit.Data(Line.Number))<1 THEN
                   Edit.Data(Line.Number) = Nul
                   GOSUB DisplayScreen
                ELSE
                   ' concatenate line
                   IF Column + Ycoor - 1 > LEN(Edit.Data(Line.Number)) THEN
                      If Line.Number + 1 <= Max.Lines Then
                         T$ = Edit.Data(Line.Number)
                         T$ = T$ + Edit.Data(Line.Number + 1)
                         Edit.Data(Line.Number) = T$
                         ' pack array
                         FOR Temp1 = Line.Number + 1 TO Max.Lines - 1
                            Edit.Data(Temp1) = Edit.Data(Temp1 + 1)
                         NEXT
                         Max.Lines = Max.Lines - 1
                         GOSUB DisplaySCreen
                      Endif
                   ELSE
                      ' delete character
                      T$ = Edit.Data(Line.Number)
                      T$ = LEFT$(T$, Column + Ycoor - 2) + MID$(T$, Column + Ycoor)
                      Edit.Data(Line.Number) = T$
                      GOSUB DisplayScreen
                   END IF
                END IF
             END IF
          END IF
       Case 71 ' home
          Ycoor=Column
       Case 79 ' end
          Ycoor=Len(Edit.Data(Line.Number))+Column
       Case 15 ' shift-tab
          If Ycoor-Column-8>False Then
             Ycoor=Ycoor-8
          Else
             Ycoor=Column
          Endif
       Case 77, 157 ' right/alt-right
          If Ycoor-Column+1<=Len(Edit.Data(Line.Number)) Then
             Ycoor=Ycoor+1
          Endif
       Case 75, 155 ' left/alt-left
          If Ycoor-Column>False Then
             Ycoor=Ycoor-1
          Endif
       Case 72, 141, 152 ' up/ctrl-up/alt-up
          If Line.Number>1 Then
             Xcoor=Xcoor-1
             Line.Number=Line.Number-1
             If Ycoor-Column+1>Len(Edit.Data(Line.Number)) Then
                Ycoor=Len(Edit.Data(Line.Number))+Column
             Endif
          Endif
       Case 80, 145, 160 ' down/ctrl-dn/alt-dn
          If Line.Number<19 Then
             Xcoor=Xcoor+1
             Line.Number=Line.Number+1
             If Ycoor-Column+1>Len(Edit.Data(Line.Number)) Then
                Ycoor=Len(Edit.Data(Line.Number))+Column
             Endif
          Endif
       Case 73, 132, 119 ' pageup/ctrl-pageup/control-home
          Xcoor=Row
          Line.Number=1
          Ycoor=Column
       Case 81, 118, 117 ' pagedn/ctrl-pagedn/control-end
          Temp2=19
          Do While Lost.Carrier=False
             Xcoor=Row+Temp2-1
             Line.Number=Temp2
             If Line.Number=1 Then
                Exit Do
             Endif
             If Len(Edit.Data(Line.Number))=False Then
                Temp2=Temp2-1
             Else
                Exit Do
             Endif
          Loop
          Ycoor=Len(Edit.Data(Line.Number))+Column
       Case 116 ' control-right
          Do While Lost.Carrier=False
             For Temp2=Ycoor-Column+1 To Len(Edit.Data(Line.Number))-1
                If Mid$(Edit.Data(Line.Number),Temp2,1)=" " Then
                   If Mid$(Edit.Data(Line.Number),Temp2+1,1)<>" " Then
                      Ycoor=Temp2+Column
                      Exit Do
                   Endif
                Endif
             Next
             If Ycoor-Column+1<=Len(Edit.Data(Line.Number)) Then
                Ycoor=Len(Edit.Data(Line.Number))+Column
             Else
                If Max.Lines>1 And Line.Number<19 Then
                   Line.Number=Line.Number+1
                   Xcoor=Xcoor+1
                   Ycoor=Column
                Endif
             Endif
             Exit Do
          Loop
       Case 115 ' control-left
          Do While Lost.Carrier=False
             For Temp2=Ycoor-Column-1 To 1 Step -1
                If Mid$(Edit.Data(Line.Number),Temp2,1)=" " Then
                   Ycoor=Temp2+Column
                   Exit Do
                Endif
             Next
             If Ycoor=Column Then
                If Max.Lines>1 And Line.Number>1 Then
                   Line.Number=Line.Number-1
                   Xcoor=Xcoor-1
                   Ycoor=Len(Edit.Data(Line.Number))+Column
                Endif
             Else
                Ycoor=Column
             Endif
             Exit Do
          Loop
       End Select
    End Select
 Loop
 Call ANSI(4,37,44)
 Call ANSI(2,2,67)
 Strng=Space$(11)
 Call Scrn(Strng)
 Locate ,,1,7,7
 Exit Sub
DisplayScreen:
 Call ANSI(4,37,40)
 For Var=1 To 19
    If Var<=Max.Lines Then
       Call ANSI(2,Var+3,1)
       Strng=Rtrim$(Edit.Data(Var))
       Strng=Left$(Strng,80)
       Strng=Strng+Space$(80-Len(Strng))
       Call Scrn(Strng)
    Else
       Call ANSI(2,Var+3,1)
       Strng=Space$(80)
       Call Scrn(Strng)
    Endif
 Next
 Call ANSI(2,Xcoor,Ycoor)
 Return
Error.Resume47:
 Strng="Error"+Str$(Err)+"."
 Call ErrorMessage
 Exit Sub
Error.Trap47:
 Resume Error.Resume47
End Sub
