#   Programmer: Franz Steinhaeusler
#   E-mail:     francescoa@users.sourceforge.net
#   Note:       You must reply to the verification e-mail to get through.
#
#   Copyright 2004-2005 Franz Steinhaeusler
#
#   Distributed under the terms of the GPL (GNU Public License)
#
#    DrPython is free software; you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation; either version 2 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program; if not, write to the Free Software
#    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

# Version 0.0.1 27.07.2004
# new:
#   - ctrl-p (previous occurence), ctrl-n (next occurence)
#   - find All Words in Document as option
#     (in larger documents, it takes some time; i will try to optimize later)
#   - try always to autocomplete now; without hindering the text input
# Many thanks to Dan, who encouraged me to continue with this plugin!
# packaged in subfolder

#Version 0.0.2 27.07.2004
#eliminated duplicated code with "rangecycle"

#Version 0.0.3 29.07.2004
#delete key should work now
#please delete shortcutsfile and assign the key binding again
#(the function name has changed)
#(All words in document) is off default now.

#Version 0.0.4 07.08.2004
#Version 0.0.5 28.08.2004
#Version 0.0.6 14.10.2004
#Version 0.0.7 04.11.2004
#Version 0.0.8 21.11.2004
#Version 0.0.9 27.12.2004
#Version 0.1.0 21.01.2005
#Version 0.1.1 25.02.2007
#Version 0.1.2 08.04.2007

# - see Changelog for details

#Plugin
#FindAutoComplete

#todo: comment this out again
#for pychecker
#import sys
#sys.path.append('c:/Eigene Dateien/python/drpython')

import wx
import drFindReplaceDialog
import drScrolledMessageDialog
import os
import drPrefsFile
import re
import string
from drRegularExpressionDialog import drRegularExpressionDialog
import drShortcutsDialog

def OnAbout(DrFrame):
    Version = "0.1.2"
    NameAndVersion = "FindAutoComplete:\n\nVersion: " + Version + "\n"
    AboutString = NameAndVersion + "By Franz Steinhaeusler\n\nReleased under the GPL."
    drScrolledMessageDialog.ShowMessage(DrFrame, AboutString, "About")

def OnHelp(DrFrame):
    drScrolledMessageDialog.ShowMessage(DrFrame, "Suggests completitions for find dialog.", "Help")

def OnPreferences(DrFrame):
    d = FindAutoCompletePrefsDialog(DrFrame, -1)
    d.ShowModal()
    d.Destroy()

def UnInstall(DrFrame):
    prefsfile = DrFrame.pluginspreferencesdirectory + "/FindAutoComplete.preferences.dat"
    if os.path.exists(prefsfile):
        os.remove(prefsfile)

