Attribute VB_Name = "ntScriptEngine"
Option Explicit

Private Type ntVarType
  Value As String
  vName As String
  vSub As String
  Script As String
End Type

Private Type ntSubType
  vName As String
  vStart As Long
  vEnd As Long
  Para As String
  Script As String
End Type

Private Type ntScriptType
  vName As String
  vStart As Long
  vEnd As Long
End Type

Private Type ntScriptTimer
  vSub As String
  vInterval As Long
  vTimerID As Integer
  vRep As Boolean
  vScript As String
  vUserID As Integer
End Type

Private Type ntRegedEventType
  EventID As String
  Script As String
  ConnID As Integer
End Type

Private Type ntArrayType
  Value As String
  vName As String
  Script As String
  indexkey As String
End Type

Public ntScript As String
Public ntScriptEnabled As Boolean
Public ntScriptTimeOut As Long
Public ntScriptErrorDone As Boolean

Dim ScriptTimer(1 To 32) As ntScriptTimer
Dim ExitErr As Boolean
Dim VarList() As ntVarType
Dim SubIndex() As ntSubType
Dim ScriptIndex() As ntScriptType
Dim RegedEvents() As ntRegedEventType
Dim ScriptArrays() As ntArrayType
Dim SkipEvent As Boolean
Dim CurrentSub As String
Dim CurrentScript As String
Dim ScriptTimeOut As Long
Dim ScriptLoopOut As Long
Dim ScriptSaveMode As Integer
Dim EvPos As Long
Dim CurrentRetVal As String
Dim LastRetVal As String
Dim CallIsRunning As Boolean

Dim Position As Long
Dim Token As String
Dim Argument As String
Dim ErrorString As String

Public Sub ListTriggers(Obj As Object)
  If Obj Is Nothing Then Exit Sub
  If Obj.ListCount > 0 Then Exit Sub
  With Obj
    .Additem "Serv_Quit(Nick, QuitMsg, ConnID)"
    .Additem "Serv_Watch(Nick, Mode, ConnID)"
    .Additem "Serv_DccRequest(Nick, Data, DCCType, FrameID, ConnID)"
    .Additem "Serv_Connect(ConnID)"
    .Additem "Serv_Connected(ConnID)"
    .Additem "Serv_Closed(ConnID)"
    .Additem "Serv_Ready(ConnID)"
    .Additem "Serv_Ping(ConnID, Data)"
    .Additem "Serv_Invited(Channel, Nick, ConnID)"
    .Additem "Serv_NickChange(OldNick, NewNick, ConnID)"
    .Additem "Serv_Query(Text, Nick, FrameID, ConnID)"
    .Additem "Serv_Notice(Text, Nick, Receiver, ConnID)"
    .Additem "Serv_Mode(Nick, ModeStr, ParaStr, ConnID)"
    .Additem "Serv_Action(Text, Nick, FrameID, ConnID)"
    .Additem "Serv_RegedEvent(EventID, Sender, ConnID, Text, RawData)"
    .Additem "Serv_CTCP(CtcpType, Text, Nick, ConnID)"
    
    .Additem "Chan_Join(Nick, Channel, FrameID, ConnID)"
    .Additem "Chan_Part(Nick, Channel, FrameID, ConnID)"
    .Additem "Chan_Kick(Receiver, Nick, KickMsg, Channel, FrameID)"
    .Additem "Chan_Mode(Nick, ModeStr, ParaStr, FrameID, ConnID)"
    .Additem "Chan_TopicChange(OldTopic, NewTopic, Channel, FrameID, ConnID)"
    .Additem "Chan_Quit(Nick, Channel, QuitMsg, FrameID, ConnID)"
    .Additem "Chan_Msg(Text, Nick, Channel, FrameID, ConnID)"
    .Additem "Chan_NickChange(OldNick, NewNick, FrameID, ConnID)"
    
    .Additem "SendMsg(Text, Channel, FrameID, ConnID)"
    .Additem "SendQuery(Text, Receiver, FrameID, ConnID)"
    .Additem "SendDCCMsg(Text, Receiver FrameID, ConnID)"
    .Additem "SendNotice(Text, Receiver, FrameID, ConnID)"
    .Additem "SendCommand(Text, FrameID)"
    .Additem "FrameChange(OldFrameID, NewFrameID)"
    .Additem "FrameClosed(FrameID)"
    .Additem "RecvDCCMsg(Text, Nick, FrameID, ConnID)"
    .Additem "Unload()"
    .Additem "Load()"
    .Additem "AppLoad()"
    .Additem "AppUnload(UnloadMode)"
    .Additem "PluginEvent(Command, Para1, Para2, Para3)"
    .Additem "TimerEvent(TimerID)"
    .Additem "RecvDDECmd(Data, Topic)"
    .Additem "ScriptLinkClicked(Text, Trigger, Button)"
    .Additem "KeyShortcut(KeyCode, Shift)"
    .Additem "DCCServAccept(LocalPort, RemoteIP, ConnID)"
    
    .Additem "Dcc_Created(PeerNick, FileName, FileSize, ConnName, DccID)"
    .Additem "Dcc_Connected(DccID)"
    .Additem "Dcc_Error(Error, DccID)"
    .Additem "Dcc_Complet(DccID)"
  End With
End Sub

Private Sub RegNewEvent(EventID As String, ConnID As Integer, ScriptName As String)
  Dim I As Integer
  
  For I = 0 To UBound(RegedEvents)
    If RegedEvents(I).EventID = UCase(EventID) And RegedEvents(I).Script = ScriptName And RegedEvents(I).ConnID = ConnID Then Exit For
  Next
  If I > UBound(RegedEvents) Then
    For I = 0 To UBound(RegedEvents)
      If Len(RegedEvents(I).EventID) = 0 Then Exit For
    Next
    If I > UBound(RegedEvents) Then ReDim Preserve RegedEvents(I)
    RegedEvents(I).EventID = UCase(EventID)
    RegedEvents(I).Script = ScriptName
    RegedEvents(I).ConnID = ConnID
  End If
End Sub

Public Sub RemRegedEvent(EventID As String, ConnID As Integer, ScriptName As String)
  Dim I As Integer
  If ntScriptEnabled Then
    For I = 0 To UBound(RegedEvents)
      If (RegedEvents(I).EventID = UCase(EventID) Or Len(EventID) = 0) And _
      (RegedEvents(I).Script = ScriptName Or Len(ScriptName) = 0) And _
      RegedEvents(I).ConnID = ConnID Then
        RegedEvents(I).EventID = ""
        RegedEvents(I).Script = ""
        RegedEvents(I).ConnID = 0
      End If
    Next
  End If
End Sub

Public Function PhraseRegedEvent(EventID As String, SenderName As String, ConnID As Integer, Text As String, RawData As String) As Boolean
  Dim I As Integer
  
  PhraseRegedEvent = True
  If ntScriptEnabled Then
    For I = 0 To UBound(RegedEvents)
      If RegedEvents(I).ConnID = ConnID Or RegedEvents(I).ConnID = 0 Then
        If RegedEvents(I).EventID = EventID Then
          PhraseRegedEvent = ntScript_Call("Serv_RegedEvent", EventID, SenderName, CStr(ConnID), Text, RawData, False, RegedEvents(I).Script, True)
          Exit For
        End If
      End If
    Next
  End If
End Function

Private Sub SetArrayValue(ScriptName As String, ArrayName As String, ArrayKey As String, Value As String)
  Dim I As Integer
  Dim ScName As String
  Dim ArrName As String
  Dim ArrKey As String
  
  ScName = LCase(ScriptName)
  ArrName = LCase(ArrayName)
  ArrKey = LCase(ArrayKey)
  
  For I = 0 To UBound(ScriptArrays)
    If ScriptArrays(I).Script = ScName And ScriptArrays(I).vName = ArrName And ScriptArrays(I).indexkey = ArrKey Then Exit For
  Next
  If I > UBound(ScriptArrays) Then
    For I = 0 To UBound(ScriptArrays)
      If Len(ScriptArrays(I).vName) = 0 Then Exit For
    Next
    If I > UBound(ScriptArrays) Then ReDim Preserve ScriptArrays(I)
  End If
  ScriptArrays(I).Script = ScName
  ScriptArrays(I).vName = ArrName
  ScriptArrays(I).indexkey = ArrKey
  ScriptArrays(I).Value = Value
End Sub

Private Function IsNtArray(Name As String) As Boolean
  Dim ScriptName As String
  Dim ArrName As String
  Dim I As Integer
  
  ScriptName = LCase(CurrentScript)
  ArrName = LCase(Name)
  For I = 0 To UBound(ScriptArrays)
    If ScriptArrays(I).vName = ArrName And ScriptArrays(I).Script = ScriptName Then
      IsNtArray = True
      Exit Function
    End If
  Next
End Function

Private Function GetArrayValue(ScriptName As String, ArrayName As String, ArrayKey As String) As String
  Dim I As Integer
  Dim ScName As String
  Dim ArrName As String
  Dim ArrKey As String
  
  ScName = LCase(ScriptName)
  ArrName = LCase(ArrayName)
  ArrKey = LCase(ArrayKey)
  
  For I = 0 To UBound(ScriptArrays)
    If ScriptArrays(I).Script = ScName And ScriptArrays(I).vName = ArrName And ScriptArrays(I).indexkey = ArrKey Then
      GetArrayValue = ScriptArrays(I).Value
      Exit For
    End If
  Next
End Function

Public Function ScrReadFile(FileName As String, pStart As Long, pLen As Long) As String
  Dim Frif As Integer
  Dim I As Long
  Dim I2 As Long
  Dim Data As String
  Dim FileNameInt As String

  FileNameInt = FileName
  If Left(FileNameInt, 2) <> "\\" And Mid(FileNameInt, 2, 2) <> ":\" Then FileNameInt = App.Path + "\" + FileNameInt
  I2 = pLen
  I = pStart
  If I < 1 Then I = 1
  Frif = FreeFile
  Open FileNameInt For Binary As #Frif
    If I2 = 0 Or I2 + I - 1 > LOF(Frif) Then I2 = LOF(Frif) - I + 1
    If I2 > &HFFFFF Then I2 = &HFFFFF + 1
    If I2 < 0 Then I2 = 0
    Data = Space(I2)
    Get Frif, I, Data
  Close #Frif
  ScrReadFile = Data
End Function

Public Sub ScrWriteFile(FileName As String, Data As String, pStart As Long)
  Dim Frif As Integer
  Dim FileNameInt As String
  Dim I As Long
  
  FileNameInt = FileName
  If Left(FileNameInt, 2) <> "\\" And Mid(FileNameInt, 2, 2) <> ":\" Then FileNameInt = App.Path + "\" + FileNameInt
  I = pStart
  If I < 1 Then I = 1
  Frif = FreeFile
  Open FileNameInt For Binary As #Frif
    Put Frif, I, Data
  Close #Frif
End Sub

