 Rem File: Editedit for Dndbbs Version v5.0a Release r2.0
 Rem $Include: 'edit.inc'

 On Error Goto ErrMain0
 Stack 4096
 Call Stdin(Var)
 If Chained=False Then
    Call Open.Arrays
    Call Get.Config
    Call Increase.Files
    Call Make.FileNames
    Call Open.Files
    Call Reset.Cursor
    Call Detect.Share
    Call Save.Screen2(0)
    Call Passwrd10(Var)
    If Var=False Then
       Call Terminate.Program
       End
    Endif
 Endif
 If Chained Then
    Gosub Get.Password
    If TempQ=0 Then
       Goto MainExit0
    Endif
 Endif
 Call Edit.Edit
 Call Terminate.Program2
 End
Get.Password:
 TempQ=False
 Var$=Ucase$(Rtrim$(Config3(46)))
 If Var$=Nul Then
    Strng="Function not available."
    Call IO.O
    Return
 Endif
 Graphics.Off=True
 Strng="Password? "
 Line.Length=20
 Hidden=True
 Call IO.I
 Hidden=False
 Graphics.Off=False
 If Len(Out2) Then
    Out2=Ucase$(Out2)
    Var2$=Nul
    Call Cryptograph(Out2)
    For Var=1 To Len(Out2)
       Var2=Asc(Mid$(Out2,Var,1))
       Var2$=Var2$+Right$("0"+Hex$(Var2),2)
    Next
    If Var2$=Var$ Then
       TempQ=True
       Return
    Endif
 Endif
 Strng="Illegal password attempt!"
 Call IO.O
 Return
MainExit0:
 Call Terminate.Program2
 End
ErrMain0:
 Resume MainExit0

Sub Edit.Edit
 On Local Error Goto ErrResume1
 ' start editor
 No.Echo=False
 Carriage.Input=False
 Carriage.Return=False
 Call Edit.Status.Line
 ' open data files
 FileName=DND.Path+"editedit.dat" ' template file
 Close #TempFile1
 If Dir$(FileName)=Nul Then
    Strng="Filename "+FileName+" not found."
    Call IO.O
    Strng="  Run Dndutil /W3"
    Call IO.O
    Exit Sub
 Endif
 Call Open.Data.Files

 ' start editor editor menu
 Do While Lost.Carrier=0
    Graphics.Off=False
    Strng="Editor Edit utility v"+Left$(Version$,4)+" menu:"
    Call IO.O
    Graphics.Off=True
    Strng="[A]dd"
    Call IO.O
    Strng="[E]dit"
    Call IO.O
    Strng="[H]elp"
    Call IO.O
    Strng="[L]ist"
    Call iO.O
    Strng="[R]emove"
    Call IO.O
    Strng="[U]ser"
    Call IO.O
    Graphics.Off=False
    No.Input.Out="q"
    Strng="Enter option(q to quit)? "
    Call IO.I
    Select Case Ucase$(Out2)
    Case "H"
       Var$=DND.Path+"editedit.hlp"
       If Dir$(Var$)<>Nul Then
          Call Out.File(Var$)
          Call Open.Data.Files
       Endif
    Case "L"
       Var$=DND.Path+"editedit.txt"
       If Dir$(Var$)<>Nul Then
          Call Out.File(Var$)
          Call Open.Data.Files
       Endif
    Case "A"
       EditCommands=String$(MaxTemplate,"1")