class FindAutoCompletePrefsDialog(wx.Dialog):

    def __init__(self, parent, id):

        wx.Dialog.__init__(self, parent, id, "FindAutoComplete Preferences", wx.Point(50, 50), \
                        wx.Size(300, 196), wx.DEFAULT_DIALOG_STYLE | wx.MAXIMIZE_BOX | wx.THICK_FRAME | wx.RESIZE_BORDER)

        self.parent = parent

        self.chkstrongautocomplete = wx.CheckBox(self, -1, "")
        self.chkstrongautocomplete.SetValue(self.parent.FindAutoComplete_strongautocomplete)
        self.chkmyfromcursor = wx.CheckBox(self, -1, "")
        self.chkmyfromcursor.SetValue(self.parent.FindAutoComplete_myfromcursor)
        self.chkquickfindtext = wx.CheckBox(self, -1, "")
        self.chkquickfindtext.SetValue(self.parent.FindAutoComplete_quickfindtext)
        self.chkusemyreplacedialog = wx.CheckBox(self, -1, "")
        self.chkusemyreplacedialog.SetValue(self.parent.FindAutoComplete_usemyreplacedialog)
        self.chkintellireplace = wx.CheckBox(self, -1, "")
        self.chkintellireplace.SetValue(self.parent.FindAutoComplete_useintellireplacedefault)

        self.theSizer = wx.FlexGridSizer(7, 3, 5, 10)

        self.theSizer.Add(wx.StaticText(self, -1, "   "), 1, wx.SHAPED)
        self.theSizer.Add(wx.StaticText(self, -1, "   "), 1, wx.SHAPED)
        self.theSizer.Add(wx.StaticText(self, -1, "   "), 1, wx.SHAPED)

        self.theSizer.Add(wx.StaticText(self, -1, "Strong AutoComplete:"),1,wx.GROW)
        self.theSizer.Add(self.chkstrongautocomplete, 1, wx.SHAPED)
        self.theSizer.Add(wx.StaticText(self, -1, "   "), 1, wx.SHAPED)

        self.theSizer.Add(wx.StaticText(self, -1, "My Find From Cursor:"),1,wx.GROW)
        self.theSizer.Add(self.chkmyfromcursor, 1, wx.SHAPED)
        self.theSizer.Add(wx.StaticText(self, -1, "   "), 1, wx.SHAPED)

        self.theSizer.Add(wx.StaticText(self, -1, "Enable Quick FindText:"),1,wx.GROW)
        self.theSizer.Add(self.chkquickfindtext, 1, wx.SHAPED)
        self.theSizer.Add(wx.StaticText(self, -1, "   "), 1, wx.SHAPED)

        self.theSizer.Add(wx.StaticText(self, -1, "Use My Replace Dialog:"),1,wx.GROW)
        self.theSizer.Add(self.chkusemyreplacedialog, 1, wx.SHAPED)
        self.theSizer.Add(wx.StaticText(self, -1, "   "), 1, wx.SHAPED)

        self.theSizer.Add(wx.StaticText(self, -1, "Default Intelli Replace:"),1,wx.GROW)
        self.theSizer.Add(self.chkintellireplace, 1, wx.SHAPED)
        self.theSizer.Add(wx.StaticText(self, -1, "   "), 1, wx.SHAPED)

        self.theSizer.Add(wx.StaticText(self, -1, "   "), 1, wx.SHAPED)
        self.theSizer.Add(wx.StaticText(self, -1, "   "), 1, wx.SHAPED)
        self.theSizer.Add(wx.StaticText(self, -1, "   "), 1, wx.SHAPED)

        self.buttonSizer = wx.BoxSizer(wx.HORIZONTAL)

        self.btnCancel = wx.Button(self, wx.ID_CANCEL, "&Close")
        self.btnSave = wx.Button(self, wx.ID_OK, "&Save")
        self.btnCancel.SetDefault()

        self.buttonSizer.Add(self.btnCancel, 1, wx.SHAPED)
        self.buttonSizer.Add(self.btnSave, 1, wx.GROW)

        self.theSizer.Add(self.buttonSizer, 0, wx.SHAPED | wx.ALIGN_CENTER)
        self.theSizer.Add(wx.StaticText(self, -1, "   "), 0, wx.SHAPED | wx.ALIGN_CENTER)
        self.theSizer.Add(wx.StaticText(self, -1, "   "), 0, wx.SHAPED | wx.ALIGN_CENTER)


        self.SetAutoLayout(True)
        self.SetSizer(self.theSizer)

        self.Bind(wx.EVT_BUTTON,  self.OnbtnClose, id = wx.ID_CANCEL)
        self.Bind(wx.EVT_BUTTON,  self.OnbtnSave, id = wx.ID_OK)


    def OnbtnClose(self, event):
        self.EndModal(0)

    def OnbtnSave (self, event):
        self.parent.FindAutoComplete_strongautocomplete = int(self.chkstrongautocomplete.GetValue())
        self.parent.FindAutoComplete_myfromcursor = int(self.chkmyfromcursor.GetValue())
        self.parent.FindAutoComplete_quickfindtext = int(self.chkquickfindtext.GetValue())
        self.parent.FindAutoComplete_usemyreplacedialog = int(self.chkusemyreplacedialog.GetValue())
        self.parent.FindAutoComplete_useintellireplacedefault = int(self.chkintellireplace.GetValue())
        
        f = file(self.parent.pluginspreferencesdirectory + "/FindAutoComplete.preferences.dat", 'w')
        f.write("<findautocomplete.strongautocomplete>" + str(self.parent.FindAutoComplete_strongautocomplete) + "</findautocomplete.strongautocomplete>\n")
        f.write("<findautocomplete.myfromcursor>" + str(self.parent.FindAutoComplete_myfromcursor) + "</findautocomplete.myfromcursor>\n")
        f.write("<findautocomplete.quickfindtext>" + str(self.parent.FindAutoComplete_quickfindtext) + "</findautocomplete.quickfindtext>\n")
        f.write("<findautocomplete.usemyreplacedialog>" + str(self.parent.FindAutoComplete_usemyreplacedialog) + "</findautocomplete.usemyreplacedialog>\n")
        f.write("<findautocomplete.useintellireplacedefault>" + str(self.parent.FindAutoComplete_useintellireplacedefault) + "</findautocomplete.useintellireplacedefault>\n")
        f.close()


class drMyRegularExpressionDialog(drRegularExpressionDialog):
    def __init__(self, parent, id, title, prompthasfocus = 0, infiles = 0):
        drRegularExpressionDialog.__init__(self, parent, id, title, prompthasfocus, infiles)

    def OnbtnOk(self, event):
        self.Show(0)

        result = self.txtRE.GetValue()
        l = len(result)
        if l > 0:
            self.parent.panel.cBoxSearchFor.SetValue(result)

        self.Close(1)


class MyCheckBox (wx.CheckBox):
    def __init__(self, parent, id, label):
        self.parent = parent
        wx.CheckBox.__init__(self, parent, id, label)
        self.Bind (wx.EVT_CHECKBOX, self.OnCheckBox)

    def OnCheckBox (self, event):
        s, e = self.parent.txtSearchFor.sel_start, self.parent.txtSearchFor.sel_end
        self.parent.txtSearchFor.SetFocus()
        self.parent.txtSearchFor.SetMark (s, e)
        event.Skip()