Public Sub ScrPrintFile(FileName As String, Data As String, ByVal Overwrite As Boolean)
  Dim Frif As Integer
  Dim FileNameInt As String
  Dim I As Long
  
  FileNameInt = FileName
  If Left(FileNameInt, 2) <> "\\" And Mid(FileNameInt, 2, 2) <> ":\" Then FileNameInt = App.Path + "\" + FileNameInt
  
  Frif = FreeFile
  If Overwrite Then
    Open FileNameInt For Output As #Frif
  Else
    Open FileNameInt For Append As #Frif
  End If
  Print #Frif, Data
  Close #Frif
End Sub

Public Sub SaveScriptValue(VarName As String, VarValue As String)
  Dim Frif As Integer
  Dim I As Long
  
  On Error Resume Next
  Frif = FreeFile
  If ScriptSaveMode < 2 And Dir(UserPath + "ScriptValues.ini") <> "" Then Kill UserPath + "ScriptValues.ini"
  Open UserPath + "ScriptValues.ini" For Binary As #Frif
    I = LOF(Frif)
    Put Frif, I + 1, "<" + VarName + "," + CStr(Len(VarValue)) + ">" + vbNewLine + VarValue + vbNewLine + vbNewLine
  Close #Frif
  ScriptSaveMode = 2
  If Err > 0 Then MsgBox Err.Description, vbCritical, "ntScript"
End Sub

Public Function LoadScriptValue(VarName As String) As String
  Dim Frif As Integer
  Dim DAT As String
  Dim I As Long
  Dim I2 As Long
  Dim I3 As Long
  
  On Error Resume Next
  Frif = FreeFile
  Open UserPath + "ScriptValues.ini" For Binary As #Frif
    I = 2
    Do Until I > LOF(Frif)
      DAT = Space(64)
      Get Frif, I, DAT
      I2 = InStr(1, DAT, ",")
      If I2 = 0 Then Exit Do
      I3 = InStr(I2, DAT, ">")
      If I3 = 0 Then Exit Do
      If LCase(Left(DAT, I2 - 1)) = LCase(VarName) Then
        If I3 - I2 - 2 > 5 Then Exit Do
        DAT = Space(Val(Mid(DAT, I2 + 1, I3 - I2 - 1)))
        Get Frif, I3 + 2 + I, DAT
        LoadScriptValue = DAT
        Exit Do
      Else
        If I3 - I2 - 2 > 5 Then Exit Do
        I = I + Val(Mid(DAT, I2 + 1, I3 - I2 - 1)) + I3 + 7
      End If
    Loop
  Close #Frif
  ScriptSaveMode = 1
  If Err > 0 Then MsgBox Err.Description, vbCritical, "ntScript"
End Function

Private Function ConnByID(ByVal ID As Integer, Optional IsIRCConn As Boolean) As Object
  Dim I As Integer
  
  For I = 1 To IRCconns.Count
    If IRCconns(I).ConnID = ID Then
      Set ConnByID = IRCconns(I)
      IsIRCConn = True
      Exit Function
    End If
  Next
  For I = 1 To DCCconns.Count
    If DCCconns(I).ConnID = ID Then Set ConnByID = DCCconns(I): Exit Function
  Next
End Function

Public Function FrameByID(ByVal FrameID As Integer) As ChatFrame
  Dim I As Integer

  For I = 1 To ChatFrames.Count
    If ChatFrames(I).FrameID = FrameID Then Exit For
  Next
  If I > ChatFrames.Count Then
    Set FrameByID = Nothing
  Else
    'If ChatFrames(I).FrameType <> cfScript Then Set FrameByID = ChatFrames(I)
    Set FrameByID = ChatFrames(I)
  End If
End Function

Private Function FrameCaptionByID(ByVal FrameID As Integer) As String
  Dim CFrame As ChatFrame
  
  Set CFrame = FrameByID(FrameID)
  If Not CFrame Is Nothing Then FrameCaptionByID = CFrame.Caption
End Function

Private Function GetStringPart(Data As String, Index As Long, Optional DiffStr As String) As String
  Dim I As Long
  Dim I2 As Long
  Dim Zae As Long
  Dim inDiffStr As String
  
  If Len(DiffStr) Then inDiffStr = DiffStr Else inDiffStr = " "
  I = 1 - Len(inDiffStr)
  Do Until (Zae >= Index And Index > 0) Or (Index = 0 And Zae = 1)
    Zae = Zae + 1
    I2 = I
    I = InStr(I + Len(inDiffStr), Data, inDiffStr)
    If I = 0 Then I = Len(Data) + 1: Exit Do
  Loop
  GetStringPart = Mid(Data, I2 + Len(inDiffStr), I - I2 - Len(inDiffStr))
End Function

'Public Function Replace(Data As String, AltString As String, NewString As String) As String
'  Dim I As Long
'  Dim I2 As Long
'
'  I2 = 1
'  Do
'    I = InStr(I + 1, Data, AltString, vbTextCompare)
'    If I = 0 Then
'      Replace = Replace + Mid(Data, I2, Len(Data) - I2 + 1)
'      Exit Do
'    End If
'    Replace = Replace + Mid(Data, I2, I - I2) + NewString
'    I2 = I + Len(AltString)
'  Loop Until I = Len(Data)
'End Function

Private Function GetConnByName(ConnName As String) As Integer
  Dim I As Integer

  For I = 1 To ChatFrames.Count
    If LCase(ChatFrames(I).Caption) = LCase(ConnName) And _
    ChatFrames(I).FrameType = cfStatus And ChatFrames(I).ConnTyp = 0 Then
      GetConnByName = ChatFrames(I).IrcConn.ConnID
      Exit For
    End If
  Next
End Function

Private Function GetConnID(ByVal FrameID As Integer) As Integer
  Dim I As Integer

  For I = 1 To ChatFrames.Count
    If ChatFrames(I).FrameID = FrameID Then Exit For
  Next
  If Not I > ChatFrames.Count Then
    Select Case ChatFrames(I).ConnTyp
      Case 0
        GetConnID = ChatFrames(I).IrcConn.ConnID
      Case 2
        GetConnID = ChatFrames(I).DCCConn.ConnID
    End Select
  End If
End Function

Private Sub SimulateCommand(Data As String, ByVal ID As Integer)
  Dim I As Integer
  
  For I = 1 To IRCconns.Count
    If IRCconns(I).ConnID = ID Then
      IRCconns(I).PraseCommandFromString Data
      Exit For
    End If
  Next
End Sub

Private Function GetFrameID(ByVal ConnID As Integer, Optional Caption As String, Optional NoFrontFrame As Boolean) As Integer
  Dim I As Integer

  For I = 1 To ChatFrames.Count
    Select Case ChatFrames(I).ConnTyp
      Case 0
        If ChatFrames(I).IrcConn.ConnID = ConnID And LCase(ChatFrames(I).Caption) = LCase(Caption) Then Exit For
      Case 2
        If ChatFrames(I).DCCConn.ConnID = ConnID And LCase(ChatFrames(I).Caption) = LCase(Caption) Then Exit For
    End Select
  Next
  If I > ChatFrames.Count And NoFrontFrame = False Then
    For I = 1 To ChatFrames.Count
      Select Case ChatFrames(I).ConnTyp
        Case 0
          If ChatFrames(I).IrcConn.ConnID = ConnID And FrontCFrame Is ChatFrames(I) Then Exit For
        Case 2
          If ChatFrames(I).DCCConn.ConnID = ConnID And FrontCFrame Is ChatFrames(I) Then Exit For
      End Select
    Next
  End If
  If I > ChatFrames.Count Then
    For I = 1 To ChatFrames.Count
      Select Case ChatFrames(I).ConnTyp
        Case 0
          If ChatFrames(I).IrcConn.ConnID = ConnID And ChatFrames(I).FrameType = cfStatus Then Exit For
        Case 2
          If ChatFrames(I).DCCConn.ConnID = ConnID And ChatFrames(I).FrameType = cfStatus Then Exit For
      End Select
    Next
  End If
  If Not I > ChatFrames.Count Then GetFrameID = ChatFrames(I).FrameID
End Function

Private Function GetConnData(ByVal ID As Integer, ByVal ValID As Integer) As String
  Dim sConn As Object
  Dim IrcConn As Boolean
  
  Set sConn = ConnByID(ID, IrcConn)
  If Not sConn Is Nothing Then
    Select Case ValID
      Case 0
        If sConn.State > 1 Then GetConnData = GetLocalHost(sConn.GetSeocket.SocketHandle)
      Case 1
        If sConn.State > 1 Then GetConnData = GetLocalPort(sConn.GetSeocket.SocketHandle)
      Case 2
        If sConn.State > 1 Then GetConnData = GetPeerHostByAddr(sConn.GetSeocket.SocketHandle)
      Case 3
        If sConn.State > 1 Then GetConnData = sConn.GetSeocket.RemotePort
      Case 4
        If ID < 500 Then
          GetConnData = sConn.Caption
        Else
          GetConnData = sConn.User
        End If
      Case 5
        GetConnData = sConn.Nick
      Case 6
        GetConnData = sConn.State
    End Select
    If IrcConn Then
      Select Case ValID
        Case 7
          GetConnData = sConn.RealServer
        Case 8
          GetConnData = sConn.UserID
        Case 9
          GetConnData = sConn.Realname
        Case 10
          GetConnData = sConn.NickPass
        Case 11
          GetConnData = sConn.ServerPass
      End Select
    End If
  End If
End Function

Private Function GetFrontID() As Integer
  Dim sConn As Integer
  Select Case FrontCFrame.ConnTyp
    Case 0
      sConn = FrontCFrame.IrcConn.ConnID
    Case 2
      sConn = FrontCFrame.DCCConn.ConnID
  End Select
  GetFrontID = sConn
End Function

Private Sub SendOutText(Text As String, ByVal ConnID As Integer, Optional mAn As String)
  Dim sCon As Object
  
  Set sCon = ConnByID(ConnID)
  If Not sCon Is Nothing Then sCon.SendLine "privmsg " + mAn + " :" + Text
End Sub

Private Sub SendOutData(Data As String, ConnID As Integer, NoLineBreak As Boolean)
  Dim sConn As Object
  
  Set sConn = ConnByID(ConnID)
  If sConn Is Nothing Then Exit Sub
  sConn.SendLine Data, NoLineBreak
End Sub

