' VBScript CRC32txt file
' by akkorn for AkelPad
' Changed: 17:45 11.03.2013

' Usage:
' Call("Scripts::Main", 1, "CRC32txt.vbs")

' Test script:
' Text "Test" has a checksum is "784DD132"

' Declarations
Option Explicit

' Defines
Dim aCRC32Table(255)
Dim CRC32SetupExit
Dim ErrorChecksum
Const sTitleLogTab = "AkelPad plugin [CRC32txt] log:"

' Executes
Call Main
WScript.Quit(-1)

' ===============
' List procedures
' ===============

Sub Main()
Dim t, CurrCRC, StatText, StatText2, StatAvailable, Answer, d1, d2, l, m1, m2
t = AkelPad.GetSelText(0)

If t="" Then
    Msgbox "No text is selected.",, "Checksum text"
    Exit sub
End if

l = Len(t)
If l > 1000 Then l = FormatNumber(l,0)

ErrorChecksum = True
CurrCRC = CRC32Text(t)

If l<2 Then ErrorChecksum = False
    If ErrorChecksum Then
        m1 = "Chance of a checksum error." & vbcrlf & vbcrlf
        m2 = 64
    Else
        m1 = ""
        m2 = 0
    End if

CurrCRC = CStr(CurrCRC)

StatText = String (5,Chr(32))
StatText2 = PreviewText(t,l)
StatText = Now() & StatText & CurrCRC & String(8-Len(CurrCRC),Chr(32))  & StatText & "Length: " & l & StatText2

If (AkelPad.IsMDI() = 0) Then
    call MsgBox(m1 & "Checksum selection of text:" & vbTab & CurrCRC,m2,"Checksum text")
Else
    StatAvailable = LogTabIsAvailable
    If StatAvailable = True Then
        If AddTextToLogTab(StatText) = False Then
        call MsgBox(m1 & "Checksum selection of text:" & vbTab & CurrCRC & _
                    vbCrLf & "Statistics are available on one of the tabs.",m2,"Checksum text")
        End if
    Else
        Answer = MsgBox(m1 & "Checksum selection of text:" & vbTab & CurrCRC & _
                        vbCrLf & "Allow display of statistics in a new tab?",m2+260,"Checksum text")
        If Answer = vbYes Then
        'msgbox StatText
        call AddTextToLogTab(StatText)
        End if
    End if
End if

End sub

Function PreviewText(sText, sLenght)
Dim StatText,StatText2

Select Case AkelPad.GetEditNewLine(0)
    Case 1: StatText = VbCrLf
    Case 2: StatText = VbLf
    Case 3: StatText = VbCr
End Select

StatText2= sText
DO
    StatText2 = Replace(StatText2,StatText & StatText,StatText)
LOOP UNTIL (InStr(1,StatText2,StatText & StatText,1)=0)

StatText2= Replace(StatText2,StatText,Chr(124))

StatText2=Left(StatText2,30)
StatText2= String(20-len(sLenght),Chr(32)) & "First 30 chars: " & Chr(34) & StatText2 & Chr(34)
PreviewText = StatText2
End Function

Function AddTextToLogTab(sNewText)
sNewText= cStr(sNewText)
if (AkelPad.IsMDI() = 0) OR (Len(sNewText)=0) Then Exit function 'MDI or PMDI

Dim hMainWnd,lpFrameTab,lpFrameTabText,lpFrameCur,sText, i, SelectionStart, SelectionEnd, CurrLogTab, FindLogTab
Const AKD_FRAMEFINDW=1290, FWF_BYTABINDEX=8, WM_SETREDRAW=&HB, AKD_FRAMEACTIVATE=1285, AKD_GETFRAMEINFO=1223, FI_WNDEDIT=2, FWF_CURRENT=1, WM_COMMAND=273, IDM_FILE_NEW=4101

AddTextToLogTab = False
FindLogTab = False
hMainWnd = AkelPad.GetMainWnd()
i=0
lpFrameTab = AkelPad.SendMessage(hMainWnd, AKD_FRAMEFINDW, FWF_BYTABINDEX, i)

