#   Programmer:  Franz Steinhaeusler
#   E-mail:      francescoa@users.sourceforge.net
#   Note:        Initial Release 05/01/2004
#
#   Copyright 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


#Plugin
#CleanUpFile

#Version: 0.0.0, 05.01.2005:

import wx
import os
import re
import string
import drPrefsFile

def OnAbout(DrFrame):
    Verision = "0.0.0"
    NameAndVersion = "CleanUp File\nVersion: " + Verision + "\n"
    AboutString = NameAndVersion + "By Franz Steinhaeusler\n\nReleased under the GPL."
    d = DrFrame.ShowMessage (AboutString, "About")

def OnHelp(DrFrame):
    d = DrFrame.ShowMessage ("CleanUpFile", "Help")

class CleanUpPrefsDialog(wx.Dialog):

    def __init__(self, parent, id):

        wx.Dialog.__init__(self, parent, id, "CleanUpFile", 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.chkeol = wx.CheckBox(self, -1, "")
        self.chkeol.SetValue(parent.CleanUpFile_CheckEol)
        self.chkindentation = wx.CheckBox(self, -1, "")
        self.chkindentation.SetValue(parent.CleanUpFile_CheckIndentation)
        self.chktrailingspaces = wx.CheckBox(self, -1, "")
        self.chktrailingspaces.SetValue(parent.CleanUpFile_CheckTrailingSpaces)

        self.theSizer = wx.FlexGridSizer(5, 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, "Check Eol:"),1,wx.GROW)
        self.theSizer.Add(self.chkeol, 1, wx.SHAPED)
        self.theSizer.Add(wx.StaticText(self, -1, "   "), 1, wx.SHAPED)

        self.theSizer.Add(wx.StaticText(self, -1, "Check Indentation:"),1,wx.GROW)
        self.theSizer.Add(self.chkindentation, 1, wx.SHAPED)
        self.theSizer.Add(wx.StaticText(self, -1, "   "), 1, wx.SHAPED)

        self.theSizer.Add(wx.StaticText(self, -1, "Check Trailing Spaces:"),1,wx.GROW)
        self.theSizer.Add(self.chktrailingspaces, 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)

        if parent.PLATFORM_IS_WIN:
            self.SetSizerAndFit(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.CleanUpFile_CheckEol = int(self.chkeol.GetValue())
        self.parent.CleanUpFile_CheckIndentation = int(self.chkindentation.GetValue())
        self.parent.CleanUpFile_CheckTrailingSpaces= int(self.chktrailingspaces.GetValue())
        f = file(self.parent.pluginspreferencesdirectory + "/CleanUpFile.preferences.dat", 'w')
        f.write("<cleanupfile.checkeol>" + str(self.parent.CleanUpFile_CheckEol) + "</cleanupfile.checkeol>\n")
        f.write("<cleanupfile.checkindentation>" + str(self.parent.CleanUpFile_CheckIndentation) + "</cleanupfile.checkindentation>\n")
        f.write("<cleanupfile.checktrailingspaces>" + str(self.parent.CleanUpFile_CheckTrailingSpaces) + "</cleanupfile.checktrailingspaces>\n")
        f.close()

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


#def AddPluginOpenFileFunction (zrdz, OnPreferences, RunFirst):
#   print "hi"

def Plugin(DrFrame):

    def OnRemoveTrailingWhiteSpaces (self):

        #if os.access(self.txtDocument.filename, os.W_OK):
        eol = self.txtDocument.GetEndOfLineCharacter()
        lines = self.txtDocument.GetText().split(eol)
        new_lines = []
        nr_lines = 0
        nr_clines = 0
        regex = re.compile('\s+' + eol, re.MULTILINE)

        for line in lines:
            nr_lines += 1
            result = regex.search(line + eol)
            if result is not None:
                end = result.start()
                nr_clines += 1
                new_lines.append (line [:end])
            else:
                new_lines.append(line)

        #file has trailing whitespaces
        if nr_clines > 0:
            answer = wx.MessageBox("File %s has tr ailing Whitespaces\nCorrect?" % self.txtDocument.filename, "Remove trailing Whitespace", wx.OK | wx.CANCEL | wx.ICON_QUESTION)
            if answer == wx.OK:
                newtext = string.join(new_lines, eol)
                #save current line
                curline = self.txtDocument.GetCurrentLine()
                self.txtDocument.SetText(newtext)
                #jump to saved current line
                self.txtDocument.GotoLine(curline)
        return nr_clines > 0




    def OnCheckAndCleanUpFile (event):
        self = DrFrame
        userinvoked = False

        if event is not None:
            userinvoked = True
            messedup = False
        filename = self.txtDocument.filename
        #print filename, self.txtDocument.filename
        if os.access(self.txtDocument.filename, os.W_OK) or userinvoked:
            ext = os.path.splitext(self.txtDocument.filename)
            #print ext
            #if ext[1] in ('.txt', '.pyw', '.py', '.h', '.cpp'):
            #manuell (auch settings ignorieren)
            #if ext[1] in ('.pyw', '.py') or userinvoked:
            if ext[1] in ('.pyw', '.py', '.txt') or userinvoked:
                indentation = self.txtDocument.CheckIndentation(self.txtDocument.GetText())
                if self.CleanUpFile_CheckIndentation or userinvoked: #self.prefs.checkindentation: #todo: replace with my preferences
                #todo fileextensionmask
                    if indentation == 0:
                        u = 0
                        indentation = -1
                        if self.txtDocument.GetUseTabs():
                            u = 2
                            indentation = 1

                        messedup = True
                        answer = wx.MessageBox((filename + ' is currently ' + "MIXED" + ".\nWould you like to change it to " \
                            + self.TABMESSAGE[u] + " ?" ), "Indentation Not Default", wx.OK | wx.CANCEL | wx.ICON_QUESTION)
                        if answer == wxOK:

                            if indentation == 1:
                                self.txtDocument.SetToTabs(4)
                            else:
                                self.txtDocument.SetToSpaces(2)
                if indentation == -1:
                    usetabs = False
                elif indentation == 1:
                    usetabs = True
                else:
                    usetabs = self.prefs.docusetabs[self.txtDocument.filetype]
                self.txtDocument.SetUseTabs(usetabs)
                self.txtDocument.SetupTabs(usetabs)
            #dmodenum = self.prefs.eolmode

                #if self.prefs.checkeol:
                if self.CleanUpFile_CheckEol or userinvoked:
                    #if not emodenum == self.prefs.eolmode:
                    if self.txtDocument.lineendingsaremixed:
                        oof = self.txtDocument.GetText()
                        winresult = self.relewin.search(oof)
                        unixresult = self.releunix.search(oof)
                        macresult = self.relemac.search(oof)

                        win = winresult is not None
                        unix = unixresult is not None
                        mac = macresult is not None

                        if (win + unix + mac) > 1:
                            #Which came first, unix, mac, or win?
                            first = -1
                            useemode = 0
                            if winresult is not None:
                                first = winresult.start()
                                useemode = 1
                            if unixresult is not None:
                                if first == -1:
                                    first = unixresult.start()
                                else:
                                    i = unixresult.start()
                                    if i < first:
                                        first = i
                                        useemode = 0
                            if macresult is not None:
                                if first == -1:
                                    first = macresult.start()
                                else:
                                    i = macresult.start()
                                    if i < first:
                                        first = i
                                        useemode = 2
                            self.txtDocument.lineendingsaremixed = 1
                            emodenum = useemode
                        else:
                            if win:
                                emodenum = 1
                            elif unix:
                                emodenum = 0
                            elif mac:
                                emodenum = 2
                            else:
                                emodenum = self.prefs.eolmode

                        messedup = True
                        #print self.txtDocument.GetEOLMode(), self.FFMESSAGE[self.txtDocument.GetEOLMode()]
                        answer = wx.MessageBox((filename + " is currently " + self.FFMESSAGE[emodenum] + \
                            "(Mixed).\nWould you like to change it to " + self.FFMESSAGE[emodenum]), \
                            "Mixed Line Ending", wx.OK | wx.CANCEL | wx.ICON_QUESTION)
                        if answer == wx.OK:
                            #Bugfix, Thanks Stephen Anderson.
                            if emodenum == 1:
                                self.OnFormatWinMode(None)
                            elif emodenum == 2:
                                self.OnFormatMacMode(None)
                            else:
                                self.OnFormatUnixMode(None)
                            self.txtDocument.lineendingsaremixed = 0
                            #emodenum = dmodenum

                        if emodenum == 1:
                            emode = wx.stc.STC_EOL_CRLF
                        elif emodenum == 2:
                            emode = wx.stc.STC_EOL_CR
                        else:
                            emode = wx.stc.STC_EOL_LF
                        self.txtDocument.SetEOLMode(emode)

                if self.CleanUpFile_CheckTrailingSpaces and ext[1] in ('.txt') or userinvoked:
                #print "remt"
                    if OnRemoveTrailingWhiteSpaces(DrFrame):
                        messedup = True
            if userinvoked:
                if not messedup:
                    wx.MessageBox("File %s is ok" % self.txtDocument.filename, "CleanUp File", wx.ICON_EXCLAMATION)


        #if filename = None:
        #   OnCheckAndCleanUpFile (None, filename)

    def OnCheckAndCleanUpFileStart():# (event): #, filename):
        #print self
        #print "OnCleanUpFile"
        #print filename, self.txtDocument.filename
        #OnCheckAndCleanUpFile (None, DrFrame.txtDocument.filename)
        #print "f:", DrFrame.txtDocument.filename
        OnCheckAndCleanUpFile (None)
        #event.Skip()

    DrFrame.CleanUpFile_CheckEol = False
    DrFrame.CleanUpFile_CheckIndentation = False
    DrFrame.CleanUpFile_CheckTrailingSpaces = False

    if os.path.exists(DrFrame.pluginspreferencesdirectory + "/CleanUpFile.preferences.dat"):
        f = file(DrFrame.pluginspreferencesdirectory + "/CleanUpFile.preferences.dat", 'r')
        text = f.read()
        f.close()
        DrFrame.CleanUpFile_CheckEol = drPrefsFile.GetPrefFromText(DrFrame.CleanUpFile_CheckEol, text, "cleanupfile.checkeol", True)
        DrFrame.CleanUpFile_CheckIndentation = drPrefsFile.GetPrefFromText(DrFrame.CleanUpFile_CheckIndentation, text, "cleanupfile.checkindentation", True)
        DrFrame.CleanUpFile_CheckTrailingSpaces = drPrefsFile.GetPrefFromText(DrFrame.CleanUpFile_CheckTrailingSpaces, text, "cleanupfile.checktrailingspaces", True)

    ID_CLEANUPFILE = DrFrame.GetNewId()

    DrFrame.AddPluginShortcutFunction("CleanUpFile", "Cleanup File", OnCheckAndCleanUpFile)
    DrFrame.AddPluginPopUpMenuFunction("CleanUpFile", "Cleanup File", OnCheckAndCleanUpFile)

    DrFrame.editmenu.AppendSeparator()
    DrFrame.LoadPluginShortcuts('CleanUpFile')
    menutext = DrFrame.GetPluginMenuLabel('CleanUpFile', 'Cleanup File', "Cleanup File...")
    DrFrame.editmenu.Append(ID_CLEANUPFILE, menutext)

    DrFrame.Bind(wx.EVT_MENU, OnCheckAndCleanUpFile, id = ID_CLEANUPFILE)
    DrFrame.PBind(DrFrame.EVT_DRPY_FILE_OPENED, OnCheckAndCleanUpFileStart)

    #DrFrame.AddPluginOpenFileFunction ("CleanUpFile", OnCheckAndCleanUpFileStart, False)