class ReplaceDialog (wx.Dialog):
    def __init__(self, parent, id, findtext, line, col):

        wx.Dialog.__init__(self, parent, id, "Intelli Replace", wx.DefaultPosition, \
                        wx.Size(540, 155), wx.DEFAULT_DIALOG_STYLE | wx.MAXIMIZE_BOX | wx.THICK_FRAME | wx.RESIZE_BORDER)

        self.parent = parent
        self.findtext = wx.StaticText(self, -1, "Found at line: %d, col: %d" % (line, col), pos = (20, 10))
        self.findtextstatic = wx.StaticText(self, -1, "Find text:", pos = (20, 40))
        self.replacetextstatic = wx.StaticText(self, -1, "Replace text:", pos = (20, 65))
        self.intellireplacetextstatic = wx.StaticText(self, 6002, "Intelli replace text:", pos = (250, 65))
        self.findtext = wx.TextCtrl(self, -1, findtext, pos = (120, 36), style = wx.TE_READONLY)
        self.replacetext = wx.TextCtrl(self, -1, "", pos = (120, 61), style = wx.TE_READONLY)
        self.intellireplacetext = wx.TextCtrl(self, -1, findtext, pos = (350, 61), style = wx.TE_READONLY)
        self.chkIntelliReplace = wx.CheckBox(self, -1, "Us&e IntelliReplace as Default", wx.Point(250, 45))
        self.chkIntelliReplace.SetValue (self.parent.parent.FindAutoComplete_useintellireplacedefault)
        self.btnCancel = wx.Button(self, wx.ID_CANCEL, "&Cancel", size = (90, 23), pos = (20, 95))
        self.btnSkip = wx.Button(self, self.parent.ID_BTNSKIP, "&Skip", size = (90, 23), pos = (120, 95))
        self.btnReplace = wx.Button(self, wx.ID_OK, "&Replace", size = (90, 23), pos = (220, 95))
        self.btnIntelliReplace = wx.Button(self, self.parent.ID_BTNINTELLIREPLACE, "&Intelli Replace", size = (90, 23), pos = (320, 95))
        self.btnUndo = wx.Button(self, self.parent.ID_BTNUNDO, "&Undo Last", size = (90, 23), pos = (420, 95))
        self.btnUndo.Enable(self.parent.canundo)

        self.findtext.SetBackgroundColour (wx.Colour(185, 185, 200))
        self.replacetext.SetBackgroundColour (wx.Colour(235, 235, 192))
        self.intellireplacetext.SetBackgroundColour (wx.Colour(224, 192, 160))
        #todo: bug in wxPython? this does nothing
        if self.parent.parent.FindAutoComplete_useintellireplacedefault:
            self.btnIntelliReplace.SetFocus()
        else:
            self.btnReplace.SetFocus()
        self.Bind(wx.EVT_BUTTON,  self.OnbtnClose, id = wx.ID_CANCEL)
        self.Bind(wx.EVT_BUTTON,  self.OnbtnReplace, id = wx.ID_OK)
        self.Bind(wx.EVT_BUTTON,  self.OnbtnSkip, id = self.parent.ID_BTNSKIP)
        self.Bind(wx.EVT_BUTTON,  self.OnbtnIntelliReplace, id = self.parent.ID_BTNINTELLIREPLACE)
        self.Bind(wx.EVT_BUTTON,  self.OnbtnUndo, id = self.parent.ID_BTNUNDO)
        self.Bind(wx.EVT_CHECKBOX,self.OnIntelliCheckBox, id = -1)

    def SetReplaceText(self, replacetext):
        self.replacetext.SetValue (replacetext)

    def SetIntelliReplaceText(self, intellireplacetext):
        self.intellireplacetext.SetValue (intellireplacetext)

    def OnIntelliCheckBox (self, event):
        self.parent.parent.FindAutoComplete_useintellireplacedefault = self.chkIntelliReplace.GetValue()
        if self.parent.parent.FindAutoComplete_useintellireplacedefault:
            self.btnIntelliReplace.SetFocus()
        else:
            self.btnReplace.SetFocus()
        event.Skip()

    def OnbtnClose(self, event):
        event.Skip()

    def OnbtnReplace (self, event):
        event.Skip()

    def OnbtnSkip (self, event):
        self.EndModal(self.parent.ID_BTNSKIP)
        event.Skip()

    def OnbtnIntelliReplace (self, event):
        self.EndModal(self.parent.ID_BTNINTELLIREPLACE)
        event.Skip()

    def OnbtnUndo (self, event):
        self.EndModal(self.parent.ID_BTNUNDO)
        event.Skip()