DO WHILE lpFrameTab>0
  CurrLogTab = False
  lpFrameTabText = AkelPad.SendMessage(hMainWnd, AKD_GETFRAMEINFO, FI_WNDEDIT, lpFrameTab)

  call AkelPad.SendMessage(hMainWnd, WM_SETREDRAW, false, 0)
  lpFrameCur = AkelPad.SendMessage(hMainWnd, AKD_FRAMEACTIVATE, 0, lpFrameTab)
  sText = AkelPad.GetTextRange(0, -1)
 
    if left(sText,30) = sTitleLogTab Then
      SelectionStart = AkelPad.GetSelStart()
      SelectionEnd = AkelPad.GetSelEnd()
      sText = sText & vbcr & sNewText
      call AkelPad.SetSel(0, -1)
      call AkelPad.ReplaceSel(sText,False)
      call AkelPad.SetSel(SelectionStart, SelectionEnd)
      FindLogTab = True
     
        If (lpFrameTab=lpFrameCur) Then
        CurrLogTab = True
        AddTextToLogTab = True
        End if
    End if
 
  call AkelPad.SendMessage(hMainWnd, AKD_FRAMEACTIVATE, 0, lpFrameCur)
  call AkelPad.SendMessage(hMainWnd, WM_SETREDRAW, true, 0)
 
  If CurrLogTab=True Then
  call AkelPad.SystemFunction().Call("user32.dll::InvalidateRect",lpFrameTabText,0)
  End if
 
  i = i+1
  lpFrameTab = AkelPad.SendMessage(hMainWnd, AKD_FRAMEFINDW, FWF_BYTABINDEX, i)
LOOP

If FindLogTab = False then
  'создаем новую вкладку и пишем туда текст
  call AkelPad.SendMessage(hMainWnd, WM_SETREDRAW, false, 0)
  call AkelPad.SendMessage (hMainWnd, WM_COMMAND, IDM_FILE_NEW, 0)
  lpFrameTab = AkelPad.SendMessage(hMainWnd, AKD_FRAMEFINDW, FWF_CURRENT, 0)
  lpFrameTabText = AkelPad.SendMessage(hMainWnd, AKD_GETFRAMEINFO, FI_WNDEDIT, lpFrameTab)
  sText = sTitleLogTab & vbcr & String(30,Chr(61)) & vbcr & sNewText
  call AkelPad.ReplaceSel(sText,False)
  call AkelPad.SetSel(0,0)
  call AkelPad.SendMessage(hMainWnd, AKD_FRAMEACTIVATE, 0, lpFrameCur)
  call AkelPad.SendMessage(hMainWnd, WM_SETREDRAW, true, 0)
End if

call AkelPad.SystemFunction().Call("user32.dll::InvalidateRect",hMainWnd,0)
End Function

Function LogTabIsAvailable()
if (AkelPad.IsMDI() = 0) Then Exit function 'MDI or PMDI

Dim hMainWnd,lpFrameTab,lpFrameCur,sText, i
Const AKD_FRAMEFINDW=1290, FWF_BYTABINDEX=8, WM_SETREDRAW=&HB, AKD_FRAMEACTIVATE=1285

LogTabIsAvailable = False
hMainWnd = AkelPad.GetMainWnd()
i=0
lpFrameTab = AkelPad.SendMessage(hMainWnd, AKD_FRAMEFINDW, FWF_BYTABINDEX, i)

DO WHILE lpFrameTab>0
  call AkelPad.SendMessage(hMainWnd, WM_SETREDRAW, false, 0)
  lpFrameCur = AkelPad.SendMessage(hMainWnd, AKD_FRAMEACTIVATE, 0, lpFrameTab)
  sText = AkelPad.GetTextRange(0, -1)
 
    if left(sText,30) = sTitleLogTab Then
      LogTabIsAvailable = True
    End if
 
  call AkelPad.SendMessage(hMainWnd, AKD_FRAMEACTIVATE, 0, lpFrameCur)
  call AkelPad.SendMessage(hMainWnd, WM_SETREDRAW, true, 0)
 
  i = i+1
  lpFrameTab = AkelPad.SendMessage(hMainWnd, AKD_FRAMEFINDW, FWF_BYTABINDEX, i)
LOOP
call AkelPad.SystemFunction().Call("user32.dll::InvalidateRect",hMainWnd,0)
End Function

Function CRC32Text(sText)
Dim iCRC
Call CRC32Setup
iCRC = CRC32(sText)
CRC32Text = Hex(iCRC)
End Function

Public Function CRC32(sMessage)
Dim iCRC, i, bytT, bytC, lngA, s, l

