$TYPECHECK ON
$INCLUDE <RAPIDQ2.INC>
$INCLUDE <FileOps.inc>      'this file should be in the <include> directory

DECLARE FUNCTION FBSearchText LIB "FileSearch_FB_DLL" alias "FBSearchText@20" (_
    ByVal lpSearchData AS DWORD,_
    ByVal SearchDataSiz AS INTEGER,_
    ByVal lpFindData AS DWORD, _
    ByVal FindDataSiz AS INTEGER, _
    ByVal IgnoreCase AS INTEGER) AS INTEGER

DECLARE SUB CancelSearch
DECLARE SUB ChangeDirectory
DECLARE SUB DoSearch
DECLARE SUB SearchTextEdit_KeyUp(Key AS Word, Shift AS INTEGER)


DEFSTR myFileName = ""
DEFSTR MyDir

DIM fileStream as QFileStream
DIM Buff AS QMEMORYSTREAM

CREATE MainForm AS QFORMEX
    Width = 770
    Height = 706
    Caption = "File Search, exact phrase"
    Font.Size = 12
    CREATE DirectoryTextEdit AS QEDIT
        Left = 114
        Top = 21
        Width = 453
        Height = 31
        Text = CURDIR$
    END CREATE
    CREATE SelectFolderButton AS QBUTTON
        Left = 594
        Top = 23
        Width = 96
        Caption = "Select Folder"
        OnClick = ChangeDirectory
    END CREATE
    CREATE Label1 AS QLABEL
        Left = 13
        Top = 25
        Width = 85
        Height = 24
        Caption = "Dir to scan"
    END CREATE
    CREATE Label2 AS QLABEL
        Left = 14
        Top = 69
        Caption = "Text to Search"
    END CREATE
    CREATE SearchTextEdit AS QEDIT
        Left = 116
        Top = 70
        Width = 448
        Height = 28
        Text = "RapidQ"
        OnKeyUp = SearchTextEdit_KeyUp
    END CREATE
    CREATE CaseSensitiveRadioButton AS QRADIOBUTTON
        Left = 589
        Top = 75
        Width = 143
        Caption = "Case Sensitive"
    END CREATE
    CREATE ListBox AS QLISTBOX
        Left = 32
        Top = 120
        Width = 528
        Height = 520
    END CREATE
    CREATE GoButton AS QBUTTON
        Left = 606
        Top = 463
        Width = 131
        Height = 50
        Caption = "Go"
        OnClick = DoSearch  'DoSearch_RQ_Slow
    END CREATE
    CREATE CancelButton AS QBUTTON
        Left = 606
        Top = 578
        Width = 118
        Height = 48
        Tag = False
        Caption = "Cancel"
        OnClick = CancelSearch
    END CREATE
    CREATE StatBar AS QSTATUSBAR
        Align = alBottom
        Height = 28
        SimpleText = True
    END CREATE
END CREATE

MainForm.ShowModal

SUB ChangeDirectory
    DIM OpenDialog AS QOPENDIALOG
    IF OpenDialog.Execute THEN
        MyDir = StripPath(OpenDialog.FileName)
        DirectoryTextEdit.Text = MyDir
        SetFocus(GoButton.Handle)
    END IF
END SUB