class drFindAutoCompleteDialog(drFindReplaceDialog.drFindReplaceDialog):

    def __init__(self, parent, id, title, stc, IsReplace = 0):

        #drFindReplaceDialog.drFindReplaceDialog.__init__(self, parent, id, title, stc)
        wx.Dialog.__init__(self, parent, id, title, wx.Point(50, 50), wx.Size(375, 300),
            wx.DEFAULT_DIALOG_STYLE | wx.MAXIMIZE_BOX | wx.THICK_FRAME | wx.RESIZE_BORDER)
        #if wx.VERSION_STRING <= "2.7":
        #    wx.Dialog.__init__(self, parent, id, title, wx.Point(50, 50), wx.Size(375, 300), wx.DEFAULT_DIALOG_STYLE | wx.MAXIMIZE_BOX | wx.THICK_FRAME | wx.RESIZE_BORDER)
        #alas, much duplicated code from the core
        self.ID_FIND = 1001
        self.ID_CANCEL = 1002

        self.ID_CHK_REGEX = 1010
        self.ID_CREATERE = 1011
        self.ID_CHK_ALLWORDS = 1012
        self.ID_SEARCH_TXT = 1013
        self.ID_SEARCH_TXT_FOCUS = 1020
        self.ID_REPLACEWITH_TXT_FOCUS = 1021

        self.ID_BTNSF = 98
        self.ID_BTNRW = 99

        self.parent = parent
        
        self.stc = stc

        self.ListAllWords = []
        self.theSizer = wx.FlexGridSizer(8, 3, 5, 10)

        self.IsReplace = IsReplace

        self.theSizer.Add(wx.StaticText(self, -1, "    "), 1, wx.SHAPED)
        self.theSizer.Add(wx.StaticText(self, -1, "    "), 1, wx.SHAPED)
        self.theSizer.Add(wx.StaticText(self, -1, "    "), 1, wx.SHAPED)

        self.theSizer.Add(wx.StaticText(self, -1, "    "), 1, wx.SHAPED)
        self.theSizer.Add(wx.StaticText(self, -1, "Search &For: "), 1, wx.SHAPED)
        self.theSizer.Add(wx.StaticText(self, -1, "    "), 1, wx.SHAPED)

        self.txtSearchFor = self.drFindTextAutoCompleteCtrl(self, self.ID_SEARCH_TXT, "", wx.DefaultPosition, wx.Size(200, -1))
        if IsReplace:
            self.txtReplaceWith = self.drFindTextAutoCompleteCtrl(self, -1, "", wx.DefaultPosition, wx.Size(200, -1))
        self.btnPopUpSearchFor = wx.Button(self, self.ID_BTNSF, "&Edit")
        self.theSizer.Add(wx.StaticText(self, -1, "    "), 1, wx.SHAPED)
        self.theSizer.Add(self.txtSearchFor, 1 ,wx.SHAPED)
        self.theSizer.Add(self.btnPopUpSearchFor, 1, wx.SHAPED)

        parent.FindAutoComplete_isGlobal = False
        if not parent.FindAutoComplete_isGlobal:
            self.txtSearchFor.SetHistory(parent.FindHistory)
        else:
            self.GetAllWordsInDoc()
            self.txtSearchFor.SetHistory(self.ListAllWords)
        self.chkAllWords = MyCheckBox(self, self.ID_CHK_ALLWORDS, "A&ll Words in Document")

        if IsReplace:
            self.btnPopUpReplaceWith = wx.Button(self, self.ID_BTNRW, "E&dit")
            self.txtReplaceWith.SetHistory(parent.ReplaceHistory)


        self.chkRegularExpression = MyCheckBox(self, self.ID_CHK_REGEX, "&RegularExpression")
        self.btnCreateRE = wx.Button(self, self.ID_CREATERE, " Cre&ate ")
        self.chkMatchCase = MyCheckBox(self, -1, "&Match Case")
        self.chkFindBackwards = MyCheckBox(self, -1, "Find &Backwards")
        self.chkWholeWord = MyCheckBox(self, -1, "&Whole Word")
        self.chkInSelection = MyCheckBox(self, -1, "&In Selection")
        self.chkFromCursor = MyCheckBox(self, -1, "From C&ursor")

        #Prefs
        self.chkRegularExpression.SetValue(parent.prefs.findreplaceregularexpression)
        self.chkAllWords.SetValue(parent.FindAutoComplete_isGlobal)
        self.btnCreateRE.Enable(parent.prefs.findreplaceregularexpression)
        self.chkMatchCase.SetValue(parent.prefs.findreplacematchcase)
        self.chkFindBackwards.SetValue(parent.prefs.findreplacefindbackwards)
        self.chkWholeWord.SetValue(parent.prefs.findreplacewholeword)
        self.chkInSelection.SetValue(parent.prefs.findreplaceinselection)
        self.chkFromCursor.SetValue(parent.prefs.findreplacefromcursor)

        self.chkInSelection.Enable(len(parent.txtDocument.GetSelectedText()) > 0)
        self.theSizer.Add(wx.StaticText(self, -1, "    "), 1, wx.SHAPED)
        self.theSizer.Add(self.chkAllWords, 1, wx.SHAPED)
        self.theSizer.Add(wx.StaticText(self, -1, "    "), 1, wx.SHAPED)

        if IsReplace:
            self.chkPromptOnReplace  = MyCheckBox(self, -1, "Promp&t on Replace")
            self.theSizer.Add(wx.StaticText(self, -1, "    "), 1, wx.SHAPED)
            self.theSizer.Add(wx.StaticText(self, -1, "Re&place With: "), 1, wx.SHAPED)
            self.theSizer.Add(wx.StaticText(self, -1, "    "), 1, wx.SHAPED)

            self.theSizer.Add(wx.StaticText(self, -1, "    "), 1, wx.SHAPED)
            self.theSizer.Add(self.txtReplaceWith, 1 ,wx.SHAPED)
            self.theSizer.Add(self.btnPopUpReplaceWith, 1, wx.SHAPED)

            self.chkFindBackwards.Disable()

            #Prefs
            self.chkPromptOnReplace.SetValue(parent.prefs.findreplacepromptonreplace)

            self.Bind(wx.EVT_BUTTON,  self.OnbtnPopUp, id=self.ID_BTNRW)

        self.theSizer.Add(wx.StaticText(self, -1, "    "), 1, wx.SHAPED)
        self.theSizer.Add(wx.StaticText(self, -1, "    "), 1, wx.SHAPED)
        self.theSizer.Add(wx.StaticText(self, -1, "    "), 1, wx.SHAPED)


        self.theSizer.Add(wx.StaticText(self, -1, "    "), 1, wx.SHAPED)
        self.theSizer.Add(self.chkRegularExpression, 1, wx.SHAPED)
        self.theSizer.Add(self.btnCreateRE, 1, wx.SHAPED)


        self.theSizer.Add(wx.StaticText(self, -1, "    "), 1, wx.SHAPED)
        self.theSizer.Add(self.chkMatchCase, 1, wx.SHAPED)
        self.theSizer.Add(self.chkFindBackwards, 1, wx.SHAPED)
        self.theSizer.Add(wx.StaticText(self, -1, "    "), 1, wx.SHAPED)
        self.theSizer.Add(self.chkWholeWord, 1, wx.SHAPED)
        self.theSizer.Add(self.chkInSelection, 1, wx.SHAPED)
        self.theSizer.Add(wx.StaticText(self, -1, "    "), 1, wx.SHAPED)
        self.theSizer.Add(self.chkFromCursor, 1, wx.SHAPED)
        if IsReplace:
            self.theSizer.Add(self.chkPromptOnReplace, 1, wx.SHAPED)
        else:
            self.theSizer.Add(wx.StaticText(self, -1, "    "), 1, wx.SHAPED)
        self.theSizer.Add(wx.StaticText(self, -1, "    "), 1, wx.SHAPED)
        self.theSizer.Add(wx.StaticText(self, -1, "    "), 1, wx.SHAPED)
        self.theSizer.Add(wx.StaticText(self, -1, "    "), 1, wx.SHAPED)

        self.btnCancel = wx.Button(self, wx.ID_CANCEL, "&Cancel")
        self.btnFind = wx.Button(self, self.ID_FIND, "&Ok")


        self.theSizer.Add(wx.StaticText(self, -1, "    "), 1, wx.SHAPED)
        self.theSizer.Add(self.btnCancel, 1, wx.SHAPED)
        self.theSizer.Add(self.btnFind, 1, wx.SHAPED)


        self.SetAutoLayout(True)
        self.SetSizerAndFit(self.theSizer)

        self.btnFind.SetDefault()
        self.txtSearchFor.SetFocus()

        tbl = wx.AcceleratorTable([(wx.ACCEL_ALT, ord('F'), self.ID_SEARCH_TXT_FOCUS)
                                ,(wx.ACCEL_ALT, ord('P'), self.ID_REPLACEWITH_TXT_FOCUS)])
        self.SetAcceleratorTable(tbl)


        self.Bind(wx.EVT_MENU, self.OnSearchForFocus, id = self.ID_SEARCH_TXT_FOCUS)
        self.Bind(wx.EVT_MENU, self.OnReplaceWithFocus, id = self.ID_REPLACEWITH_TXT_FOCUS)

        self.Bind(wx.EVT_BUTTON,  self.OnbtnCancel, id = wx.ID_CANCEL)
        self.Bind(wx.EVT_BUTTON,  self.OnbtnFind, id=self.ID_FIND)
        self.Bind(wx.EVT_BUTTON,  self.OnbtnCreateRE, id=self.ID_CREATERE)
        self.Bind(wx.EVT_BUTTON,  self.OnbtnPopUp, id=self.ID_BTNSF)
        self.Bind(wx.EVT_CHECKBOX,  self.OnCheckAllWords, id=self.ID_CHK_ALLWORDS)

        self.Bind(wx.EVT_CHECKBOX,  self.OnCheckRegularExpression, id=self.ID_CHK_REGEX)
        self.btnFind.Enable()
        self.parent.LoadDialogSizeAndPosition(self, 'findreplacedialog.sizeandposition.dat')

    def OnbtnCancel(self, event):
        #workaround
        focuswindow = wx.Window.FindFocus()
        if isinstance (focuswindow, wx.TextCtrl):
            if focuswindow.GetParent().GetTitle() == "Create Regular Expression":
                focuswindow.GetParent().Destroy()
                return
        self.Destroy()

    def OnSearchForFocus(self, event):
        self.txtSearchFor.SetFocus()

    def OnReplaceWithFocus(self, event):
        if self.IsReplace:
            self.txtReplaceWith.SetFocus()

    def MyReplaceAll(self, findtext, replacetext, flags, prompt = 0):
        self.ID_BTNUNDO = self.parent.GetNewId()
        self.ID_BTNSKIP = self.parent.GetNewId()
        self.ID_BTNINTELLIREPLACE = self.parent.GetNewId()
        self.targetEnd = self.parent.txtDocument.GetTextLength()
        self.targetStart = self.parent.txtDocument.GetCurrentPos()

        self.txtSearchFor.AppendToHistory(self.parent.FindHistory)
        self.parent.ReplaceOptions = self.GetOptions()
        self.txtReplaceWith.AppendToHistory(self.parent.ReplaceHistory)

        p = self.parent.txtDocument.FindText(self.targetStart , self.parent.txtDocument.GetTextLength(), findtext, flags)
        if p == -1:
            msgtext = 'Search string "' + findtext + '" not found.\n'
            msgtext += "(From Line: %d, Col: %d)" % (self.parent.txtDocument.LineFromPosition(self.targetStart)+1, self.parent.txtDocument.GetColumn(self.targetStart) + 1)
            wx.MessageBox(msgtext, "My Replace", wx.ICON_EXCLAMATION)
            return
        if prompt:
            wx.CallAfter (self.parent.txtDocument.SetSelection, p, p + len(findtext))
        if not prompt:
            answer = wx.MessageBox("Replace all without prompting?", "Warning", wx.YES_NO | wx.ICON_QUESTION)
            if answer != wx.YES:
                return

        diff = len(replacetext) - len(findtext)
        x = 0
        favpos = wx.DefaultPosition
        self.canundo = False
        while p != -1:
            if self.parent.prefs.docfolding:
                self.parent.txtDocument.EnsureVisible(self.parent.txtDocument.LineFromPosition(p))
            self.parent.txtDocument.GotoPos(p)
            self.parent.txtDocument.EnsureCaretVisible()
            self.parent.txtDocument.SetTargetStart(p)
            self.parent.txtDocument.SetTargetEnd(p + len(findtext))

            intellireplacetext = ''
            foundtext = self.parent.txtDocument.GetTextRange(p, p + len (findtext))
            #preview intellireplace
            #all lowercase? yes => all replace lowercase
            #first uppercase? => also uppercase
            if replacetext:
                if len(replacetext) != len(foundtext):
                    if foundtext.islower():
                        intellireplacetext = replacetext.lower()
                    elif foundtext.isupper():
                        intellireplacetext = replacetext.upper()
                    else:
                        if foundtext[0] == string.upper(foundtext[0]):
                            intellireplacetext = replacetext[0].upper() + replacetext[1:]
                        else:
                            intellireplacetext = replacetext
                else:
                    for i in range(len (foundtext)):
                        if foundtext[i].lower() == foundtext[i]:
                            newchar = replacetext[i].lower()
                        else:
                            newchar = replacetext[i].upper()
                        intellireplacetext += newchar
            else:
                intellireplacetext = replacetext

            if prompt:
                d = ReplaceDialog(self, -1, findtext, self.parent.txtDocument.LineFromPosition(p)+1, self.parent.txtDocument.GetColumn(p))

                d.SetReplaceText(replacetext)
                d.SetIntelliReplaceText (intellireplacetext)

                d.Move(favpos)
                self.Hide()
                answer = d.ShowModal()
                favpos = d.GetPosition()
                d.Destroy()
                self.Show()
                if answer != wx.ID_CANCEL:
                    if answer == wx.ID_OK or answer == self.ID_BTNINTELLIREPLACE:
                        self.canundo = True

                        self.oldreplacedstart = p
                        self.oldreplacedend = p + len (replacetext)
                        self.oldfindtext = self.parent.txtDocument.GetTextRange (p, p + len (findtext))
                        self.targetEnd = self.targetEnd + diff
                        to_replace = replacetext
                    if answer == self.ID_BTNINTELLIREPLACE:
                        to_replace = intellireplacetext

                    if answer == self.ID_BTNSKIP:
                        x = x - 1
                        p = p + 1
                    else:
                        self.parent.txtDocument.ReplaceTarget(to_replace)
                    #undo last
                    if answer == self.ID_BTNUNDO:
                        if self.canundo:
                            self.canundo = False
                            self.parent.txtDocument.SetTargetStart (self.oldreplacedstart)
                            self.parent.txtDocument.SetTargetEnd (self.oldreplacedend)
                            self.parent.txtDocument.ReplaceTarget(self.oldfindtext)
                            p = self.oldreplacedstart - len(replacetext)
                    p = self.parent.txtDocument.FindText((p + len(replacetext)), self.targetEnd, findtext, flags)
                    wx.CallAfter (self.parent.txtDocument.SetSelection,p, p + len(findtext))

                #cancel
                else:
                    p = -1
                    x = x - 1
            else:
                self.parent.txtDocument.ReplaceTarget(replacetext)
                self.targetEnd = self.targetEnd + diff
                p = self.parent.txtDocument.FindText((p + len(replacetext)), self.targetEnd, findtext, flags)
            x = x + 1
        return x

    def OnbtnFind(self, event):
        focuswindow = wx.Window.FindFocus()
        if isinstance (focuswindow, wx.TextCtrl):
            if focuswindow.GetParent().GetTitle() == "Create Regular Expression":
                focuswindow.GetParent().OnbtnOk(None)
                focuswindow.GetParent().Destroy()
                return
        #makes sense (replacestring empty: delete this string)
        if self.txtSearchFor.GetValue():
            findflags = 0
            if self.chkWholeWord.GetValue():
                findflags = findflags | wx.stc.STC_FIND_WHOLEWORD
            if self.chkMatchCase.GetValue():
                findflags = findflags | wx.stc.STC_FIND_MATCHCASE

            if self.parent.FindAutoComplete_usemyreplacedialog and self.IsReplace and not self.chkInSelection.GetValue()\
                and not self.chkRegularExpression.GetValue():
                x = self.MyReplaceAll(self.txtSearchFor.GetText(), self.txtReplaceWith.GetText(), findflags, self.chkPromptOnReplace.GetValue())
                if self.parent.prefs.enablefeedback:
                    drScrolledMessageDialog.ShowMessage(self, (str(x) + " occurances of \"" + self.txtSearchFor.GetText() + "\" replaced with \"" + self.txtReplaceWith.GetText() + "\""), "Replace")
            else:
                super (drFindAutoCompleteDialog, self).OnbtnFind (event)
            if self.parent.FindAutoComplete_myfromcursor:
                self.parent.txtDocument.Finder.SetTargetRange(0, self.parent.txtDocument.GetTextLength(), self.chkFindBackwards.GetValue())