Private Sub TextOut(Text As String, Optional FrameID As Integer, Optional ColorStr As String, Optional NoNewLine As Boolean, Optional TriggerStr As String, Optional Trigger As Long)
  Dim CFrame As ChatFrame
  Dim I As Integer
  Dim outColor As Long
  Dim IfTrigger As Long
  
  If Len(TriggerStr) And Trigger = 0 Then IfTrigger = 9 Else IfTrigger = Trigger
  If Len(ColorStr) = 0 Then
    outColor = CoVal.NormalText
  Else
    outColor = Val(ColorStr)
  End If
  For Each CFrame In ChatFrames
    If Not CFrame.TextF Is Nothing Then
      If CFrame.FrameID = FrameID Or (FrameID = 0 And CFrame Is FrontCFrame) Then
        CFrame.PrintText Text, outColor, True, NoNewLine = False, IfTrigger, IfTrigger = 9, TriggerStr
        If CFrame Is FrontCFrame And Not CFrame.TextF Is Nothing Then CFrame.TextF.RefText
        I = 1
        Exit For
      End If
    End If
  Next
  If I = 0 And (FrameID = 0) Then
    Set CFrame = Nothing
    If Not LastFrontFrame Is Nothing Then
      If Not LastFrontFrame.TextF Is Nothing Then Set CFrame = LastFrontFrame
    End If
    If CFrame Is Nothing Then
      For I = 1 To ChatFrames.Count
        If Not ChatFrames(I).TextF Is Nothing Then Set CFrame = ChatFrames(I): Exit For
      Next
    End If
    If Not CFrame Is Nothing Then
      CFrame.PrintText Text, outColor, True, NoNewLine = False, IfTrigger, IfTrigger = 9, TriggerStr
      If CFrame Is FrontCFrame And Not CFrame.TextF Is Nothing Then CFrame.TextF.RefText
    End If
  End If
End Sub

Private Function GetFrameByIndex(Index As Integer) As Integer
  If Index > 0 And Index <= ChatFrames.Count Then
    GetFrameByIndex = ChatFrames(Index).FrameID
  End If
End Function

Private Function GetIRCConnByIndex(Index As Integer) As Integer
  If Index > 0 And Index <= IRCconns.Count Then
    GetIRCConnByIndex = IRCconns(Index).ConnID
  End If
End Function

Private Function GetDCCConnByIndex(Index As Integer) As Integer
  If Index > 0 And Index <= DCCconns.Count Then
    GetDCCConnByIndex = DCCconns(Index).ConnID
  End If
End Function

Public Sub ntScript_Unload()
  Dim I As Integer
  
  If ntScriptEnabled = False Then Exit Sub
  If ExitErr = False Then ntScript_Call "Unload"
  
  For I = DCCconns.Count To 1 Step -1
    If DCCconns(I).GetMode > 1 Then DCCconns.Remove I
  Next
  
  ReDim SubIndex(0)
  ReDim VarList(0)
  ReDim ScriptIndex(0)
  ReDim ScriptArrays(0)
  CurrentScript = ""
  ntScriptEnabled = False
  StopAllScriptTimers
  Form1.MoMenue
  RemoveFromComList
  RemDCCScriptServer 0
End Sub

Public Sub ntScript_Reset()
  Dim I As Long
  Dim I2 As Long
  Dim I3 As Long
  Dim I4 As Long
  Dim I5 As Long
  Dim DAT As String
  Dim CountI As Integer
  Dim ScrCount As Integer
  Dim TrimedCom As String
  Dim TrimedCStart As String
  
  ReDim SubIndex(0)
  ReDim VarList(0)
  ReDim ScriptIndex(0)
  ReDim RegedEvents(0)
  ReDim ScriptArrays(0)
  
  CurrentScript = "Default"
  ExitErr = False
  I = -1
  Do
    I2 = I
    I = InStr(I + 2, ntScript, vbNewLine)
    If I = 0 Then I = Len(ntScript) + 1
    I3 = InStr(I2 + 2, ntScript, " ")
    TrimedCom = Trim(Mid(ntScript, I2 + 2, I - I2 - 2))
    If I3 > 0 And Len(TrimedCom) > 0 And Left(TrimedCom, 1) <> "'" Then
      TrimedCStart = LCase(Trim(Mid(ntScript, I2 + 2, I3 - I2 - 2)))
      If TrimedCStart = "#newscriptbegin" Then
        If CountI > 0 Then
          ReDim Preserve ScriptIndex(ScrCount)
          ScriptIndex(ScrCount).vEnd = I2 + 1
          ScrCount = ScrCount + 1
        End If
        CurrentScript = Trim(Mid(ntScript, I3 + 1, I - I3 - 1))
        ReDim Preserve ScriptIndex(ScrCount)
        ScriptIndex(ScrCount).vName = CurrentScript
        ScriptIndex(ScrCount).vStart = I + 2
        ScrCount = ScrCount + 1
      ElseIf TrimedCStart = "rem" Then
        'Auskommentiert
      ElseIf TrimedCStart = "dim" Then
        SetVarVal Trim(Mid(ntScript, I3 + 1, I - I3 - 1)), "", "", CurrentScript, False
      ElseIf TrimedCStart = "public" Then
        SetVarVal Trim(Mid(ntScript, I3 + 1, I - I3 - 1)), "", "", "", False
      ElseIf TrimedCStart = "sub" Or TrimedCStart = "function" Then
        ReDim Preserve SubIndex(CountI)
        I4 = InStr(I3, ntScript, "(")
        If I4 = 0 Or I4 > I Then I4 = I
        SubIndex(CountI).vName = Trim(Mid(ntScript, I3 + 1, I4 - I3 - 1))
        SubIndex(CountI).Script = CurrentScript
        If I > I4 Then
          SubIndex(CountI).Para = Trim(Mid(ntScript, I4 + 1, I - I4 - 1))
          If Len(SubIndex(CountI).Para) Then
            SubIndex(CountI).Para = Left(SubIndex(CountI).Para, Len(SubIndex(CountI).Para) - 1)
          End If
        End If
        SubIndex(CountI).vStart = I + 2
        I5 = I
        Do
          I4 = I5
          I5 = InStr(I5 + 2, ntScript, vbNewLine)
          If I5 = 0 Then I5 = Len(ntScript) + 1
          If LCase(Trim(Mid(ntScript, I4 + 2, I5 - I4 - 2))) = "end sub" Or LCase(Trim(Mid(ntScript, I4 + 2, I5 - I4 - 2))) = "end function" Then
            SubIndex(CountI).vEnd = I4 + 1
            I2 = I4
            I = I5
            Exit Do
          End If
        Loop Until I5 = Len(ntScript) + 1
        CountI = CountI + 1
      Else
        ScriptError I - 1, 1, "Syntax error, unknown command (" + Left(TrimedCStart, I - I2 - 2) + ")"
        ExitErr = False
        Exit Sub
      End If
    End If
  Loop Until I = Len(ntScript) + 1
  If ScrCount > 0 Then ScriptIndex(ScrCount - 1).vEnd = Len(ntScript)
  ntScriptEnabled = True
  Form1.MoMenue
  ScriptSaveMode = 0
  CurrentScript = ""
  ntScript_Call "Load"
End Sub

Private Function IsNtSFunction(Name As String) As Boolean
  Dim ScriptName As String
  Dim SubName As String
  Dim I As Integer
  
  I = InStr(1, Name, ".")
  If I Then
    SubName = LCase(Mid(Name, I + 1))
    ScriptName = LCase(Left(Name, I - 1))
  Else
    SubName = LCase(Name)
    ScriptName = LCase(CurrentScript)
  End If
  For I = 0 To UBound(SubIndex)
    If LCase(SubIndex(I).vName) = SubName And (LCase(SubIndex(I).Script) = ScriptName Or Len(ScriptName) = 0) Then
      IsNtSFunction = True
      Exit Function
    End If
  Next
End Function