SUB DoSearch_RQ_Slow

    IF DIREXISTS(DirectoryTextEdit.Text) = False THEN
        ShowMessage "Directory does not exist"
        EXIT SUB
    END IF
    IF LTRIM$(RTRIM$(SearchTextEdit.Text)) = "" THEN
        ShowMessage "Enter search text"
        EXIT SUB
    END IF

    CHDIR DirectoryTextEdit.Text
    ListBox.Clear
    ListBox.AddItems "searching ..."
    CancelButton.Tag = False
    
    DEFINT i
    DEFSTR inChar
    DEFINT BailOut
    DEFINT FoundIt
    DEFSTR MySearchText = SearchTextEdit.Text
    IF CaseSensitiveRadioButton.Checked = False THEN MySearchText = UCASE$(MySearchText)
    DEFINT Critern = LEN(MySearchText) + 1      'save computations
    DEFSTR MyFirstByte = LEFT$(MySearchText, 1)

    myFileName = DIR$("*.*", 0) '-- Get first file
    WHILE ((myFileName <> "") AND (CancelButton.Tag = False) )
        IF fileStream.Open(myFileName , fmOpenRead) THEN
            Buff.Position = 0
            Buff.Size = 0
            Buff.Close
            buff.CopyFrom (fileStream, fileStream.Size)
            Buff.Position = 0
            fileStream.Close
            StatBar.SimpleText = myFileName       'MainForm.TextOut(10, MainForm.ClientHeight -20, myFileName, clBlack, clWhite)
            DOEVENTS
            DO
                BailOut = False
                FoundIt = False
                inChar = Buff.ReadBinStr(1)
                IF ASC(inChar) > 31 THEN             'skip unicode, etc.
                    IF (CaseSensitiveRadioButton.Checked = False) THEN inChar = UCASE$(inChar)
                    i = 0
                    IF inChar = MyFirstByte THEN
                        i = 2
                        DO
                            inChar = Buff.ReadBinStr(1)
                            IF ASC(inChar) > 31 THEN            'skip unicode, etc.
                                IF (CaseSensitiveRadioButton.Checked = False) THEN inChar = UCASE$(inChar)
                                IF (inChar = MID$(MySearchText, i, 1)) THEN
                                    i++
                                ELSE
                                    BailOut = True
                                END IF
                            END IF
                        LOOP UNTIL ((i = Critern) OR (Buff.Position = Buff.Size) OR BailOut OR (CancelButton.Tag = True) )
                        IF (i = Critern) THEN
                            FoundIt = True
                            'ListBox.AddItems StripFileName(myFileName)
                            ListBox.AddItems (myFileName)
                        END IF
                        DOEVENTS
                    END IF
                END IF
            LOOP UNTIL ( (Buff.Position = Buff.Size) OR FoundIt OR CancelButton.Tag )
        END IF
        myFileName = DIR$                                           'get next file in data folder, if none matching spec, returns null
    WEND
    IF CancelButton.Tag THEN
        ShowMessage "Cancelled search"
    ELSE
        ShowMessage "Finished search"
    END IF
    IF MessageDlg("Save list?", mtWarning, mbYes OR mbNo, 0) = mrYes THEN
        ListBox.SaveToFile "Search_Results.txt"
    END IF
END SUB

SUB CancelSearch
    CancelButton.Tag = True
END SUB

SUB SearchTextEdit_KeyUp(Key AS Word, Shift AS INTEGER)
    IF Key = 13 THEN DoSearch
END SUB

SUB DoSearch
    IF DIREXISTS(DirectoryTextEdit.Text) = False THEN
        ShowMessage "Directory does not exist"
        EXIT SUB
    END IF
    IF LTRIM$(RTRIM$(SearchTextEdit.Text)) = "" THEN
        ShowMessage "Enter search text"
        EXIT SUB
    END IF

    CHDIR DirectoryTextEdit.Text
    ListBox.Clear
    ListBox.AddItems "searching ..."
    CancelButton.Tag = False

    DEFSTR MySearchText = SearchTextEdit.Text
    IF CaseSensitiveRadioButton.Checked = False THEN MySearchText = UCASE$(MySearchText)
    DEFINT Critern = LEN(MySearchText) + 1      'save computations
    DEFSTR MyFirstByte = LEFT$(MySearchText, 1)

    myFileName = DIR$("*.*", 0) '-- Get first file
    WHILE ((myFileName <> "") AND (CancelButton.Tag = False) )
        IF fileStream.Open(myFileName , fmOpenRead) THEN
            Buff.Position = 0
            Buff.Size = 0
            Buff.Close
            buff.CopyFrom (fileStream, fileStream.Size)
            Buff.Position = 0
            fileStream.Close
            StatBar.SimpleText = myFileName       'MainForm.TextOut(10, MainForm.ClientHeight -20, myFileName, clBlack, clWhite)
            DOEVENTS
            IF FBSearchText(buff.Pointer, buff.Size, VARPTR(MySearchText), LEN(MySearchText), 1) > 0 THEN
                ListBox.AddItems (myFileName)       'StripFileName(myFileName)
            END IF
        END IF
        myFileName = DIR$                                           'get next file in data folder, if none matching spec, returns null
    WEND

    IF CancelButton.Tag THEN
        ShowMessage "Cancelled search"
    ELSE
        ShowMessage "Finished search"
    END IF

    IF MessageDlg("Save list?", mtWarning, mbYes OR mbNo, 0) = mrYes THEN
        ListBox.SaveToFile "Search_Results.txt"
    END IF
END SUB