'       Mid$(EditCommands,506,1)="0" ' UserEdit [B]password
       Var!=Lof(TemplateFile)/MaxTemplate+1!
       Call Write.Record(TemplateFile,Var!)
       Strng="Record added."
       Call IO.O
    Case "E"
       Var!=Lof(TemplateFile)/MaxTemplate
       If Var!=0! Then
          Strng="No edit records exist."
          Call IO.O
       Else
          Strng="Enter edit record(1-"+Mid$(Str$(Var!),2)+")? "
          Call IO.I
          Rec!=Int(Val(Out2)+.5)
          If Rec!>=1! And Rec!<=Var! Then
             Call Read.Record(TemplateFile,Rec!)
             Gosub EditFileBlocks
             Call Write.Record(TemplateFile,Rec!)
          Else
             Strng="Edit record out of range."
             Call IO.O
          Endif
       Endif
    Case "R"
       Call Find.User(0)
       If Temp5! Then
          Call Search.Mess.File(Temp5!,VarX)
          If VarX Then
             Strng="User is online."
             Call IO.O
          Else
             UserRecord2.EditList=0!
             Call Write.Record(UserFile2,Temp5!)
             Out3=Lcase$(Rtrim$(Out3))
             Mid$(Out3,1,1)=Ucase$(Mid$(Out3,1,1))
             Strng="Edit record deleted from "+Out3+"."
             Call IO.O
          Endif
       Endif
    Case "U"
       Var!=Lof(TemplateFile)/MaxTemplate
       If Var!=0! Then
          Strng="No edit records exist."
          Call IO.O
       Else
          If Var!=1! Then
             Strng="No user edit records exist."
             Call IO.O
          Else
             Strng="Enter edit record(2-"+Mid$(Str$(Var!),2)+")? "
             Call IO.I
             Rec!=Int(Val(Out2)+.5)
             If Rec!>=2! And Rec!<=Var! Then
                Call Find.User(0)
                If Temp5! Then
                   Call Search.Mess.File(Temp5!,VarX)
                   If VarX Then
                      Strng="User is online."
                      Call IO.O
                   Else
                      UserRecord2.EditList=Rec!
                      Call Write.Record(UserFile2,Temp5!)
                      Out3=Lcase$(Rtrim$(Out3))
                      Mid$(Out3,1,1)=Ucase$(Mid$(Out3,1,1))
                      Strng="Edit record added to "+Out3+"."
                      Call IO.O
                   Endif
                Endif
             Else
                Strng="Edit record out of range."
                Call IO.O
             Endif
          Endif
       Endif
    Case "Q"
       Exit Do
    End Select
 Loop
 Exit Sub

 ' start editor edit menu
EditFileBlocks:
 ' find block 0
 Var=0
 Gosub Find.Block
 Current.Block=0
 Do While Lost.Carrier=0
    If File.Position=-1 Then ' error finding block
       Exit Do
    Endif
    If Current.Block=0 Then
       Graphics.Off=False
       Strng="Editor Edit utility v"+Left$(Version$,4)+" menu:"
       Call IO.O
    Endif
    Graphics.Off=True
    Gosub Display.Block
    Graphics.Off=False
    If Current.Block=0 Then
       Strng="Enter (t)oggle, (j)ump, (q)uit? "
    Else
       Strng="Enter (t)oggle, (j)ump, (b)ack, (q)uit? "
    Endif
    No.Input.Out="q"
    Call IO.I
    V$=Out2
    Select Case Lcase$(V$)
    Case "t" ' toggle
       Strng="Enter menu selection? "
       Call IO.I
       Toggle$=Out2
       Gosub Toggle.Item
    Case "j" ' jump
       Strng="Enter menu selection? "
       Call IO.I
       Jump$=Out2
       Gosub Jump.Block
    Case "b" ' back
       If Current.Block=0 Then
          Strng="Nothing to backup to."
          Call IO.O
       Else
          Gosub Back.Block
       Endif
    Case "q" ' quit
       Exit Do
    End Select
 Loop
 Return