Public Function ntScript_Call(Name As String, Optional PaMe1 As String, Optional PaMe2 As String, Optional PaMe3 As String, Optional PaMe4 As String, Optional PaMe5 As String, Optional MakeErr As Boolean, Optional ScriptNameIn As String, Optional NoEvent As Boolean) As Boolean
  Dim I As Integer
  Dim I2 As Integer
  Dim I3 As Integer
  Dim CountI As Integer
  Dim FoundSub As Boolean
  Dim SubName As String
  Dim ParaM As String
  Dim TempSubName As String
  Dim TempScriptName As String
  Dim StartScript As Boolean
  Dim ScriptName As String
  Dim TempRetVal As String
  
  Dim TempPosition As Integer
  Dim TempToken As String
  Dim TempArgument As String
  Dim TempErrStr As String
  Dim FirstCall As Boolean
  Dim DAT As String
    
  If NoEvent = False Then
    SendEventToPlg Name, PaMe1 + Chr(27) + PaMe2 + Chr(27) + PaMe3 + Chr(27) + PaMe4 + Chr(27) + PaMe5 + Chr(27)
  End If
  ntScript_Call = True
  If ntScriptEnabled = False Then Exit Function
  If Len(ntScript) = 0 Then Exit Function
  
  If ntScriptTimeOut = 0 Then ntScriptTimeOut = 3
  If ScriptTimeOut = 0 Then
    ScriptLoopOut = 0
    StartScript = True
    ScriptTimeOut = AltTimer + ntScriptTimeOut
  End If
  
  SkipEvent = False
  I = InStr(1, Name, ".")
  If I Then
    SubName = LCase(Mid(Name, I + 1))
    ScriptName = LCase(Left(Name, I - 1))
  Else
    SubName = LCase(Name)
    ScriptName = LCase(ScriptNameIn)
  End If
  
  If CallIsRunning = False Then
    FirstCall = True
    CallIsRunning = True
  End If
  
  For I = 0 To UBound(SubIndex)
    If LCase(SubIndex(I).vName) = SubName And (LCase(SubIndex(I).Script) = ScriptName Or Len(ScriptName) = 0) Then
      TempSubName = CurrentSub
      CurrentSub = SubIndex(I).vName
      TempScriptName = CurrentScript
      CurrentScript = LCase(SubIndex(I).Script)
      
      CountI = 0
      I2 = 0
      Do
        Select Case CountI
          Case 0
            ParaM = PaMe1
          Case 1
            ParaM = PaMe2
          Case 2
            ParaM = PaMe3
          Case 3
            ParaM = PaMe4
          Case 4
            ParaM = PaMe5
          Case Else
            ParaM = ""
        End Select
        I3 = I2
        I2 = InStr(I2 + 1, SubIndex(I).Para, ",")
        If I2 = 0 Then I2 = Len(SubIndex(I).Para) + 1
        DAT = Trim(Mid(SubIndex(I).Para, I3 + 1, I2 - I3 - 1))
        If Len(DAT) Then
          SetVarVal DAT, ParaM, CurrentSub, CurrentScript, True
        End If
        CountI = CountI + 1
      Loop Until I2 = Len(SubIndex(I).Para) + 1
      
      TempRetVal = CurrentRetVal
      TempPosition = Position
      TempToken = Token
      TempArgument = Argument
      TempErrStr = ErrorString
      
      RunPart SubIndex(I).vStart, SubIndex(I).vEnd
      
      LastRetVal = CurrentRetVal
      CurrentRetVal = TempRetVal
      Position = TempPosition
      Token = TempToken
      Argument = TempArgument
      ErrorString = TempErrStr
      
      If ExitErr = True Then Exit For
      RemVar CurrentSub, CurrentScript
      CurrentSub = TempSubName
      CurrentScript = TempScriptName
      FoundSub = True
    End If
  Next
  If FoundSub = False And MakeErr = True And ExitErr = False Then
    ScriptError -1, 2, "Sub not found: """ + Name + """"
  End If
  ntScript_Call = SkipEvent = False
  If StartScript = True Then ScriptTimeOut = 0
  
  If FirstCall Then
    ExitErr = False
    CallIsRunning = False
  End If
End Function

Private Sub RunPart(ByVal FirstBytePos As Long, ByVal LastBytePos As Long)
  Dim I As Long
  Dim I2 As Long
  Dim DAT As String
  Dim saveLastDo(15) As Long
  Dim DoIndex As Integer
  I = FirstBytePos - 2
  Do
    I2 = I
    I = InStr(I + 2, ntScript, vbNewLine)
    If I = 0 Then I = Len(ntScript) + 1
    If I > LastBytePos Then Exit Do
    DAT = Mid(ntScript, I2 + 2, I - I2 - 2)
    If Trim(DAT) <> "" Then
      PhraseLine Trim(DAT), FirstBytePos, LastBytePos, I, saveLastDo, DoIndex
    End If
  Loop Until I = Len(ntScript) + 1 Or ExitErr = True
End Sub

Public Sub PhraseLine(DAT As String, ByVal FirstBytePos As Long, ByVal LastBytePos As Long, lZeiger As Long, saveLastDo() As Long, DoIndex As Integer)
  Dim I As Long
  Dim I2 As Long
  Dim I3 As Long
  Dim I4 As Long
  Dim I5 As Long
  Dim J1 As Long
  Dim SpaceIn As Boolean
  Dim endCom As Boolean
  Dim Beginning As Boolean
  Dim WData As String
  Dim Argus(5) As String
  
  Dim AnfZ As Boolean
  Dim KlamM As Integer
  
  On Error GoTo AppFehler
  
  If ExitErr = True Then Exit Sub
  If Left(DAT, 1) = "'" Then Exit Sub
  
  Beginning = False
  EvPos = lZeiger
  
  For J1 = 1 To Len(DAT)
    Select Case AscB(LCase(Mid(DAT, J1, 1)))
      Case 39 And SpaceIn = False ' "'"
        If endCom = True Then
          Argus(I2) = GetValue(Mid(DAT, I3 + 1, J1 - I3 - 1))
          I3 = J1
          Exit For
        End If
      Case 32 ' " "
        If endCom = False Then
          I = J1
          I3 = J1
          I5 = J1
          endCom = True
        ElseIf KlamM = 0 And SpaceIn = False Then
          I5 = J1
        End If
      Case 61 ' "="
        If I4 = 0 Then
          I = InStr(1, DAT, "(")
          If I > 0 And I < J1 Then
            I4 = InStr(I, DAT, ")")
            If I4 > 0 And I4 < J1 Then
              SetArrayValue CurrentScript, Trim(Left(DAT, I - 1)), GetValue(Mid(DAT, I + 1, I4 - I - 1)), GetValue(Mid(DAT, J1 + 1))
              I4 = 0
            End If
          Else
            SetVarVal Trim(Left(DAT, J1 - 1)), GetValue(Mid(DAT, J1 + 1)), CurrentSub, CurrentScript
          End If
          I = 1
          endCom = False
          Exit For
        End If
      Case 44 ' ","
        If endCom = True And KlamM = 0 And SpaceIn = False Then
          Argus(I2) = GetValue(Mid(DAT, I3 + 1, J1 - I3 - 1))
          I3 = J1
          If I2 < UBound(Argus) Then I2 = I2 + 1
        End If
      Case 40 ' "("
        If endCom = True And SpaceIn = False Then KlamM = KlamM + 1
      Case 41 ' ")"
        If endCom = True And SpaceIn = False Then KlamM = KlamM - 1
      Case 34 ' """"
        If endCom = True Then SpaceIn = SpaceIn = False
      Case Else
        If endCom = True Then
          If J1 < Len(DAT) Then
            If Mid(DAT, J1 + 1, 1) = " " Then I4 = 2 Else I4 = 1
          Else
            I4 = 2
          End If
          If KlamM = 0 And SpaceIn = False And I4 = 2 Then
            Select Case LCase(Mid(DAT, I5 + 1, J1 - I5))
              Case "then", "until", "while", "if"
                endCom = False
                Exit For
            End Select
          End If
        End If
    End Select
  Next
  
  If endCom = True And KlamM = 0 And SpaceIn = False Then
    Argus(I2) = GetValue(Mid(DAT, I3 + 1))
    I3 = J1
    I2 = I2 + 1
    If ExitErr Then Exit Sub
  End If
  
  If I = 0 Then I = Len(DAT) + 1
  
  I3 = I
  Select Case LCase(Left(DAT, I - 1))
    Case "rem" 'REM
    Case "if"  'IF THEN
      I2 = I5 + 1
      If endCom = True Then ScriptError lZeiger, 1, "Syntax error, expect ""Then""": Exit Sub
      If I2 + 3 = Len(DAT) Then
        I4 = 0
        I = lZeiger
        Do
          I3 = I
          Do
            I = InStr(I + 1, ntScript, vbNewLine)
          Loop Until I = 0 Or I > I3 + 1
          If I = 0 Then I = Len(ntScript) + 1
          If LCase(Left(Trim(Mid(ntScript, I3 + 2, I - I3 - 2)), 6)) = "end if" Then I4 = I4 - 1
          If LCase(Trim(Mid(ntScript, I3 + 2, I - I3 - 2))) = "else" And I4 = 0 Then I4 = I4 - 1
          If LCase(Left(Trim(Mid(ntScript, I3 + 2, I - I3 - 2)), 3)) = "if " Then
            If LCase(Right(Trim(Mid(ntScript, I3 + 2, I - I3 - 2)), 5)) = " then" Then I4 = I4 + 1
          End If
          If I = Len(ntScript) + 1 Then I3 = 0: Exit Do
        Loop Until I4 < 0
        
        If I3 = 0 Then ScriptError lZeiger, 2, "Syntax error, ""if""  without  ""end if""": Exit Sub
        If IsTrue(Mid(DAT, 4, I2 - 5)) = False Then lZeiger = I
      Else
        If IsTrue(Mid(DAT, 4, I2 - 5)) = True Then
          PhraseLine Mid(DAT, I2 + 5), FirstBytePos + I2 + 1, LastBytePos, lZeiger, saveLastDo, DoIndex
        End If
      End If
      Exit Sub
    Case "do" 'DO
      I4 = 0
      saveLastDo(DoIndex) = lZeiger
      DoIndex = DoIndex + 1
      If Len(DAT) > 2 Then
        I = lZeiger
        Do
          I3 = I
          Do
            I = InStr(I + 1, ntScript, vbNewLine)
          Loop Until I = 0 Or I > I3 + 1
          If I = 0 Then I = Len(ntScript) + 1
          If LCase(Left(Trim(Mid(ntScript, I3 + 2, I - I3 - 2)), 4)) = "loop" Then I4 = I4 - 1
          If LCase(Left(Trim(Mid(ntScript, I3 + 2, I - I3 - 2)), 2)) = "do" Then I4 = I4 + 1
          If I = Len(ntScript) + 1 Then I3 = 0: Exit Do
        Loop Until I4 < 0
        If LCase(Mid(DAT, 4, 5)) = "until" Then
          If IsTrue(Mid(DAT, 10)) = True Then lZeiger = I
        ElseIf LCase(Mid(DAT, 4, 5)) = "while" Then
          If IsTrue(Mid(DAT, 10)) = False Then lZeiger = I
        Else
          ScriptError lZeiger, 1, "Syntax error, expect ""Until"" or ""While""": Exit Sub
        End If
      End If
      If lZeiger = I Then DoIndex = DoIndex - 1
    Case "loop" 'LOOP
      If DoIndex < 1 Then
        If I3 = 0 Then ScriptError lZeiger, 2, """loop""  ohne  ""do""": Exit Sub
      Else
        For I2 = saveLastDo(DoIndex - 1) - 2 To 1 Step -1
          If Mid(ntScript, I2, 2) = vbNewLine Then Exit For
        Next
      End If
      If Len(DAT) > 4 Then
        If LCase(Mid(DAT, 6, 5)) = "until" Then
          If IsTrue(Mid(DAT, 12)) = False Then lZeiger = I2
        ElseIf LCase(Mid(DAT, 6, 5)) = "while" Then
          If IsTrue(Mid(DAT, 12)) = True Then lZeiger = I2
        Else
          ScriptError lZeiger, 1, "Syntax error, expect ""Until"" or ""While""": Exit Sub
        End If
      Else
        lZeiger = I2
      End If
      DoIndex = DoIndex - 1
    Case "else"
      I = lZeiger
      Do
        I3 = I
        I = InStr(I + 1, ntScript, vbNewLine)
        If I = 0 Then I = Len(ntScript) + 1
        If LCase(Left(Trim(Mid(ntScript, I3 + 2, I - I3 - 2)), 6)) = "end if" Then I4 = I4 - 1
        If LCase(Left(Trim(Mid(ntScript, I3 + 2, I - I3 - 2)), 3)) = "if " Then
          If LCase(Right(Trim(Mid(ntScript, I3 + 2, I - I3 - 2)), 5)) = " then" Then I4 = I4 + 1
        End If
        If I = Len(ntScript) + 1 Then I3 = 0: Exit Do
      Loop Until I4 < 0
      If I3 = 0 Then ScriptError lZeiger, 2, "Syntax error, ""if""  without  ""end if""": Exit Sub
      lZeiger = I
    Case "msgbox" 'MSGBOX
      If Val(Argus(1)) < 1024 Then MsgBox Argus(0), Val(Argus(1)), "ntScript"
    Case "beep" 'BEEP
      If Val(Argus(0)) = 1 Then
        MakeSignal
      ElseIf Val(Argus(0)) = 2 Then
        MakeSignal2
      Else
        Beep
      End If
    Case "end" 'END IF
    Case "dim"
      SetVarVal Trim(Mid(DAT, 4)), "", CurrentSub, CurrentScript, True
    Case "skipevent" 'SKIPEVENT
      SkipEvent = True
    Case "call" 'CALL
      ntScript_Call Argus(0), Argus(1), Argus(2), Argus(3), Argus(4), Argus(5), True, CurrentScript, True
    Case "print"
      If Len(Argus(1)) < 4 Then TextOut Argus(0), Val(Argus(1)), Argus(2), CBool(Val(Argus(3))), Argus(4), Val(Argus(5))
    Case "cprint"
      If Len(Argus(1)) < 4 Then TextOut Argus(0), GetFrameID(Val(Argus(1))), Argus(2), CBool(Val(Argus(3))), Argus(4), Val(Argus(5))
    Case "echo"
      TextOut "~ Script: ", 0, CStr(CoVal.ClientMSG)
      TextOut Trim(Argus(0) + " " + Argus(1) + " " + Argus(2) _
      + " " + Argus(3) + " " + Argus(4) + " " + Argus(5)), 0, CStr(CoVal.NormalText), True
    Case "send"
      If Len(Argus(1)) < 4 Then
        If Not FrameByID(Val(Argus(1))) Is Nothing Then FrameByID(Val(Argus(1))).SendM Argus(0), True
      End If
    Case "sendtext"
      If Len(Argus(1)) < 4 Then SendOutText Argus(0), Val(Argus(1)), Argus(2)
    Case "senddata"
      If Len(Argus(1)) < 4 Then SendOutData Argus(0), Val(Argus(1)), Val(Argus(2))
    Case "dccconnect"
      StDccConn Argus(0), Argus(1), Argus(2), Argus(3), Val(Argus(4)), Val(Argus(5))
    Case "cls"
      If Len(Argus(1)) < 4 Then StCls Val(Argus(0))
    Case "newframe"
      OpenNewWindow Argus(0)
    Case "closeconn"
      CloseAConnection Val(Argus(0))
    Case "closeframe"
      If Len(Argus(0)) < 4 Then If Not FrameByID(Val(Argus(0))) Is Nothing Then FrameByID(Val(Argus(0))).CloseFrame
    Case "connect"
      If Len(Argus(0)) < 4 Then SetConnection Val(Argus(0)), False
    Case "disconnect"
      If Len(Argus(0)) < 4 Then SetConnection Val(Argus(0)), True
    Case "dccaccept"
      If Len(Argus(1)) < 4 Then
        If Not FrameByID(Val(Argus(1))) Is Nothing Then
          StartDCCConnection "DCC:" + Argus(0), True, , FrameByID(Val(Argus(1)))
        End If
      End If
    Case "openconnection"
      StartDCCConnection "DCC:CHAT " + Argus(2) + " " + Argus(0) + " " + Argus(1) + " -1 chat Client", False, 1 + Val(Abs(Sgn(Val(Argus(3))))) * 2
    Case "save"
      SaveScriptValue Argus(0), Argus(1)
    Case "plstart"
      StartPlugin Argus(0)
    Case "plstop"
      UnloadPlugin Argus(0)
    Case "plsend"
      SendDataToPlugin Argus(0), Argus(1), Argus(2)
    Case "starttimer"
      StartScriptTimer Val(Argus(0)), Val(Argus(1)), Argus(2), CBool(Val(Argus(3)))
    Case "stoptimer"
      StopScriptTimer Val(Argus(0))
    Case "makeshortcut"
      If Val(Argus(3)) > -1 And Val(Argus(3)) < 3 Then
        AddToComList Argus(0), Argus(1), Argus(2), Val(Argus(3)), True
      End If
    Case "setlineicon"
      If Len(Argus(0)) < 4 And Len(Argus(1)) < 4 Then SetLineIcon Val(Argus(0)), Val(Argus(1))
    Case "showosdmsg"
      If Len(Argus(2)) < 4 Then If Not FrameByID(Val(Argus(2))) Is Nothing Then ShowOSDmsg FrameByID(Val(Argus(2))), Argus(1), Argus(0), True
    Case "settrayicon"
      If Len(Argus(0)) < 4 Then SetTrayIcon Val(Argus(0)), Val(Argus(1))
    Case "setframeicon"
      If Len(Argus(0)) < 4 Then SetFrameIcon Val(Argus(0)), Val(Argus(1)), Val(Argus(2))
    Case "playwave"
      MakeSignal2 CStr(Argus(0))
    Case "beepstring"
      Beep2 CStr(Argus(0))
    Case "setfrontframe"
      If Not FrameByID(Val(Argus(0))) Is Nothing Then SetFrontFrame FrameByID(Val(Argus(0)))
    Case "pasttext"
      If Not Form1.TextFeld Is Nothing Then Form1.TextFeld.SelText = Argus(0)
    Case "setlistcolor"
       SetListColor Val(Argus(0)), Val(Argus(1)), Val(Argus(2)), Val(Argus(3))
    Case "regevent"
      RegNewEvent Argus(0), Val(Argus(1)), CurrentScript
    Case "unregevent"
      RemRegedEvent Argus(0), Val(Argus(1)), CurrentScript
    Case "phrasedata"
      SimulateCommand Argus(0), Val(Argus(1))
    Case "showinfo"
      Form1.ShowScriptNotify Argus(0), Val(Argus(1)), Val(Argus(2)), Val(Argus(3)), Val(Argus(4))
    Case "openport"
      AddDCCScriptServer Val(Argus(0)), Val(Argus(1)), Val(Argus(2))
    Case "closeport"
      RemDCCScriptServer Val(Argus(0))
    Case "writefile"
      ScrWriteFile Argus(0), Argus(1), Val(Argus(2))
    Case "printtofile"
      ScrPrintFile Argus(0), Argus(1), Val(Argus(2))
    Case "writelog"
      If Not FrameByID(Val(Argus(1))) Is Nothing Then WriteLog Format(Now, "dd.mm.yyyy hh:mm:ss") + " " & Argus(0), FrameByID(Argus(1))
    Case "ddepoke"
      PokeDDEMessage Argus(0), Argus(1), Argus(2)
    Case "ddeexecute"
      ExeDDEMessage Argus(0), Argus(1), Argus(2)
    Case "setserver"
      SetNewServer Val(Argus(2)), Argus(0), Val(Argus(1))
    Case "setproxy"
      SetNewProxy Val(Argus(2)), Argus(0), Val(Argus(1)), Val(Argus(3))
    Case "setstatetext"
      LastWispMsg = Argus(0)
      Form1.pStateIntRefresh
    Case Else
      If I > 1 Then
        If IsNtSFunction(Left(DAT, I - 1)) Then
          ntScript_Call Left(DAT, I - 1), Argus(0), Argus(1), Argus(2), Argus(3), Argus(4), False, CurrentScript, True
        Else
          ScriptError lZeiger, 1, "Syntax error, unknown command": Exit Sub
        End If
      End If
  End Select
  ScriptLoopOut = ScriptLoopOut + 1
  If AltTimeDiff(ScriptTimeOut) > 0 And ExitErr = False And ScriptLoopOut > 128 Then
    I = MsgBox(TeVal.scrTimeout, vbCritical + vbYesNo, "ntScript")
    If I = vbYes Then ExitErr = True: ntScript_Unload Else ScriptTimeOut = AltTimer + 3
  End If
  Exit Sub
  