#            top = self.parent.txtDocument.GetCurrentLine() - self.parent.txtDocument.LinesOnScreen()/2
#            if top < 0:
#                top = 0
#            self.parent.txtDocument.ScrollToLine(top)
                
        else:
            self.txtSearchFor.SetFocus()

    def OnTextChanged(self, event):
        pass


    def GetAllWordsInDoc(self):
        try:
            if self.ListAllWords == []:
                #code from Find and Complete
                text = self.parent.txtDocument.GetText()
                findandcompleteregex = re.compile(r"\b" + "" + r"\w*\b", re.MULTILINE)
                r = findandcompleteregex.findall(text)
                r.sort()
                tr = []
                results = ""
                for item in r:
                    try:
                        tr.index(item)
                    except:
                        results = results + " " + item
                        tr.append(item)
                results = results.strip()
                tr.reverse()
                self.ListAllWords = tr
        except:
            pass


    def OnCheckAllWords (self, event):
        self.parent.FindAutoComplete_isGlobal = self.chkAllWords.GetValue()
        #collect only the first time
        if not self.parent.FindAutoComplete_isGlobal:
            self.txtSearchFor.SetHistory(self.parent.FindHistory)
        else:
            self.GetAllWordsInDoc()
            self.txtSearchFor.SetHistory(self.ListAllWords)


    class drFindTextAutoCompleteCtrl(drFindReplaceDialog.drFindTextCtrl):
        def __init__(self, parent, id, value, pos, size, returnfunction = None, InFiles = False):
            drFindReplaceDialog.drFindTextCtrl.__init__ (self, parent, id, "", wx.DefaultPosition, wx.Size(200, -1))
            self.__readonly = self.GetWindowStyleFlag() & wx.CB_READONLY == wx.CB_READONLY
            self._ignoreChange = False

            self.parent = parent
            self.Bind(wx.EVT_TEXT, self.EvtText)
            self.Bind(wx.EVT_KEY_DOWN, self.EvtKeyDown)
            self.findindex = -1
            self.delete = False
            self.bs = False
            self.firstbs = False

            self.Bind(wx.EVT_KILL_FOCUS, self.OnKillFocus)

        def OnKillFocus(self, event):
            self.insertionpoint = self.GetInsertionPoint()
            self.sel_start, self.sel_end = self.GetMark()
            event.Skip()

        def EvtKeyDown(self, event):
            self.delete = event.GetKeyCode() == wx.WXK_DELETE
            if not event.GetKeyCode() == 8:
                self.bs = False

            event.Skip()

        def EvtText (self, event):

            if self._ignoreChange:
                event.Skip()
                return
            if self.delete:
                event.Skip()
                return

            if not self.parent.parent.FindAutoComplete_strongautocomplete:
                if self.bs:
                    event.Skip()
                    return
            else:
                if self.findindex > -1 and self.bs:
                    if not self.firstbs:
                        self.SetValue(self.GetValue()[:-1])
                        l = len (self.GetValue())
                        #self.SetMark (l, l)
                        wx.CallAfter (self.SetMark, l, l)
                    else:
                        self.firstbs = False

            cBoxLen = len (self.GetValue())
            if cBoxLen > 0:
                cnt = self.GetCount()
                for i in range (cnt):
                    s = self.GetClientData(i)
                    #this causes problems
                    #if s[:cBoxLen].lower() == self.GetValue().lower():
                    if s[:cBoxLen] == self.GetValue():
                        self.SetValue(s)
                        #self.SetMark (cBoxLen, len (s))
                        wx.CallAfter (self.SetMark, cBoxLen, len (s))
                        self.findindex  = i
                        break
                else:
                    self.findindex = -1
            else:
                self.findindex = -1

        def rangecycle (self, start, end, forward = True):
            r = []
            if forward:
                r = range (start, end)
                r.extend (range (0, start))
            else:
                r = range (start, -1, -1)
                r.extend (range (end, start, -1))
            return r

        def OnChar(self, event):
            self.firstbs =  event.GetKeyCode() == 8 and not self.bs
            self.bs = event.GetKeyCode() == 8
            self.donext = event.GetKeyCode() == 14
            self.doprevious = event.GetKeyCode() == 16
            if self.donext:
                pos = self.GetInsertionPoint()
                for i in self.rangecycle (self.findindex +1, self.GetCount()):
                    s = self.GetClientData(i)
                    if s[:pos] == self.GetValue()[:pos]:
                        self.SetValue(s)
                        self.SetMark (pos, len (s))
                        self.findindex  = i
                        break
                else:
                    self.findindex  = -1
            if self.doprevious:
                pos = self.GetInsertionPoint()
                for i in self.rangecycle (self.findindex - 1, self.GetCount() - 1, False):
                    s = self.GetClientData(i)
                    if s[:pos] == self.GetValue()[:pos]:
                        self.SetValue(s)
                        self.SetMark (pos, len (s))
                        self.findindex  = i
                        break
                else:
                    self.findindex  = -1
            event.Skip()

        def SetHistory(self, history):
            if self.GetCount() > 0:
                self.Clear()
            l = len(history)
            x = l - 1
            while x > -1:
                self.Append(history[x], history[x])
                x = x - 1
            if l > 0:
                #self.SetMark(0, len(history[l-1]))
                wx.CallAfter(self.SetMark, 0, len(history[l-1]))

        def AppendToHistory(self, targetList):
            text = self.GetText()
            try:
                while True:
                    i = targetList.index(text)
                    targetList.pop(i)
            except:
                pass

            targetList.append(text)