' find block Var
Find.Block:
 File.Position=0
 Var$="##"+Mid$(Str$(Var),2)+"."
 Do
    File.Position=File.Position+1
    If File.Position>Lof(TempFile1)/80 Then
       Strng="Block "+Var$+" not found."
       Call IO.O
       If Debug.Mode Then
          Strng=" Positions searched:"+Str$(File.Position)
          Strng=Strng+" of"+Str$(Lof(TempFile1)/80)
          Strng=Strng+" file"+Str$(TempFile1)
          Call IO.O
       Endif
       File.Position=-1
       Return
    Endif
    Call Read.Message.Record(TempFile1,File.Position)
    Var2$=Rtrim$(BufferRecord.Buffer)
    If Var2$=Var$ Then
       Exit Do
    Endif
 Loop
 Return

' jump to block in Jump$ selection
Jump.Block:
 Position=File.Position
 Do
    Position=Position+1
    If Position>Lof(TempFile1)/80 Then
       Return
    Endif
    Call Read.Message.Record(TempFile1,Position)
    If Left$(BufferRecord.Buffer,2)="##" Then
       Exit Do
    Endif
    If Left$(BufferRecord.Buffer,1)=";" Then
       Eat$ = Nul
    Else
       If Left$(BufferRecord.Buffer,1)=":" Then
          Eat$ = Nul
       Else
          If Left$(BufferRecord.Buffer,1)="#" Then
             ' parse #macros
             EditLine$=Rtrim$(BufferRecord.Buffer)
             Do
                Var=Instr(EditLine$,"#") ' #xxx[s] Var=1
                If Var Then
                   EditLine$=Mid$(EditLine$,Var+1) ' xxx[s]
                   Var=Instr(EditLine$,"[") ' xxx[s] Var=4
                   If Var Then
                      Var$=Left$(EditLine$,Var-1) ' xxx
                      Var2$=Mid$(EditLine$,Var) ' [s]...
                      Var2$=Left$(Var2$,Instr(Var2$,"]")) ' [s]
                      EditLine$=Mid$(EditLine$,Var+1) ' s]...
                      ' parse 1.:
                      If Right$(Var$,2)=".:" Then ' jump
                         Var$=Left$(Var$,Len(Var$)-2) ' 1
                         Var=Int(Val(Var$)+.5) ' 1
                         If Lcase$(Var2$)="["+Lcase$(Jump$)+"]" Then
                            Gosub Find.Block
                            If File.Position<>-1 Then
                               Current.Block=Var
                               Return
                            Endif
                         Endif
                      Endif
                   Else
                      Exit Do
                   Endif
                Else
                   Exit Do
                Endif
             Loop
          Endif
       Endif
    Endif
 Loop
 Return

' backup a block from Current.Block
Back.Block:
 Position=0
 ' look for #xxx. which called current block
 Do
    Position=Position+1
    If Position>Lof(TempFile1)/80 Then
       Return
    Endif
    Call Read.Message.Record(TempFile1,Position)
    If Left$(BufferRecord.Buffer,2)="##" Then
       ' store block
       Var$=Rtrim$(BufferRecord.Buffer) ' ##xxx.
       Var$=Mid$(Var$,3) ' xxx.
       Var$=Left$(Var$,Len(Var$)-1) ' xxx
       Temp.Block=Int(Val(Var$)+.5)
    Else
       If Left$(BufferRecord.Buffer,1)=";" Then
          Eat$ = Nul
       Else
          If Left$(BufferRecord.Buffer,1)=":" Then
             Eat$ = Nul
          Else
             If Left$(BufferRecord.Buffer,1)="#" Then
                ' parse #macros
                EditLine$=Rtrim$(BufferRecord.Buffer)
                Do
                   Var=Instr(EditLine$,"#") ' #xxx.?[s]
                   If Var Then
                      Var$=Mid$(EditLine$,Var+1) ' xxx.?[s]...
                      Var=Instr(Var$,".") ' xxx.?[s]
                      Var$=Left$(Var$,Var-1) ' xxx
                      Var=Instr(EditLine$,"]") ' #xxx[s]...
                      EditLine$=Mid$(EditLine$,Var+1) ' s]...
                      If Int(Val(Var$)+.5)=Current.Block Then ' jumped from
                         ' jump to Temp.Block
                         Var=Temp.Block
                         Gosub Find.Block
                         If File.Position<>-1 Then
                            Current.Block=Var
                            Return
                         Endif
                      Endif
                   Else
                      Exit Do
                   Endif
                Loop
             Endif
          Endif
       Endif
    Endif
 Loop
 Return