AppFehler:
  ExitErr = True
  ntScript_Unload
  MsgBox Err.Description, vbCritical, "ntScript"
End Sub

Private Sub CloseAConnection(ConnID As Integer)
  Dim FrameObj As ChatFrame
  Dim I As Integer
  
  Set FrameObj = FrameByID(GetFrameID(ConnID, "", True))
  If FrameObj Is Nothing Then
    For I = DCCconns.Count To 1 Step -1
      If DCCconns(I).ConnID = ConnID Then DCCconns.Remove I
    Next
  Else
    FrameObj.CloseFrame
  End If
End Sub

Public Sub ntScript_TimerEvent(TimerID As Integer)
  Dim I As Integer
  
  For I = 1 To UBound(ScriptTimer)
    If ScriptTimer(I).vTimerID = TimerID Then
      ntScript_Call ScriptTimer(I).vSub, CStr(ScriptTimer(I).vUserID), , , , , False, ScriptTimer(I).vScript
      If ScriptTimer(I).vTimerID Then
        If ScriptTimer(I).vRep Then
          Form1.StartScriptTimer ScriptTimer(I).vInterval, ScriptTimer(I).vTimerID
        Else
          ScriptTimer(I).vTimerID = 0
        End If
      End If
      Exit For
    End If
  Next
End Sub

Private Sub StartScriptTimer(Interval As Long, UserID As Integer, SubName As String, NoRepeat As Boolean)
  Dim I As Integer
  Dim OutSubName As String
  
  If Len(SubName) Then
    OutSubName = SubName
  Else
    OutSubName = "TimerEvent"
  End If
  If Interval > 0 Then
    For I = 1 To UBound(ScriptTimer)
      If ScriptTimer(I).vTimerID = 0 Then
        ScriptTimer(I).vSub = OutSubName
        ScriptTimer(I).vScript = CurrentScript
        ScriptTimer(I).vInterval = Interval
        ScriptTimer(I).vTimerID = I
        ScriptTimer(I).vUserID = UserID
        ScriptTimer(I).vRep = Not NoRepeat
        Form1.StartScriptTimer Interval, I
        Exit For
      End If
    Next
  End If
End Sub

Private Sub StopScriptTimer(TimerID As Integer)
  Dim I As Integer
  
  For I = 1 To UBound(ScriptTimer)
    If ScriptTimer(I).vTimerID > 0 And ScriptTimer(I).vUserID = TimerID And ScriptTimer(I).vScript = CurrentScript Then
      Form1.StopScriptTimer ScriptTimer(I).vTimerID
      ScriptTimer(I).vTimerID = 0
    End If
  Next
End Sub

Private Sub StopAllScriptTimers()
  Dim I As Integer
  
  For I = 1 To UBound(ScriptTimer)
    If ScriptTimer(I).vTimerID > 0 Then
      Form1.StopScriptTimer ScriptTimer(I).vTimerID
      ScriptTimer(I).vTimerID = 0
    End If
  Next
End Sub

Private Sub SetLineIcon(FrameID As Integer, IconID As Integer)
  Dim CFrame As ChatFrame
  Dim IconIndex As Long
  
  Select Case IconID
    Case 0: IconIndex = 69
    Case 1: IconIndex = 65
    Case 2: IconIndex = 75
    Case 3: IconIndex = 76
    Case 4: IconIndex = 77
  End Select
  
  Set CFrame = FrameByID(FrameID)
  If CFrame Is Nothing Then Exit Sub
  If Not CFrame.TextF Is Nothing And IconIndex Then
    CFrame.TextF.SetLineIcon IconIndex
  End If
End Sub

Private Sub SetTrayIcon(TrayState As Integer, Optional ByVal Overwrite As Boolean)
  If TrayState >= 0 And TrayState <= Form1.TrayIcon.Count Then
    If IsNotifyNess Or Overwrite Then
      If TrayState > TrayIconState Or Overwrite Then
        T.hIcon = Form1.TrayIcon(TrayState + 1)
        Shell_NotifyIcon NIM_MODIFY, T
        If TrayState > 5 Then
          TrayIconState = 3
        Else
          TrayIconState = TrayState
        End If
      End If
      If TrayState > 3 Then Form1.StartTrayFlash
    End If
  End If
End Sub

Private Sub SetFrameIcon(FrameID As Integer, FrameState As Integer, ByVal Overwrite As Boolean)
  Dim CFrame As ChatFrame
  
  If FrameState >= 0 And FrameState <= 4 Then
    Set CFrame = FrameByID(FrameID)
    If Not CFrame Is Nothing Then
      If (CFrame.Changed < FrameState And Not CFrame Is FrontCFrame) Or Overwrite Then
        CFrame.Changed = FrameState
        Form1.ColumRedraw True
        If FrameState > 2 Then Form1.StartFlash CFrame
      End If
    End If
  End If