l = Len(sMessage)
If l=0 Then Exit function

Call CRC32Setup
iCRC = &HFFFFFFFF

s = Asc(Mid(sMessage, 1, 1))
For i = 1 To l
    bytC = Asc(Mid(sMessage, i, 1))
    'msgbox bytC
    If Not (bytC = s) Then ErrorChecksum = False
    s = bytC
    bytT = Abs((iCRC And &HFF) Xor bytC) Mod &H100
    lngA = ulShiftRightBy8(iCRC)
    iCRC = lngA Xor aCRC32Table(bytT)
Next

CRC32 = iCRC Xor &HFFFFFFFF
End Function

Public Function ulShiftRightBy8(x)
Dim iNew
iNew = (x And &H7FFFFFFF) \ 256
If (x And &H80000000) <> 0 Then
    iNew = iNew Or &H800000
End If
ulShiftRightBy8 = iNew
End Function

Public Function CRC32Setup()
Dim vntA, i, iOffset, nLen

If CRC32SetupExit Then
    Exit Function
End If

iOffset = 0
nLen = 32

vntA = Array( _
    &H0, &H77073096, &HEE0E612C, &H990951BA, _
    &H76DC419, &H706AF48F, &HE963A535, &H9E6495A3, _
    &HEDB8832, &H79DCB8A4, &HE0D5E91E, &H97D2D988, _
    &H9B64C2B, &H7EB17CBD, &HE7B82D07, &H90BF1D91, _
    &H1DB71064, &H6AB020F2, &HF3B97148, &H84BE41DE, _
    &H1ADAD47D, &H6DDDE4EB, &HF4D4B551, &H83D385C7, _
    &H136C9856, &H646BA8C0, &HFD62F97A, &H8A65C9EC, _
    &H14015C4F, &H63066CD9, &HFA0F3D63, &H8D080DF5)

For i = iOffset To iOffset + nLen - 1
aCRC32Table(i) = vntA(i - iOffset)
Next
iOffset = iOffset + nLen

vntA = Array( _
    &H3B6E20C8, &H4C69105E, &HD56041E4, &HA2677172, _
    &H3C03E4D1, &H4B04D447, &HD20D85FD, &HA50AB56B, _
    &H35B5A8FA, &H42B2986C, &HDBBBC9D6, &HACBCF940, _
    &H32D86CE3, &H45DF5C75, &HDCD60DCF, &HABD13D59, _
    &H26D930AC, &H51DE003A, &HC8D75180, &HBFD06116, _
    &H21B4F4B5, &H56B3C423, &HCFBA9599, &HB8BDA50F, _
    &H2802B89E, &H5F058808, &HC60CD9B2, &HB10BE924, _
    &H2F6F7C87, &H58684C11, &HC1611DAB, &HB6662D3D)

For i = iOffset To iOffset + nLen - 1
aCRC32Table(i) = vntA(i - iOffset)
Next
iOffset = iOffset + nLen

vntA = Array( _
    &H76DC4190, &H1DB7106, &H98D220BC, &HEFD5102A, _
    &H71B18589, &H6B6B51F, &H9FBFE4A5, &HE8B8D433, _
    &H7807C9A2, &HF00F934, &H9609A88E, &HE10E9818, _
    &H7F6A0DBB, &H86D3D2D, &H91646C97, &HE6635C01, _
    &H6B6B51F4, &H1C6C6162, &H856530D8, &HF262004E, _
    &H6C0695ED, &H1B01A57B, &H8208F4C1, &HF50FC457, _
    &H65B0D9C6, &H12B7E950, &H8BBEB8EA, &HFCB9887C, _
    &H62DD1DDF, &H15DA2D49, &H8CD37CF3, &HFBD44C65)

For i = iOffset To iOffset + nLen - 1
aCRC32Table(i) = vntA(i - iOffset)
Next
iOffset = iOffset + nLen

vntA = Array( _
    &H4DB26158, &H3AB551CE, &HA3BC0074, &HD4BB30E2, _
    &H4ADFA541, &H3DD895D7, &HA4D1C46D, &HD3D6F4FB, _
    &H4369E96A, &H346ED9FC, &HAD678846, &HDA60B8D0, _
    &H44042D73, &H33031DE5, &HAA0A4C5F, &HDD0D7CC9, _
    &H5005713C, &H270241AA, &HBE0B1010, &HC90C2086, _
    &H5768B525, &H206F85B3, &HB966D409, &HCE61E49F, _
    &H5EDEF90E, &H29D9C998, &HB0D09822, &HC7D7A8B4, _
    &H59B33D17, &H2EB40D81, &HB7BD5C3B, &HC0BA6CAD)
   