' toggle item in Toggle$
Toggle.Item:
 Position=File.Position
 Toggle$="["+Toggle$+"]"
 Toggle$=Lcase$(Toggle$)
 ' look for #xxx.?[s] in current block
 Do
    Position=Position+1
    If Position>Lof(TempFile1)/80 Then
       Return
    Endif
    Call Read.Message.Record(TempFile1,Position)
    If Left$(BufferRecord.Buffer,2)="##" Then
       Return
    Else
       If Left$(BufferRecord.Buffer,1)=";" Then
          Eat$ = Nul
       Else
          If Left$(BufferRecord.Buffer,1)=":" Then
             Eat$ = Nul
          Else
             If Left$(BufferRecord.Buffer,1)="#" Then
                ' parse #macros
                EditLine$=Rtrim$(BufferRecord.Buffer)
                Do
                   Var=Instr(EditLine$,"#") ' #xxx.?[s]...
                   If Var Then
                      T$=Mid$(EditLine$,Var+1) ' xxx.?[s]...
                      Var=Instr(T$,".")
                      T$=Left$(T$,Var-1) ' xxx
                      Var=Instr(EditLine$,"[") ' xxx.?[s]...
                      Var$=Mid$(EditLine$,Var) ' [s]...
                      Var=Instr(Var$,"]")
                      Var$=Left$(Var$,Var) ' [s]
                      Var=Instr(EditLine$,"]") ' #xxx[s]...
                      EditLine$=Mid$(EditLine$,Var+1) ' s]...
                      If Lcase$(Var$)=Toggle$ Then
                         ' toggle selection
                         Var=Int(Val(T$)+.5)
                         If Mid$(EditCommands,Var,1)="1" Then
                            Mid$(EditCommands,Var,1)="0"
                         Else
                            Mid$(EditCommands,Var,1)="1"
                         Endif
                         Return
                      Endif
                   Else
                      Exit Do
                   Endif
                Loop
             Endif
          Endif
       Endif
    Endif
 Loop
 Return

' display menu items in current block
Display.Block:
 Position=File.Position
 Do
    Position=Position+1
    If Position>Lof(TempFile1)/80 Then
       Return
    Endif
    Call Read.Message.Record(TempFile1,Position)
    If Left$(BufferRecord.Buffer,2)="##" Then
       Exit Do
    Endif
    If Left$(BufferRecord.Buffer,1)=";" Then
       Eat$ = Nul
    Else
       If Left$(BufferRecord.Buffer,1)=":" Then
          Strng=Mid$(Rtrim$(BufferRecord.Buffer),2)
          Call IO.O
       Else
          If Left$(BufferRecord.Buffer,1)="#" Then
             ' parse out #macros
             EditLine$=Rtrim$(BufferRecord.Buffer)
             Do
                Var=Instr(EditLine$,"#") ' #xxx.?[s]
                If Var Then
                   Var$=Mid$(EditLine$,Var+1) ' xxx.?[s]...
                   T$=Left$(Var$,Instr(Var$,".")-1) ' xxx
                   Var=Instr(EditLine$,"#") ' #xxx.?[s]
                   Var2=Instr(Var+1,EditLine$,"[") ' #xxx.?[s]
                   T=Int(Val(T$)+.5)
                   If Mid$(EditCommands,T,1)="0" Then ' disabled
                      Mid$(EditLine$,Var2,1)="{"
                      Var3=Instr(Var2+1,EditLine$,"]")
                      Mid$(EditLine$,Var3,1)="}"
                   Endif
                   EditLine$=Left$(EditLine$,Var-1)+Mid$(EditLine$,Var2) ' [s]
                Else
                   Exit Do
                Endif
             Loop
             ' hilight {x} with red
             V$=EditLine$
             V1=0
             V2=Len(V$)
             If Instr(V$,"{")=0 Then
                Strng=V$
                Call IO.O
             Else
                Do
                   V1=V1+1
                   If V1>V2 Then
                      Exit Do
                   Endif
                   V1$=Mid$(V$,V1,1)
                   If V1$="{" Then
                      CALL Modem.ANSI(4, 31, 12)
                      CALL ScreenANSI(4, 31, 12)
                      Strng="{"
                      Carriage.Return=-1
                      Graphics.On=True
                      Call IO.O
                      Do
                         V1=V1+1
                         If V1>V2 Then
                            Exit Do
                         Endif
                         V1$=Mid$(V$,V1,1)
                         If V1$="}" Then
                            Strng="}"
                            Carriage.Return=-1
                            Call IO.O
                            Exit Do
                         Endif
                         Strng=Mid$(V$,V1,1)
                         Carriage.Return=-1
                         Call IO.O
                      Loop
                      CALL Modem.ANSI(4, 37, 15)
                      CALL ScreenANSI(4, 37, 15)
                      Graphics.On=False
                   Else
                      Carriage.Return=-1
                      Strng=V1$
                      Call IO.O
                   Endif
                Loop
                Call IO.O
             Endif
          Endif
       Endif
    Endif
 Loop
 Return