End Sub

Private Sub StCls(FrameID As Integer)
  Dim CFrame As ChatFrame
  
  Set CFrame = FrameByID(FrameID)
  If CFrame Is Nothing Then Exit Sub
  If Not CFrame.TextF Is Nothing Then CFrame.TextF.ClearText
End Sub

Private Function GetFrameType(FrameID As Integer) As Integer
  Dim CFrame As ChatFrame
  
  Set CFrame = FrameByID(FrameID)
  If Not CFrame Is Nothing Then
    GetFrameType = CFrame.FrameType
  Else
    GetFrameType = -1
  End If
End Function

Private Function GetFListC(FrameID As Integer) As Integer
  Dim CFrame As ChatFrame
  
  Set CFrame = FrameByID(FrameID)
  If Not CFrame Is Nothing Then
    If Not CFrame.UListF Is Nothing Then
      GetFListC = CFrame.UListF.ListCount
    End If
  End If
End Function

Private Function GetFListV(FrameID As Integer, ListIndex As Integer, ListColum As Integer) As String
  Dim CFrame As ChatFrame
  
  Set CFrame = FrameByID(FrameID)
  If Not CFrame Is Nothing Then
    If Not CFrame.UListF Is Nothing Then
      GetFListV = CFrame.UListF.List(ListIndex, ListColum)
    End If
  End If
End Function

Private Function GetListIndexByText(FrameID As Integer, Text As String, ListColum As Integer) As String
  Dim CFrame As ChatFrame
  Dim I As Integer
  
  GetListIndexByText = -1
  Set CFrame = FrameByID(FrameID)
  If Not CFrame Is Nothing Then
    If Not CFrame.UListF Is Nothing Then
      For I = 0 To CFrame.UListF.ListCount - 1
        If CFrame.FrameType = cfRoom Then
          If Text = LCase(CFrame.IrcConn.ChatNoSign(CFrame.UListF.GetListText(I, ListColum))) Then
            GetListIndexByText = I
            Exit For
          End If
        Else
          If Text = LCase(CFrame.UListF.GetListText(I, ListColum)) Then
            GetListIndexByText = I
            Exit For
          End If
        End If
      Next
    End If
  End If
End Function

Private Sub SetListColor(FrameID As Integer, ListIndex As Integer, TextColor As Long, DontRef As Integer)
  Dim CFrame As ChatFrame
  
  Set CFrame = FrameByID(FrameID)
  If Not CFrame Is Nothing Then
    If Not CFrame.UListF Is Nothing Then
      CFrame.UListF.SetListTextColor ListIndex, TextColor, DontRef <> 0
    End If
  End If
End Sub

Private Function StDccConn(Server As String, Port As String, Optional ClientName As String, Optional ServerName As String, Optional cMode As Integer, Optional NoWindow As Integer) As String
  Dim WData As String
  Dim WData2 As String
  WData = ClientName
  If Trim(WData) = "" Or Trim(WData) = "0" Then WData = "Client"
  WData2 = ServerName
  If Trim(WData2) = "" Or Trim(WData2) = "0" Then WData2 = "Server"
  StDccConn = StartDCCConnection("DCC:CHAT " + WData2 + " " + Server + " " + Port + " -1 chat " + WData, False, Abs(Sgn(cMode)) + Abs(Sgn(NoWindow)) * 2)
End Function

Private Function IsSilent(ConnID As Integer) As Boolean
  Dim CConn As IRCConnection
  Dim CFrame As ChatFrame
  
  Set CFrame = FrameByID(GetFrameID(ConnID, "", True))
  If Not CFrame Is Nothing Then
    If CFrame.ConnTyp = 0 Then
      Set CConn = ConnByID(ConnID)
      If Not CConn Is Nothing And ConnID < 500 Then IsSilent = CConn.Silent
    End If
  End If
End Function

Private Function IsTrue(DAT As String) As Boolean
  IsTrue = CStr(GetValue(DAT)) = CStr(True)
End Function

Private Function ScrInput(Optional Caption As String, Optional DefText As String) As String
  Load Form3
  If Len(Caption) Then
    Form3.Label3.Caption = Caption
  Else
    Form3.Label3.Caption = "Text:"
  End If
  Form3.Caption = "ntScript"
  Form3.Text3.Text = DefText
  Form3.Text3.SelStart = 0
  Form3.Text3.SelLength = Len(Form3.Text3.Text)
  Form3.Picture1.Visible = False
  Form3.Picture2.Visible = True
  Form3.Text3.TabIndex = 0
  Form3.Show 1
  ScrInput = Form3.Text3.Text
  Unload Form3
End Function

Private Sub SetConnection(ByVal ConnID As Integer, CloseConn As Boolean)
  If Not ConnByID(ConnID) Is Nothing Then
    If CloseConn Then
      ConnByID(ConnID).CloseConnection
    Else
      ConnByID(ConnID).Connect
    End If
  End If
End Sub

Private Sub SetNewServer(ByVal ConnID As Integer, Server As String, Port As Long)
  Dim IsIRC As Boolean
  If Not ConnByID(ConnID, IsIRC) Is Nothing Then
    If IsIRC Then
      ConnByID(ConnID).Server = Server
      ConnByID(ConnID).Port = Port
      If ConnByID(ConnID).Port = 0 Then ConnByID(ConnID).Port = 6667
    End If
  End If
End Sub

Private Sub SetNewProxy(ByVal ConnID As Integer, Server As String, Port As Long, ProxyType As Double)
  Dim IsIRC As Boolean
  If Not ConnByID(ConnID, IsIRC) Is Nothing Then
    If IsIRC Then
      ConnByID(ConnID).SockProxyServer = Server
      ConnByID(ConnID).SockProxyPort = Port
      If ProxyType > 4 Then
        ConnByID(ConnID).SockProxyType = 45
      Else
        ConnByID(ConnID).SockProxyType = 40
      End If
      
      If ConnByID(ConnID).SockProxyPort = 0 Then ConnByID(ConnID).SockProxyPort = 1080
    End If
  End If
End Sub

Private Function GetValue(DAT As String) As String
  Dim ScError As String
  If Len(DAT) = 0 Then Exit Function
  GetValue = Evaluate(DAT, ScError)
  If ScError <> "" And ExitErr = False Then ScriptError EvPos, 5, ScError: Exit Function
End Function

Private Function GetVarVal(VarName As String, Optional SubName As String, Optional ScriptName As String) As String
  Dim I As Integer
  
  Select Case LCase(VarName)
    Case "rnd": GetVarVal = CStr(Rnd)
    Case "pi": GetVarVal = CStr(Atn(1) * 4)
    Case "e": GetVarVal = "2.71828182845904"
    Case "timer": GetVarVal = CStr(Timer)
    Case "time": GetVarVal = Format(Now, "long time")
    Case "date": GetVarVal = Format(Now, "short date")
    Case "now": GetVarVal = CStr(Now)
    Case "longdate": GetVarVal = Format(Now, "long date")
    Case "frontid", "frontframeid": GetVarVal = FrontCFrame.FrameID
    Case "frontconid", "frontconnid", "frontcid": GetVarVal = GetFrontID
    Case "version": GetVarVal = App.Major & "." & App.Minor & "." & App.Revision
    Case "wisperto": GetVarVal = WisperTo
    
    Case "vallocalhost": GetVarVal = "0"
    Case "vallocalport": GetVarVal = "1"
    Case "valserverip": GetVarVal = "2"
    Case "valserverport": GetVarVal = "3"
    Case "valcaption": GetVarVal = "4"
    Case "valnick": GetVarVal = "5"
    Case "valstate": GetVarVal = "6"
    Case "valserver": GetVarVal = "7"
    Case "valuserid": GetVarVal = "8"
    Case "valrealname": GetVarVal = "9"
    Case "valnickpass": GetVarVal = "10"
    Case "valpass": GetVarVal = "11"
    
    Case "valcclientmsg": GetVarVal = CoVal.ClientMSG
    Case "valcerrormsg": GetVarVal = CoVal.ErrorMSG
    Case "valcwhispermsg": GetVarVal = CoVal.FlusterVon
    Case "valclink": GetVarVal = CoVal.Link
    Case "valctext": GetVarVal = CoVal.NormalText
    Case "valcsender": GetVarVal = CoVal.NormalVon
    Case "valcnotice": GetVarVal = CoVal.Notice
    Case "valcservermsg": GetVarVal = CoVal.ServerMSG
    Case "valctimestamp": GetVarVal = CoVal.TimeStamp
    Case "valcusermsg": GetVarVal = CoVal.UserMSG
    Case "valcownnick": GetVarVal = CoVal.OwnNick
    
    Case "valcred": GetVarVal = vbRed
    Case "valcblue": GetVarVal = vbBlue
    Case "valcgreen": GetVarVal = vbGreen
    Case "valcblack": GetVarVal = vbBlack
    Case "valcwhite": GetVarVal = vbWhite
    
    Case "false": GetVarVal = "0"
    Case "true": GetVarVal = "1"
    
    Case "dataport": GetVarVal = CStr(Form1.DataPort.hWnd)
    Case "notvisible": GetVarVal = Abs(CInt(IsNotifyNess))
    Case "framecount": GetVarVal = ChatFrames.Count
    Case "ircconncount": GetVarVal = IRCconns.Count
    Case "dccconncount": GetVarVal = DCCconns.Count
    
    Case "textbox": GetVarVal = Form1.Text1.Text
    
    Case "clipboardtext": GetVarVal = Clipboard.GetText
    
    Case Else
      If ntScriptEnabled Then
        For I = 1 To UBound(VarList)
          If LCase(VarList(I).vName) = LCase(VarName) And LCase(VarList(I).vSub) = LCase(SubName) And LCase(VarList(I).Script) = LCase(ScriptName) Then
            GetVarVal = VarList(I).Value
            Exit For
          End If
        Next
        If I > UBound(VarList) Then
          For I = 1 To UBound(VarList)
            If LCase(VarList(I).vName) = LCase(VarName) And Len(VarList(I).vSub) = 0 And _
            (LCase(VarList(I).Script) = LCase(ScriptName) Or Len(VarList(I).Script) = 0) Then
              GetVarVal = VarList(I).Value
              Exit For
            End If
          Next
        End If
      End If
  End Select
End Function

