#   Programmer:  Franz Steinhaeusler
#   E-mail:      francescoa@users.sourceforge.net
#   Note:        Initial Release 03.11.2004
#
#   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.0:
# - see changelog.txt

#Version: 0.0.1:
# - see changelog.txt

#Version: 0.0.2:, 07.04.2007:
# update for wxPython 2.8 and DrPython 1.65.

#Plugin
#CompWord

#This plugin ...

import wx
import drScrolledMessageDialog
import re

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

def OnHelp(DrFrame):
    drScrolledMessageDialog.ShowMessage(DrFrame, "Complete Word", "Help")

def Plugin(DrFrame):

    def CollectWords (reduce_dups = False):
        text = DrFrame.txtDocument.GetText()
        curpos = DrFrame.txtDocument.GetCurrentPos()
        DrFrame.CompWord_CurPos = curpos
        a, b = DrFrame.txtDocument.GetSelection()
        if a == b: #nothing selected
            DrFrame.CompWord_part = DrFrame.txtDocument.GetTextRange(DrFrame.txtDocument.WordStartPosition(curpos, 1), curpos)
        else:
            DrFrame.CompWord_part = DrFrame.txtDocument.GetTextRange(DrFrame.txtDocument.WordStartPosition(curpos, 1), a)
        reg = re.compile (r"\b" + DrFrame.CompWord_part +r"\w*\b", re.IGNORECASE)
        listtemp = reg.findall(text[:curpos-1])

        DrFrame.CompWord_List = []
        #iter = r.finditer('abdaertrtrreaew')
        #match = listtemp.next()
        #listtemp = []
        #while match is not None:
            #try:
                #match = matcher.next()
            #except:
                #match = None
            #listtemp.append (match.group)

        DrFrame.CompWord_pos = 0
        for i in listtemp:
            if len(i) > len(DrFrame.CompWord_part):
                DrFrame.CompWord_List.append (i)
        if reduce_dups:
            DrFrame.CompWord_List = reduce(lambda d,v:(d.setdefault(v,None),d)[1], DrFrame.CompWord_List, {}).keys()
            #new Set Command? 08.03.2005:
        DrFrame.CompWord_pos = len (DrFrame.CompWord_List)
        listtemp = reg.findall(text[curpos:])
        for i in listtemp:
            if len(i) > len(DrFrame.CompWord_part):
                DrFrame.CompWord_List.append (i)
        if reduce_dups:
            DrFrame.CompWord_List = reduce(lambda d,v:(d.setdefault(v,None),d)[1], DrFrame.CompWord_List, {}).keys()
        if DrFrame.CompWord_pos >= len (DrFrame.CompWord_List):# added 08.03.2005:
            DrFrame.CompWord_pos = len (DrFrame.CompWord_List) - 1



    def FirstTimeCompletition (forward = True):
        CollectWords()

        #DrFrame.CompWord_List.extend (reg.findall(text[curpos:]))
        DrFrame.CompWord_Len = len (DrFrame.CompWord_List)
        #print DrFrame.CompWord_Len, DrFrame.CompWord_pos, DrFrame.CompWord_List
        if DrFrame.CompWord_Len > 0:
            if not forward:
                if DrFrame.CompWord_pos > 0:
                    DrFrame.CompWord_pos -= 1
            DrFrame.txtDocument.AddText (DrFrame.CompWord_List[DrFrame.CompWord_pos][len(DrFrame.CompWord_part):])
            DrFrame.txtDocument.SetSelection (DrFrame.CompWord_CurPos, DrFrame.CompWord_CurPos + len (DrFrame.CompWord_List[DrFrame.CompWord_pos][len(DrFrame.CompWord_part):]))
            DrFrame.SetStatusText("CompWordNext: %d/%d" % (DrFrame.CompWord_pos + 1, DrFrame.CompWord_Len), 2)
        else:
            DrFrame.SetStatusText("CompWordNext: No Completition found", 2)

    def OnCompWordNext (event):
        #TODO: make one function
        a, b = DrFrame.txtDocument.GetSelection()
        if a == b: #nothing selected
            FirstTimeCompletition()
        else:
            a, b = DrFrame.txtDocument.GetSelection()
            if DrFrame.CompWord_Len > 0 and DrFrame.CompWord_CurPos == a:
                DrFrame.CompWord_pos += 1
                if DrFrame.CompWord_pos >= DrFrame.CompWord_Len:
                    DrFrame.CompWord_pos = 0
                DrFrame.txtDocument.ReplaceSelection (DrFrame.CompWord_List[DrFrame.CompWord_pos][len (DrFrame.CompWord_part):])
                DrFrame.txtDocument.SetSelection (DrFrame.CompWord_CurPos, DrFrame.CompWord_CurPos + len (DrFrame.CompWord_List[DrFrame.CompWord_pos][len (DrFrame.CompWord_part):]))
                DrFrame.SetStatusText("CompWordNext: %d/%d" % (DrFrame.CompWord_pos + 1, DrFrame.CompWord_Len), 2)
            else:
                DrFrame.SetStatusText("CompWordNext: No Completition found", 2)


    def OnCompWordPrevious (event):
        a, b = DrFrame.txtDocument.GetSelection()
        if a == b: #nothing selected
            FirstTimeCompletition(False)
        else:
            a, b = DrFrame.txtDocument.GetSelection()
            if DrFrame.CompWord_Len > 0 and DrFrame.CompWord_CurPos == a:
                DrFrame.CompWord_pos -= 1
                if DrFrame.CompWord_pos < 0:
                    DrFrame.CompWord_pos = DrFrame.CompWord_Len - 1
                DrFrame.txtDocument.ReplaceSelection (DrFrame.CompWord_List[DrFrame.CompWord_pos][len (DrFrame.CompWord_part):])
                DrFrame.txtDocument.SetSelection (DrFrame.CompWord_CurPos, DrFrame.CompWord_CurPos + len (DrFrame.CompWord_List[DrFrame.CompWord_pos][len (DrFrame.CompWord_part):]))
                DrFrame.SetStatusText("CompWordNext: %d/%d" % (DrFrame.CompWord_pos + 1, DrFrame.CompWord_Len), 2)
            else:
                DrFrame.SetStatusText("CompWordNext: No Completition found", 2)

    def CompareLowerCase(n1, n2):
        if n1.lower() == n2.lower():
            return 0
        elif n1.lower() < n2.lower():
            return -1
        return 1

    def OnCompWordList (event):
        a, b = DrFrame.txtDocument.GetSelection()
        #if a == b: #nothing selected
        if 1:
            CollectWords(True)
            #todo: if selected, get part of none selected
            if DrFrame.CompWord_List:
                DrFrame.CompWord_List.sort(CompareLowerCase)
                d = wx.SingleChoiceDialog(DrFrame, "Select one Word from the list:", "Comp Word List", DrFrame.CompWord_List, wx.OK|wx.CANCEL)
                answer = d.ShowModal()
                d.Destroy()
                if answer == wx.ID_OK:
                    s = d.GetStringSelection()
                    DrFrame.txtDocument.ReplaceSelection (s[len (DrFrame.CompWord_part):])
                    DrFrame.txtDocument.SetSelection (DrFrame.CompWord_CurPos, DrFrame.CompWord_CurPos + len (s[len (DrFrame.CompWord_part):]))
            else:
                wx.MessageBox("No Completions found", "CompWord List", wx.ICON_EXCLAMATION)
        else:
            wx.MessageBox("Please clear selection", "CompWord List", wx.ICON_EXCLAMATION)

    ID_COMPWORDNEXT = DrFrame.GetNewId()
    ID_COMPWORDPREVIOUS = DrFrame.GetNewId()
    ID_COMPWORDLIST= DrFrame.GetNewId()


    DrFrame.CompWord_pos = -1
    DrFrame.CompWord_List = []
    DrFrame.CompWord_Len = -1
    DrFrame.CompWord_CurPos = -1
    DrFrame.CompWord_part = ''
    DrFrame.CompWord_current_searchpos = -1


    DrFrame.Bind(wx.EVT_MENU, OnCompWordNext, id = ID_COMPWORDNEXT)
    DrFrame.Bind(wx.EVT_MENU, OnCompWordPrevious, id = ID_COMPWORDPREVIOUS)
    DrFrame.Bind(wx.EVT_MENU, OnCompWordList, id = ID_COMPWORDLIST)

    DrFrame.AddPluginShortcutFunction("CompWord", "CompWord Next", OnCompWordNext)
    DrFrame.AddPluginShortcutFunction("CompWord", "CompWord Previous", OnCompWordPrevious)
    DrFrame.AddPluginShortcutFunction("CompWord", "CompWord List", OnCompWordList)

    DrFrame.AddPluginPopUpMenuFunction("CompWord", "CompWord Next", OnCompWordNext)
    DrFrame.AddPluginPopUpMenuFunction("CompWord", "CompWord Previous", OnCompWordPrevious)
    DrFrame.AddPluginPopUpMenuFunction("CompWord", "CompWord List", OnCompWordList)

    DrFrame.LoadPluginShortcuts('CompWord')
    compwordmenu = wx.Menu()
    compwordmenu.Append(ID_COMPWORDNEXT, DrFrame.GetPluginMenuLabel('CompWord', 'CompWord Next', 'CompWord Next'))
    compwordmenu.Append(ID_COMPWORDPREVIOUS, DrFrame.GetPluginMenuLabel('CompWord', 'CompWord Previous', 'CompWord Previous'))
    compwordmenu.Append(ID_COMPWORDLIST, DrFrame.GetPluginMenuLabel('CompWord', 'CompWord List', 'CompWord List'))
    #remove duplicates and sort

    DrFrame.editmenu.AppendSeparator()
    DrFrame.editmenu.AppendMenu(DrFrame.GetNewId(), "CompWord", compwordmenu)