ErrExit1:
 Exit Sub
ErrResume1:
 Resume ErrExit1
End Sub

Sub Search.Mess.File(Var1!,Var2)
 On Local Error Goto ErrMain41
 Var2=False
 For TempA=False To MaxNodes
    Call Read.Message.Record(MessWorkFile1,TempA+1)
    Var$=MessWorkRecord1.UserName
    Select Case Rtrim$(Lcase$(Var$))
    Case "login", "logoff", "relogin"
       TempB=False
    Case Deleted$, Offline$
       TempB=False
    Case Else
       TempB=True
    End Select
    If TempB Then
       If MessWorkRecord1.UserIndex=Var1! Then
          Var2=True
          Exit For
       Endif
    Endif
 Next
MainExit41:
 Exit Sub
ErrMain41:
 Resume MainExit41
End Sub

Sub Terminate.Program2
 On Local Error Goto ErrMain42
 Call Clear.Status.Line
 If Chained Then
    Chain DND.Path+"DNDBBS.EXE"
 Endif
 Color 15,0
 Call ScreenANSI(1,37,7)
 Cls
 Call ScreenANSI(3,0,0)
 Call Save.Screen2(-1)
 Locate Max.Row,1,1
 If Local.Mode Then
    Color 15,0
    Print
    Print "Now exiting the Dndbbs Menu Editor.."
    Color 7,0
 Endif
 Call Decrease.Files
MainExit42:
 End
ErrMain42:
 Resume MainExit42
End Sub

Sub Open.Data.Files
 On Local Error Goto ErrMain43
 FileName=DND.Path+"editedit.dat" ' template file
 Close #TempFile1
 Open FileName For Random Shared As #TempFile1 Len=80
 If Debug.Mode Then
    Strng=Filename+" opened length="+Str$(Lof(TempFile1)/80)
    Call IO.O
 Endif
 FileName=DND.Path+"editdata.dat" ' restriction datafile
 Close #TemplateFile
 Open FileName For Random Shared As #TemplateFile Len=MaxTemplate
 If Debug.Mode Then
    Strng=Filename+" opened length="+Str$(Lof(TemplateFile)/MaxTemplate)
    Call IO.O
 Endif
 Exit Sub
MainExit43:
 Strng="Filename "+FileName+" not found."
 Call IO.O
 Call Terminate.Program2
 End
ErrMain43:
 Resume MainExit43
End Sub