Private Function SetVarVal(VarName As String, ByVal Value As String, Optional SubName As String, Optional ScriptName As String, Optional takePrivate As Boolean)
  Dim I As Integer
  
  Select Case LCase(VarName)
    Case LCase(SubName)
      CurrentRetVal = Value
    Case "textbox"
      I = Form1.Text1.SelStart
      If I = Len(Form1.Text1.Text) Or I > Len(Value) Then I = Len(Value)
      Form1.Text1.Text = Value
      Form1.Text1.SelStart = I
    Case "clipboardtext"
      SetClipboardText Value, Form1.hWnd
    Case Else
      For I = 1 To UBound(VarList)
        If LCase(VarList(I).vName) = LCase(VarName) And LCase(VarList(I).vSub) = LCase(SubName) And _
        LCase(VarList(I).Script) = LCase(ScriptName) Then Exit For
      Next
      If I > UBound(VarList) And takePrivate = False Then
        For I = 1 To UBound(VarList)
          If LCase(VarList(I).vName) = LCase(VarName) And Len(VarList(I).vSub) = 0 And _
          (LCase(VarList(I).Script) = LCase(ScriptName) Or Len(VarList(I).Script) = 0) Then Exit For
        Next
      End If
      If I > UBound(VarList) Then
        For I = 1 To UBound(VarList)
          If Len(VarList(I).vName) = 0 Then Exit For
        Next
        If I > UBound(VarList) Then
          ReDim Preserve VarList(I)
        End If
        VarList(I).vName = VarName
        VarList(I).Value = Value
        VarList(I).vSub = SubName
        VarList(I).Script = ScriptName
      Else
        VarList(I).Value = Value
      End If
  End Select
End Function

Private Function RemVar(SubName As String, ScriptName As String)
  Dim I As Integer
  For I = 1 To UBound(VarList)
    If LCase(VarList(I).vSub) = LCase(SubName) And LCase(VarList(I).Script) = LCase(ScriptName) Then
      VarList(I).vName = ""
      VarList(I).Value = ""
      VarList(I).vSub = ""
      VarList(I).Script = ""
    End If
  Next
End Function

Private Sub ScriptError(ByVal ByteNumber As Long, ErrNumber As Integer, Optional ErrDescr As String)
  Dim I As Long
  Dim I2 As Long
  Dim Lines As Integer
    
  ExitErr = True
  ntScript_Unload
  
  If AppUnloading = True Then Exit Sub
  
  Do
    Lines = Lines + 1
    I = InStr(I + 1, ntScript, vbNewLine)
  Loop Until I = 0 Or I > ByteNumber - 2
  
  ntScriptErrorDone = False
  ntScript_Call "Scr_ScriptError", CStr(Lines), CStr(ByteNumber), CStr(ErrNumber), ErrDescr
  
  If ntScriptErrorDone = False Then
    I2 = MsgBox("The following error occurs in line " & Lines & ": " + ErrDescr + vbNewLine + _
    "Display this line now?", vbCritical + vbYesNo, "ntScript  (" & ErrNumber & ")")
    If I2 = vbYes Then
      Form1.ShowScript
      If Form1.Text2.Visible = True And ByteNumber > 2 And ByteNumber < Len(Form1.Text2) - 1 Then
        I2 = ByteNumber
        Do
          I2 = I2 - 1
        Loop Until I2 < 3 Or Mid(ntScript, I2, 2) = vbNewLine
        If ByteNumber > I2 Then
            Form1.SetScriptSelection I2, ByteNumber - I2
        Else
            Form1.SetScriptSelection I2, 0
        End If
        Form1.Text2.SetFocus
      End If
    End If
  End If
End Sub




'###########################  -Phrase-  ##############################

Public Function Evaluate(Expr As String, Optional FirstError As String)
  Dim S() As Integer
  Dim I As Integer
  
  ReDim S(Len(Expr))
  For I = 1 To Len(Expr)
    S(I - 1) = AscW(Mid(Expr, I, 1))
  Next
  
  ErrorString = ""
  Position = 0
  NextPosition S
  Evaluate = Prs(1, S)
  If Token <> Chr(0) And ErrorString = "" Then
    FirstError = "Syntax Error"
  Else
    FirstError = ErrorString
  End If
  If ErrorString <> "" Then Evaluate = ""
End Function