For i = iOffset To iOffset + nLen - 1
aCRC32Table(i) = vntA(i - iOffset)
Next
iOffset = iOffset + nLen

vntA = Array( _
    &HEDB88320, &H9ABFB3B6, &H3B6E20C, &H74B1D29A, _
    &HEAD54739, &H9DD277AF, &H4DB2615, &H73DC1683, _
    &HE3630B12, &H94643B84, &HD6D6A3E, &H7A6A5AA8, _
    &HE40ECF0B, &H9309FF9D, &HA00AE27, &H7D079EB1, _
    &HF00F9344, &H8708A3D2, &H1E01F268, &H6906C2FE, _
    &HF762575D, &H806567CB, &H196C3671, &H6E6B06E7, _
    &HFED41B76, &H89D32BE0, &H10DA7A5A, &H67DD4ACC, _
    &HF9B9DF6F, &H8EBEEFF9, &H17B7BE43, &H60B08ED5)

For i = iOffset To iOffset + nLen - 1
aCRC32Table(i) = vntA(i - iOffset)
Next
iOffset = iOffset + nLen

vntA = Array( _
    &HD6D6A3E8, &HA1D1937E, &H38D8C2C4, &H4FDFF252, _
    &HD1BB67F1, &HA6BC5767, &H3FB506DD, &H48B2364B, _
    &HD80D2BDA, &HAF0A1B4C, &H36034AF6, &H41047A60, _
    &HDF60EFC3, &HA867DF55, &H316E8EEF, &H4669BE79, _
    &HCB61B38C, &HBC66831A, &H256FD2A0, &H5268E236, _
    &HCC0C7795, &HBB0B4703, &H220216B9, &H5505262F, _
    &HC5BA3BBE, &HB2BD0B28, &H2BB45A92, &H5CB36A04, _
    &HC2D7FFA7, &HB5D0CF31, &H2CD99E8B, &H5BDEAE1D)

For i = iOffset To iOffset + nLen - 1
aCRC32Table(i) = vntA(i - iOffset)
Next
iOffset = iOffset + nLen

vntA = Array( _
    &H9B64C2B0, &HEC63F226, &H756AA39C, &H26D930A, _
    &H9C0906A9, &HEB0E363F, &H72076785, &H5005713, _
    &H95BF4A82, &HE2B87A14, &H7BB12BAE, &HCB61B38, _
    &H92D28E9B, &HE5D5BE0D, &H7CDCEFB7, &HBDBDF21, _
    &H86D3D2D4, &HF1D4E242, &H68DDB3F8, &H1FDA836E, _
    &H81BE16CD, &HF6B9265B, &H6FB077E1, &H18B74777, _
    &H88085AE6, &HFF0F6A70, &H66063BCA, &H11010B5C, _
    &H8F659EFF, &HF862AE69, &H616BFFD3, &H166CCF45)

For i = iOffset To iOffset + nLen - 1
aCRC32Table(i) = vntA(i - iOffset)
Next
iOffset = iOffset + nLen

vntA = Array( _
    &HA00AE278, &HD70DD2EE, &H4E048354, &H3903B3C2, _
    &HA7672661, &HD06016F7, &H4969474D, &H3E6E77DB, _
    &HAED16A4A, &HD9D65ADC, &H40DF0B66, &H37D83BF0, _
    &HA9BCAE53, &HDEBB9EC5, &H47B2CF7F, &H30B5FFE9, _
    &HBDBDF21C, &HCABAC28A, &H53B39330, &H24B4A3A6, _
    &HBAD03605, &HCDD70693, &H54DE5729, &H23D967BF, _
    &HB3667A2E, &HC4614AB8, &H5D681B02, &H2A6F2B94, _
    &HB40BBE37, &HC30C8EA1, &H5A05DF1B, &H2D02EF8D)

For i = iOffset To iOffset + nLen - 1
    aCRC32Table(i) = vntA(i - iOffset)
Next
iOffset = iOffset + nLen

CRC32SetupExit = True
End Function