def Plugin(DrFrame):

    def OnFindAutoComplete(event):
        d = drFindAutoCompleteDialog(DrFrame, -1, "Find Autocomplete", DrFrame.GetActiveSTC())
        d.SetOptions(DrFrame.FindOptions)
        if DrFrame.txtDocument.GetSelectionStart() < DrFrame.txtDocument.GetSelectionEnd():
            d.SetFindString(DrFrame.txtDocument.GetSelectedText())
        elif DrFrame.prefs.findreplaceundercursor:
            pos = DrFrame.txtDocument.GetCurrentPos()
            d.SetFindString(DrFrame.txtDocument.GetTextRange(DrFrame.txtDocument.WordStartPosition(pos, 1), DrFrame.txtDocument.WordEndPosition(pos, 1)))
        else:
            d.SetFindString(DrFrame.txtDocument.Finder.GetFindText())
        d.Show(True)

    def OnReplaceAutoComplete(event):
        d = drFindAutoCompleteDialog(DrFrame, -1, "Replace Autocomplete", DrFrame.GetActiveSTC(), 1)
        d.SetOptions(DrFrame.ReplaceOptions)
        if DrFrame.txtDocument.GetSelectionStart() < DrFrame.txtDocument.GetSelectionEnd():
            d.SetFindString(DrFrame.txtDocument.GetSelectedText())
        elif DrFrame.prefs.findreplaceundercursor:
            pos = DrFrame.txtDocument.GetCurrentPos()
            d.SetFindString(DrFrame.txtDocument.GetTextRange(DrFrame.txtDocument.WordStartPosition(pos, 1), DrFrame.txtDocument.WordEndPosition(pos, 1)))
        else:
            d.SetFindString(DrFrame.txtDocument.Finder.GetFindText())
        d.Show(True)

    def OnNextFindText(event):
        if DrFrame.FindAutoComplete_lastcursorpos != DrFrame.txtDocument.GetCurrentPos():
            DrFrame.FindAutoComplete_lastcursorpos = DrFrame.txtDocument.GetCurrentPos()
            DrFrame.FindAutoComplete_quicksearchstringptr = 0
        if DrFrame.FindAutoComplete_quicksearchstringptr < len (DrFrame.FindHistory):
            DrFrame.FindAutoComplete_quicksearchstringptr += 1
        else:
            DrFrame.FindAutoComplete_quicksearchstringptr = 1
        DrFrame.txtDocument.Finder.findtext = DrFrame.FindHistory[-DrFrame.FindAutoComplete_quicksearchstringptr]
        statustext = "Index: %d ->Find Text: '%s'" % (DrFrame.FindAutoComplete_quicksearchstringptr, DrFrame.txtDocument.Finder.GetFindText())
        DrFrame.SetStatusText(statustext, 2)

    def OnPreviousFindText(event):
        if DrFrame.FindAutoComplete_lastcursorpos != DrFrame.txtDocument.GetCurrentPos():
            DrFrame.FindAutoComplete_lastcursorpos = DrFrame.txtDocument.GetCurrentPos()
            DrFrame.FindAutoComplete_quicksearchstringptr = len (DrFrame.FindHistory)
        if DrFrame.FindAutoComplete_quicksearchstringptr <= 1:
            DrFrame.FindAutoComplete_quicksearchstringptr = len (DrFrame.FindHistory)
        else:
            DrFrame.FindAutoComplete_quicksearchstringptr -= 1
        DrFrame.txtDocument.Finder.findtext = DrFrame.FindHistory[-DrFrame.FindAutoComplete_quicksearchstringptr]
        statustext = "Index: %d ->Find Text: '%s'" % (DrFrame.FindAutoComplete_quicksearchstringptr, DrFrame.txtDocument.Finder.GetFindText())
        DrFrame.SetStatusText(statustext, 2)


    DrFrame.FindAutoComplete_isGlobal = False
    DrFrame.FindAutoComplete_strongautocomplete = False
    DrFrame.FindAutoComplete_myfromcursor = False
    DrFrame.FindAutoComplete_quicksearchstringptr = 0
    DrFrame.FindAutoComplete_lastcursorpos = -1
    DrFrame.FindAutoComplete_quickfindtext = False
    DrFrame.FindAutoComplete_useintellireplacedefault = False
    DrFrame.FindAutoComplete_usemyreplacedialog = False
    #DrFrame.FindAutoComplete_ReorderHistory = False

    ID_FIND_AUTOCOMPLETE = DrFrame.GetNewId()
    ID_SEARCH_AUTOCOMPLETE = DrFrame.GetNewId()
    ID_NEXT_FINDTEXT= DrFrame.GetNewId()
    ID_PREVIOUS_FINDTEXT= DrFrame.GetNewId()

    prefsfile = DrFrame.pluginspreferencesdirectory + "/FindAutoComplete.preferences.dat"
    if os.path.exists(prefsfile):
        f = file(prefsfile, 'r')
        text = f.read()
        f.close()
        DrFrame.FindAutoComplete_strongautocomplete = drPrefsFile.GetPrefFromText(DrFrame.FindAutoComplete_strongautocomplete, text, "findautocomplete.strongautocomplete", True)
        DrFrame.FindAutoComplete_myfromcursor = drPrefsFile.GetPrefFromText(DrFrame.FindAutoComplete_myfromcursor, text, "findautocomplete.myfromcursor", True)
        DrFrame.FindAutoComplete_quickfindtext = drPrefsFile.GetPrefFromText(DrFrame.FindAutoComplete_quickfindtext, text, "findautocomplete.quickfindtext", True)
        DrFrame.FindAutoComplete_usemyreplacedialog = drPrefsFile.GetPrefFromText(DrFrame.FindAutoComplete_usemyreplacedialog, text, "findautocomplete.usemyreplacedialog", True)
        DrFrame.FindAutoComplete_useintellireplacedefault = drPrefsFile.GetPrefFromText(DrFrame.FindAutoComplete_useintellireplacedefault, text, "findautocomplete.useintellireplacedefault", True)


    DrFrame.AddPluginShortcutFunction("FindAutoComplete", "Find Autocomplete", OnFindAutoComplete)
    DrFrame.AddPluginShortcutFunction("FindAutoComplete", "Replace Autocomplete", OnReplaceAutoComplete)
    if DrFrame.FindAutoComplete_quickfindtext:
        DrFrame.AddPluginShortcutFunction("FindAutoComplete", "Next Find Text", OnNextFindText)
        DrFrame.AddPluginShortcutFunction("FindAutoComplete", "Previous Find Text", OnPreviousFindText)

    DrFrame.AddPluginPopUpMenuFunction("FindAutoComplete", "Find Autocomplete", OnFindAutoComplete)
    DrFrame.AddPluginPopUpMenuFunction("FindAutoComplete", "Replace Autocomplete", OnReplaceAutoComplete)
    if DrFrame.FindAutoComplete_quickfindtext:
        DrFrame.AddPluginPopUpMenuFunction("FindAutoComplete", "Next Find Text", OnNextFindText)
        DrFrame.AddPluginPopUpMenuFunction("FindAutoComplete", "Previous Find Text", OnPreviousFindText)


    DrFrame.searchmenu.AppendSeparator()

    DrFrame.LoadPluginShortcuts('FindAutoComplete')

    findautocompletemenu = wx.Menu()
    DrFrame.searchmenu.AppendMenu(DrFrame.GetNewId(), "Find AutoComplete", findautocompletemenu)

    findautocompletemenu.Append(ID_FIND_AUTOCOMPLETE, DrFrame.GetPluginMenuLabel('FindAutoComplete', 'Find Autocomplete', 'Find Autocomplete...'))
    findautocompletemenu.Append(ID_SEARCH_AUTOCOMPLETE, DrFrame.GetPluginMenuLabel('FindAutoComplete', 'Replace Autocomplete', 'Replace Autocomplete...'))

    #findautocompletemenu.Append(ID_SEARCH_AUTOCOMPLETE, getlabel ("Replace Autocomplete", True))
    if DrFrame.FindAutoComplete_quickfindtext:
        findautocompletemenu.Append(ID_NEXT_FINDTEXT, DrFrame.GetPluginMenuLabel('FindAutoComplete', 'Next Find Text', 'Next Find Text'))
        findautocompletemenu.Append(ID_PREVIOUS_FINDTEXT, DrFrame.GetPluginMenuLabel('FindAutoComplete', 'Previous Find Text', 'Previous Find Text'))


    DrFrame.Bind(wx.EVT_MENU, OnFindAutoComplete, id = ID_FIND_AUTOCOMPLETE)
    DrFrame.Bind(wx.EVT_MENU, OnReplaceAutoComplete, id = ID_SEARCH_AUTOCOMPLETE)
    if DrFrame.FindAutoComplete_quickfindtext:
        DrFrame.Bind(wx.EVT_MENU, OnNextFindText, id = ID_NEXT_FINDTEXT)
        DrFrame.Bind(wx.EVT_MENU, OnPreviousFindText, id = ID_PREVIOUS_FINDTEXT)