Sub VarTest(S() As Integer)
  If IsFunction(Argument) = False Then
    Argument = """" + GetVarVal(Argument, CurrentSub, CurrentScript)
    Token = "_Txt_"
  End If
End Sub

Sub NextPosition(S() As Integer)
  Dim C As Long
  If ExitErr = True Then Exit Sub
  Token = ""
  Argument = ""
  If Position > UBound(S) Then Token = Chr(0): Exit Sub
  Do
    C = S(Position)
    Position = Position + 1
  Loop While C = 32 Or C = 9 Or C = 13 Or C = 10
  If C > 64 And C < 91 Then C = C + 32             'Großbuchstaben in kleine Buchstaben...
  Select Case C
    Case 48 To 57, 46                              '0,1,2,3,4,5,6,7,8,9 und .
      Token = "_Val_"
      Do
        Argument = Argument & ChrW(C)
        C = S(Position)
        Position = Position + 1
      Loop While (C > 47 And C < 58) Or C = 46
      Position = Position - 1
    Case 34                                        'Hochkomma
      Token = "_Txt_"
      Do
        Argument = Argument & ChrW(C)
        C = S(Position)
        Position = Position + 1
      Loop Until C = 34 Or Position > UBound(S)
    Case 97 To 122, 95, 46                            'a,b,c,...,z und Unterstrich und .
      Token = "_Func_"
      Do
        Argument = Argument & ChrW(C)
        C = S(Position)
        Position = Position + 1
      Loop While (C > 96 And C < 123) Or C = 95 Or C = 46 Or (C > 47 And C < 58) Or (C > 64 And C < 91)
      Position = Position - 1
      Select Case LCase$(Argument)
        Case "like": Token = "like"
        Case "and": Token = "and"
        Case "eqv": Token = "eqv"
        Case "imp": Token = "imp"
        Case "mod": Token = "mod"
        Case "not": Token = "not"
        Case "or": Token = "or"
        Case "xor": Token = "xor"
        Case Else: VarTest S
      End Select
    Case 60 To 62                                  '<,=,>
      Token = ChrW(C)
      C = S(Position)
      If C > 59 And C < 63 Then Token = Token + ChrW(C): Position = Position + 1
    Case Else
      Token = ChrW(C)
  End Select
  If Argument = "" Then Argument = Token
End Sub

Function ScannValue(InVal As String) As Variant
  Dim I As Long
  
  For I = 1 To Len(InVal)
    Select Case Mid(InVal, I, 1)
      Case "0" To "9", ".", "-", "E", "+"
      Case Else
        Exit For
    End Select
  Next
  If I > Len(InVal) And I < 32 And Len(InVal) > 0 Then
    If InVal = LTrim(Str(Val(InVal))) Then
      ScannValue = Val(InVal)
    Else
      ScannValue = InVal
    End If
  Else
    ScannValue = InVal
  End If
End Function

Function Prs(P As Long, S() As Integer)
  Dim FunctionName As String
  Dim IsArr As Boolean
  Dim VS As String
  Dim ArrayDimensions As Long
  Dim r(1 To 10)
  Dim ObjectName As String
  Dim Z
  Dim ColMode As Boolean
  Dim Obj As Object
  Dim Method As String
  Dim VV
  
  If ExitErr = True Then Exit Function
  ArrayDimensions = 1
  On Error Resume Next
  Select Case Token
    Case Chr(0)
      Exit Function
    Case "_Val_"
      If InStr(InStr(Argument, ".") + 1, Argument, ".") <> 0 Then
        If ErrorString = "" Then ErrorString = "Number is no double"
      End If
      r(1) = Val(Argument)
      NextPosition S
    Case "_Txt_"
      r(1) = ScannValue(Mid(Argument, 2))
      NextPosition S
    Case "-"
      NextPosition S
      r(1) = -Prs(11, S)
    Case "not"
      NextPosition S
      r(1) = Not Prs(6, S)
    Case "("
      NextPosition S
      r(1) = Prs(1, S)
      If ErrorString = "" And Token <> ")" And Token <> "," Then ErrorString = "Expected: ')' or ',' at position " & Position
      NextPosition S
    Case "_Func_", "_Arr_"
      IsArr = (Token = "_Arr_")
      FunctionName = Argument
      
      NextPosition S
      If ErrorString = "" And Not IsArr And Not IsFunction(FunctionName) Then ErrorString = "Undefined function '" & FunctionName & "' at position " & Position
      'If ErrorString = "" And Token <> "(" And Not Position > UBound(S) Then ErrorString = "Expected: '(' at position " & Position
      If ErrorString <> "" Or Token = "(" Or Position > UBound(S) Then
        NextPosition S
        r(1) = Prs(1, S)
        Do While Token = ","
          ArrayDimensions = ArrayDimensions + 1
          NextPosition S
          r(ArrayDimensions) = Prs(1, S)
        Loop
        If ErrorString = "" And Token <> ")" And Token <> Chr(0) Then ErrorString = "Expected: ')' at position " & Position
      End If
    
      NextPosition S

      Select Case LCase$(FunctionName)
        Case "abs": r(1) = Abs(r(1))
        Case "arctan": r(1) = Atn(r(1))
        Case "arccot": r(1) = Atn(1 / r(1))
        Case "cos": r(1) = Cos(r(1))
        Case "exp": r(1) = Exp(r(1))
        Case "fix": r(1) = Fix(r(1))
        Case "int": r(1) = Int(r(1))
        Case "log": r(1) = Log(r(1))
        Case "ln": r(1) = Log(r(1))
        Case "log10": r(1) = Log(r(1)) / Log(10)
        Case "lg": r(1) = Log(r(1)) / Log(10)
        Case "rndex": r(1) = Rnd(r(1))
        Case "sgn": r(1) = Sgn(r(1))
        Case "sin": r(1) = Sin(r(1))
        Case "sqr": r(1) = Sqr(r(1))
        Case "tan": r(1) = Tan(r(1))
        Case "sinh": r(1) = 0.5 * (Exp(r(1)) - Exp(-r(1)))
        Case "cosh": r(1) = 0.5 * (Exp(r(1)) + Exp(-r(1)))
        Case "tanh": r(1) = (1 - Exp(-2 * r(1))) / (1 + Exp(-2 * r(1)))
        Case "coth": r(1) = (1 + Exp(-2 * r(1))) / (1 - Exp(-2 * r(1)))
        Case "arsinh": r(1) = Log(r(1) + Sqr(r(1) * r(1) + 1))
        Case "arcosh": r(1) = Log(r(1) + Sqr(r(1) * r(1) - 1))
        Case "artanh": r(1) = 0.5 * Log((1 + r(1)) / (1 - r(1)))
        Case "arcoth": r(1) = 0.5 * Log((r(1) + 1) / (r(1) - 1))
        Case "arcsin": r(1) = Atn(r(1) / Sqr(1 - r(1) * r(1)))
        Case "arccos": r(1) = Atn(Sqr(1 - r(1) * r(1)) / r(1))
        Case "atn": r(1) = Atn(r(1))
        Case "cot": r(1) = 1 / Tan(r(1))
        Case "len": r(1) = Len(r(1))
        Case "lenb": r(1) = LenB(r(1))
        Case "asc": r(1) = Asc(r(1))
        Case "ascb": r(1) = AscB(r(1))
        Case "ascw": r(1) = AscW(r(1))
        Case "chr", "chr$": r(1) = Chr(r(1))
        Case "chrw", "chrw$": r(1) = ChrW(r(1))
        Case "left", "left$": r(1) = Left(r(1), r(2))
        Case "right", "right$": r(1) = Right(r(1), r(2))
        Case "mid", "mid$"
          If r(3) = Empty Then
            r(1) = Mid(r(1), r(2))
          Else
            r(1) = Mid(r(1), r(2), r(3))
          End If
        Case "str", "str$", "cstr": r(1) = CStr(r(1))
        Case "trim", "trim$": r(1) = Trim(r(1))
        Case "format": r(1) = Format(r(1), r(2))
        Case "instr": r(1) = InStr(r(1), r(2), r(3), r(4))
        Case "iif": r(1) = IIf(r(1), r(2), r(3))
        Case "min": r(1) = IIf(r(1) < r(2), r(1), r(2))
        Case "max": r(1) = IIf(r(1) < r(2), r(2), r(1))
        Case "isnull": r(1) = IsNull(r(1))
        Case "val": r(1) = Val(r(1))
        Case "dccconnect": r(1) = StDccConn(CStr(r(1)), CStr(r(2)), CStr(r(3)), CStr(r(4)), Val(r(5)), Val(r(6)))
        Case "dir": r(1) = Dir(CStr(r(1)), Val(r(2)))
        Case "newframe": r(1) = OpenNewWindow(CStr(r(1)))
        Case "lcase", "lcase$": r(1) = LCase(CStr(r(1)))
        Case "ucase", "ucase$": r(1) = UCase(CStr(r(1)))
        Case "msgbox": r(1) = MsgBox(CStr(r(1)), Val(r(2)), "ntScript")
        Case "inputbox", "input": r(1) = ScrInput(CStr(r(1)), CStr(r(2)))
        Case "load": r(1) = LoadScriptValue(CStr(r(1)))
        Case "getframe": r(1) = GetFrameID(r(1), CStr(r(2)))
        Case "getstateframe": r(1) = GetFrameID(r(1), "", True)
        Case "getconn": r(1) = GetConnID(r(1))
        Case "plstart": r(1) = StartPlugin(CStr(r(1)))
        Case "plstop": r(1) = UnloadPlugin(CStr(r(1)))
        Case "plsend": r(1) = SendDataToPlugin(CStr(r(1)), CStr(r(2)), CStr(r(3)))
        Case "getval": r(1) = GetConnData(Val(r(1)), r(2))
        Case "cval": r(1) = CDbl(CStr(r(1)))
        Case "hex": r(1) = Hex(Val(r(1)))
        Case "datediff": r(1) = DateDiff(CStr(r(1)), CDate(r(2)), CDate(r(3)))
        Case "getconnbyname": r(1) = GetConnByName(CStr(r(1)))
        Case "formatbytes": r(1) = FormatBytes(r(1))
        Case "formatsec": r(1) = FormatSec(r(1))
        Case "rgb": r(1) = RGB(r(1), r(2), r(3))
        Case "issilent": r(1) = Abs(CInt(IsSilent(Val(r(1)))))
        Case "getframetype": r(1) = GetFrameType(Val(r(1)))
        Case "getlistcount": r(1) = GetFListC(Val(r(1)))
        Case "getlistvalue": r(1) = GetFListV(Val(r(1)), Val(r(2)), Val(r(3)))
        Case "getlistindex": r(1) = GetListIndexByText(Val(r(1)), LCase(CStr(r(2))), Val(r(3)))
        Case "string", "string$": r(1) = String(Val(r(1)), CStr(r(2)))
        Case "encodeutf8": r(1) = EncodeUTF8(CStr(r(1)))
        Case "decodeutf8": r(1) = DecodeUTF8(CStr(r(1)))
        Case "getframebyindex": r(1) = GetFrameByIndex(Val(r(1)))
        Case "getircconnbyindex": r(1) = GetIRCConnByIndex(Val(r(1)))
        Case "getdccconnbyindex": r(1) = GetDCCConnByIndex(Val(r(1)))
        Case "nosign": r(1) = ChatNoSignGlobal(CStr(r(1)))
        Case "getcaption": r(1) = FrameCaptionByID(Val(r(1)))
        Case "split": r(1) = GetStringPart(CStr(r(1)), Val(r(2)), CStr(r(3)))
        Case "replace": r(1) = Replace(CStr(r(1)), CStr(r(2)), CStr(r(3)))
        Case "openport": r(1) = AddDCCScriptServer(Val(r(1)), Val(r(2)), Val(r(3)))
        Case "readfile": r(1) = ScrReadFile(CStr(r(1)), Val(r(2)), Val(r(3)))
        Case "ddepoke": r(1) = PokeDDEMessage(CStr(r(1)), CStr(r(2)), CStr(r(3)))
        Case "ddeexecute": r(1) = ExeDDEMessage(CStr(r(1)), CStr(r(2)), CStr(r(3)))
        Case Else
          If IsNtSFunction(FunctionName) Then
            ntScript_Call FunctionName, CStr(r(1)), CStr(r(2)), CStr(r(3)), CStr(r(4)), CStr(r(5)), False, CurrentScript, True
            r(1) = LastRetVal
          Else
            r(1) = GetArrayValue(CurrentScript, FunctionName, CStr(r(1)))
          End If
      End Select
   Case Else: If ErrorString = "" Then ErrorString = "Syntax Error at position " & Position
  End Select
  If ExitErr = True Then Exit Function
  'Operatoren
  Do While ErrorString = ""
    If False Then
      ElseIf P <= 11 And Token = "^" Then NextPosition S: r(1) = r(1) ^ Prs(12, S)
      ElseIf P <= 10 And Token = "*" Then NextPosition S: r(1) = r(1) * Prs(11, S)
      ElseIf P <= 10 And Token = "/" Then NextPosition S: r(1) = r(1) / Prs(11, S)
      ElseIf P <= 9 And Token = "\" Then NextPosition S: r(1) = r(1) \ Prs(11, S)
      ElseIf P <= 8 And Token = "mod" Then NextPosition S: r(1) = r(1) Mod Prs(9, S)
      ElseIf P <= 7 And Token = "+" Then NextPosition S: r(1) = r(1) + Prs(8, S)
      ElseIf P <= 7 And Token = "-" Then NextPosition S: r(1) = r(1) - Prs(8, S)
      ElseIf P <= 7 And Token = "&" Then NextPosition S: r(1) = r(1) & Prs(8, S)
      ElseIf P <= 6 And Token = "=" Then
        NextPosition S: VV = Prs(7, S)
        If VarType(r(1)) <> VarType(VV) Then r(1) = CStr(r(1)) = CStr(VV) Else r(1) = r(1) = VV
      ElseIf P <= 6 And Token = "<" Then NextPosition S: r(1) = r(1) < Prs(7, S)
      ElseIf P <= 6 And Token = ">" Then NextPosition S: r(1) = r(1) > Prs(7, S)
      ElseIf P <= 6 And Token = "<>" Then
        NextPosition S: VV = Prs(7, S)
        If VarType(r(1)) <> VarType(VV) Then r(1) = CStr(r(1)) <> CStr(VV) Else r(1) = r(1) <> VV
      ElseIf P <= 6 And Token = "<=" Then NextPosition S: r(1) = r(1) <= Prs(7, S)
      ElseIf P <= 6 And Token = ">=" Then NextPosition S: r(1) = r(1) >= Prs(7, S)
      ElseIf P <= 6 And Token = "like" Then NextPosition S: r(1) = r(1) Like Prs(7, S)
      ElseIf P <= 5 And Token = "and" Then NextPosition S: r(1) = r(1) And Prs(6, S)
      ElseIf P <= 4 And Token = "or" Then
        NextPosition S: r(1) = r(1) Or Prs(5, S)
      ElseIf P <= 3 And Token = "xor" Then NextPosition S: r(1) = r(1) Xor Prs(4, S)
      ElseIf P <= 2 And Token = "eqv" Then NextPosition S: r(1) = r(1) Eqv Prs(3, S)
      ElseIf P <= 1 And Token = "imp" Then NextPosition S: r(1) = r(1) Imp Prs(2, S)
      Else: Exit Do
    End If
  Loop
  Prs = r(1)
  If ErrorString = "" Then ErrorString = Err.Description
End Function

Function IsFunction(FN As String) As Boolean
  IsFunction = True
  Select Case LCase(FN)
    Case "abs"
    Case "arctan"
    Case "cos"
    Case "exp"
    Case "fix"
    Case "int"
    Case "log"
    Case "ln"
    Case "log10"
    Case "lg"
    Case "rndex"
    Case "sgn"
    Case "sin"
    Case "sqr"
    Case "tan"
    Case "len"
    Case "lenb"
    Case "asc", "ascw", "ascb"
    Case "chr", "chr$", "chrw", "chrw$"
    Case "left", "left$"
    Case "right", "right$"
    Case "mid", "mid$"
    Case "str", "str$", "cstr"
    Case "trim", "trim$"
    Case "format"
    Case "instr"
    Case "iif"
    Case "min"
    Case "max"
    Case "arccot"
    Case "arcsin"
    Case "arccos"
    Case "atn"
    Case "cot"
    Case "sinh"
    Case "cosh"
    Case "tanh"
    Case "coth"
    Case "arsinh"
    Case "arcosh"
    Case "artanh"
    Case "arcoth"
    Case "isnull"
    Case "val"
    Case "dccconnect"
    Case "connect"
    Case "dir", "dir$"
    Case "newframe"
    Case "lcase"
    Case "ucase"
    Case "msgbox"
    Case "inputbox", "input"
    Case "load"
    Case "getframe"
    Case "getstateframe"
    Case "getconn"
    Case "plstart"
    Case "plsend"
    Case "plstop"
    Case "getval"
    Case "cval"
    Case "hex"
    Case "datediff"
    Case "getconnbyname"
    Case "formatbytes"
    Case "formatsec"
    Case "rgb"
    Case "issilent"
    Case "getframetype"
    Case "getlistcount"
    Case "getlistvalue"
    Case "getlistindex"
    Case "string", "string$"
    Case "encodeutf8", "decodeutf8"
    Case "getframebyindex"
    Case "getircconnbyindex"
    Case "getdccconnbyindex"
    Case "nosign"
    Case "getcaption"
    Case "split"
    Case "replace"
    Case "openport"
    Case "readfile"
    Case "ddepoke"
    Case "ddeexecute"
    Case Else
      If ntScriptEnabled Then
        If IsNtSFunction(FN) Then
          IsFunction = True
        Else
          IsFunction = IsNtArray(FN)
        End If
      Else
        IsFunction = False
      End If
  End Select
End Function
