# changes by dscherer@cmu.edu
#   - IOBinding.open() replaces the current window with the opened file,
#     if the current window is both unmodified and unnamed
#   - IOBinding.loadfile() interprets Windows, UNIX, and Macintosh
#     end-of-line conventions, instead of relying on the standard library,
#     which will only understand the local convention.

import os
import types
import pipes
import sys
import codecs
import tempfile
import tkFileDialog
import tkMessageBox
import re
from Tkinter import *
from SimpleDialog import SimpleDialog

from idlelib.configHandler import idleConf

try:
    from codecs import BOM_UTF8
except ImportError:
    # only available since Python 2.3
    BOM_UTF8 = '\xef\xbb\xbf'

# Try setting the locale, so that we can find out
# what encoding to use
try:
    import locale
    locale.setlocale(locale.LC_CTYPE, "")
except (ImportError, locale.Error):
    pass

# Encoding for file names
filesystemencoding = sys.getfilesystemencoding()

encoding = "ascii"
if sys.platform == 'win32':
    # On Windows, we could use "mbcs". However, to give the user
    # a portable encoding name, we need to find the code page
    try:
        encoding = locale.getdefaultlocale()[1]
        codecs.lookup(encoding)
    except LookupError:
        pass
else:
    try:
        # Different things can fail here: the locale module may not be
        # loaded, it may not offer nl_langinfo, or CODESET, or the
        # resulting codeset may be unknown to Python. We ignore all
        # these problems, falling back to ASCII
        encoding = locale.nl_langinfo(locale.CODESET)
        if encoding is None or encoding is '':
            # situation occurs on Mac OS X
            encoding = 'ascii'
        codecs.lookup(encoding)
    except (NameError, AttributeError, LookupError):
        # Try getdefaultlocale well: it parses environment variables,
        # which may give a clue. Unfortunately, getdefaultlocale has
        # bugs that can cause ValueError.
        try:
            encoding = locale.getdefaultlocale()[1]
            if encoding is None or encoding is '':
                # situation occurs on Mac OS X
                encoding = 'ascii'
            codecs.lookup(encoding)
        except (ValueError, LookupError):
            pass

encoding = encoding.lower()

coding_re = re.compile("coding[:=]\s*([-\w_.]+)")

class EncodingMessage(SimpleDialog):
    "Inform user that an encoding declaration is needed."
    def __init__(self, master, enc):
        self.should_edit = False

        self.root = top = Toplevel(master)
        top.bind("<Return>", self.return_event)
        top.bind("<Escape>", self.do_ok)
        top.protocol("WM_DELETE_WINDOW", self.wm_delete_window)
        top.wm_title("I/O Warning")
        top.wm_iconname("I/O Warning")
        self.top = top

        l1 = Label(top,
            text="Non-ASCII found, yet no encoding declared. Add a line like")
        l1.pack(side=TOP, anchor=W)
        l2 = Entry(top, font="courier")
        l2.insert(0, "# -*- coding: %s -*-" % enc)
        # For some reason, the text is not selectable anymore if the
        # widget is disabled.
        # l2['state'] = DISABLED
        l2.pack(side=TOP, anchor = W, fill=X)
        l3 = Label(top, text="to your file\n"
                   "Choose OK to save this file as %s\n"
                   "Edit your general options to silence this warning" % enc)
        l3.pack(side=TOP, anchor = W)

        buttons = Frame(top)
        buttons.pack(side=TOP, fill=X)
        # Both return and cancel mean the same thing: do nothing
        self.default = self.cancel = 0
        b1 = Button(buttons, text="Ok", default="active",
                    command=self.do_ok)
        b1.pack(side=LEFT, fill=BOTH, expand=1)
        b2 = Button(buttons, text="Edit my file",
                    command=self.do_edit)
        b2.pack(side=LEFT, fill=BOTH, expand=1)

        self._set_transient(master)

    def do_ok(self):
        self.done(0)

    def do_edit(self):
        self.done(1)

def coding_spec(str):
    """Return the encoding declaration according to PEP 263.

    Raise LookupError if the encoding is declared but unknown.
    """
    # Only consider the first two lines
    str = str.split("\n")[:2]
    str = "\n".join(str)

    match = coding_re.search(str)
    if not match:
        return None
    name = match.group(1)
    # Check whether the encoding is known
    import codecs
    try:
        codecs.lookup(name)
    except LookupError:
        # The standard encoding error does not indicate the encoding
        raise LookupError, "Unknown encoding "+name
    return name


class IOBinding:

    def __init__(self, editwin):
        self.editwin = editwin
        self.text = editwin.text
        self.__id_open = self.text.bind("<<open-window-from-file>>", self.open)
        self.__id_save = self.text.bind("<<save-window>>", self.save)
        self.__id_saveas = self.text.bind("<<save-window-as-file>>",
                                          self.save_as)
        self.__id_savecopy = self.text.bind("<<save-copy-of-window-as-file>>",
                                            self.save_a_copy)
        self.fileencoding = None
        self.__id_print = self.text.bind("<<print-window>>", self.print_window)

    def close(self):
        # Undo command bindings
        self.text.unbind("<<open-window-from-file>>", self.__id_open)
        self.text.unbind("<<save-window>>", self.__id_save)
        self.text.unbind("<<save-window-as-file>>",self.__id_saveas)
        self.text.unbind("<<save-copy-of-window-as-file>>", self.__id_savecopy)
        self.text.unbind("<<print-window>>", self.__id_print)
        # Break cycles
        self.editwin = None
        self.text = None
        self.filename_change_hook = None

    def get_saved(self):
        return self.editwin.get_saved()

    def set_saved(self, flag):
        self.editwin.set_saved(flag)

    def reset_undo(self):
        self.editwin.reset_undo()

    filename_change_hook = None

    def set_filename_change_hook(self, hook):
        self.filename_change_hook = hook

    filename = None
    dirname = None

    def set_filename(self, filename):
        if filename and os.path.isdir(filename):
            self.filename = None
            self.dirname = filename
        else:
            self.filename = filename
            self.dirname = None
            self.set_saved(1)
            if self.filename_change_hook:
                self.filename_change_hook()

    def open(self, event=None, editFile=None):
        flist = self.editwin.flist
        # Save in case parent window is closed (ie, during askopenfile()).
        if flist:
            if not editFile:
                filename = self.askopenfile()
            else:
                filename=editFile
            if filename:
                # If editFile is valid and already open, flist.open will
                # shift focus to its existing window.
                # If the current window exists and is a fresh unnamed,
                # unmodified editor window (not an interpreter shell),
                # pass self.loadfile to flist.open so it will load the file
                # in the current window (if the file is not already open)
                # instead of a new window.
                if (self.editwin and
                        not getattr(self.editwin, 'interp', None) and
                        not self.filename and
                        self.get_saved()):
                    flist.open(filename, self.loadfile)
                else:
                    flist.open(filename)
            else:
                if self.text:
                    self.text.focus_set()
            return "break"

        # Code for use outside IDLE:
        if self.get_saved():
            reply = self.maybesave()
            if reply == "cancel":
                self.text.focus_set()
                return "break"
        if not editFile:
            filename = self.askopenfile()
        else:
            filename=editFile
        if filename:
            self.loadfile(filename)
        else:
            self.text.focus_set()
        return "break"

    eol = r"(\r\n)|\n|\r"  # \r\n (Windows), \n (UNIX), or \r (Mac)
    eol_re = re.compile(eol)
    eol_convention = os.linesep # Default

    def loadfile(self, filename):
        try:
            # open the file in binary mode so that we can handle
            #   end-of-line convention ourselves.
            f = open(filename,'rb')
            chars = f.read()
            f.close()
        except IOError, msg:
            tkMessageBox.showerror("I/O Error", str(msg), master=self.text)
            return False

        chars = self.decode(chars)
        # We now convert all end-of-lines to '\n's
        firsteol = self.eol_re.search(chars)
        if firsteol:
            self.eol_convention = firsteol.group(0)
            if isinstance(self.eol_convention, unicode):
                # Make sure it is an ASCII string
                self.eol_convention = self.eol_convention.encode("ascii")
            chars = self.eol_re.sub(r"\n", chars)

        self.text.delete("1.0", "end")
        self.set_filename(None)
        self.text.insert("1.0", chars)
        self.reset_undo()
        self.set_filename(filename)
        self.text.mark_set("insert", "1.0")
        self.text.yview("insert")
        self.updaterecentfileslist(filename)
        return True

    def decode(self, chars):
        """Create a Unicode string

        If that fails, let Tcl try its best
        """
        # Check presence of a UTF-8 signature first
        if chars.startswith(BOM_UTF8):
            try:
                chars = chars[3:].decode("utf-8")
            except UnicodeError:
                # has UTF-8 signature, but fails to decode...
                return chars
            else:
                # Indicates that this file originally had a BOM
                self.fileencoding = BOM_UTF8
                return chars
        # Next look for coding specification
        try:
            enc = coding_spec(chars)
        except LookupError, name:
            tkMessageBox.showerror(
                title="Error loading the file",
                message="The encoding '%s' is not known to this Python "\
                "installation. The file may not display correctly" % name,
                master = self.text)
            enc = None
        if enc:
            try:
                return unicode(chars, enc)
            except UnicodeError:
                pass
        # If it is ASCII, we need not to record anything
        try:
            return unicode(chars, 'ascii')
        except UnicodeError:
            pass
        # Finally, try the locale's encoding. This is deprecated;
        # the user should declare a non-ASCII encoding
        try:
            chars = unicode(chars, encoding)
            self.fileencoding = encoding
        except UnicodeError:
            pass
        return chars

    def maybesave(self):
        if self.get_saved():
            return "yes"
        message = "Do you want to save %s before closing?" % (
            self.filename or "this untitled document")
        confirm = tkMessageBox.askyesnocancel(
                  title="Save On Close",
                  message=message,
                  default=tkMessageBox.YES,
                  master=self.text)
        if confirm:
            reply = "yes"
            self.save(None)
            if not self.get_saved():
                reply = "cancel"
        elif confirm is None:
            reply = "cancel"
        else:
            reply = "no"
        self.text.focus_set()
        return reply

    def save(self, event):
        if not self.filename:
            self.save_as(event)
        else:
            if self.writefile(self.filename):
                self.set_saved(True)
                try:
                    self.editwin.store_file_breaks()
                except AttributeError:  # may be a PyShell
                    pass
        self.text.focus_set()
        return "break"

    def save_as(self, event):
        filename = self.asksavefile()
        if filename:
            if self.writefile(filename):
                self.set_filename(filename)
                self.set_saved(1)
                try:
                    self.editwin.store_file_breaks()
                except AttributeError:
                    pass
        self.text.focus_set()
        self.updaterecentfileslist(filename)
        return "break"

    def save_a_copy(self, event):
        filename = self.asksavefile()
        if filename:
            self.writefile(filename)
        self.text.focus_set()
        self.updaterecentfileslist(filename)
        return "break"

    def writefile(self, filename):
        self.fixlastline()
        chars = self.encode(self.text.get("1.0", "end-1c"))
        if self.eol_convention != "\n":
            chars = chars.replace("\n", self.eol_convention)
        try:
            f = open(filename, "wb")
            f.write(chars)
            f.flush()
            f.close()
            return True
        except IOError, msg:
            tkMessageBox.showerror("I/O Error", str(msg),
                                   master=self.text)
            return False

    def encode(self, chars):
        if isinstance(chars, types.StringType):
            # This is either plain ASCII, or Tk was returning mixed-encoding
            # text to us. Don't try to guess further.
            return chars
        # See whether there is anything non-ASCII in it.
        # If not, no need to figure out the encoding.
        try:
            return chars.encode('ascii')
        except UnicodeError:
            pass
        # If there is an encoding declared, try this first.
        try:
            enc = coding_spec(chars)
            failed = None
        except LookupError, msg:
            failed = msg
            enc = None
        if enc:
            try:
                return chars.encode(enc)
            except UnicodeError:
                failed = "Invalid encoding '%s'" % enc
        if failed:
            tkMessageBox.showerror(
                "I/O Error",
                "%s. Saving as UTF-8" % failed,
                master = self.text)
        # If there was a UTF-8 signature, use that. This should not fail
        if self.fileencoding == BOM_UTF8 or failed:
            return BOM_UTF8 + chars.encode("utf-8")
        # Try the original file encoding next, if any
        if self.fileencoding:
            try:
                return chars.encode(self.fileencoding)
            except UnicodeError:
                tkMessageBox.showerror(
                    "I/O Error",
                    "Cannot save this as '%s' anymore. Saving as UTF-8" \
                    % self.fileencoding,
                    master = self.text)
                return BOM_UTF8 + chars.encode("utf-8")
        # Nothing was declared, and we had not determined an encoding
        # on loading. Recommend an encoding line.
        config_encoding = idleConf.GetOption("main","EditorWindow",
                                             "encoding")
        if config_encoding == 'utf-8':
            # User has requested that we save files as UTF-8
            return BOM_UTF8 + chars.encode("utf-8")
        ask_user = True
        try:
            chars = chars.encode(encoding)
            enc = encoding
            if config_encoding == 'locale':
                ask_user = False
        except UnicodeError:
            chars = BOM_UTF8 + chars.encode("utf-8")
            enc = "utf-8"
        if not ask_user:
            return chars
        dialog = EncodingMessage(self.editwin.top, enc)
        dialog.go()
        if dialog.num == 1:
            # User asked us to edit the file
            encline = "# -*- coding: %s -*-\n" % enc
            firstline = self.text.get("1.0", "2.0")
            if firstline.startswith("#!"):
                # Insert encoding after #! line
                self.text.insert("2.0", encline)
            else:
                self.text.insert("1.0", encline)
            return self.encode(self.text.get("1.0", "end-1c"))
        return chars

    def fixlastline(self):
        c = self.text.get("end-2c")
        if c != '\n':
            self.text.insert("end-1c", "\n")

    def print_window(self, event):
        confirm = tkMessageBox.askokcancel(
                  title="Print",
                  message="Print to Default Printer",
                  default=tkMessageBox.OK,
                  master=self.text)
        if not confirm:
            self.text.focus_set()
            return "break"
        tempfilename = None
        saved = self.get_saved()
        if saved:
            filename = self.filename
        # shell undo is reset after every prompt, looks saved, probably isn't
        if not saved or filename is None:
            (tfd, tempfilename) = tempfile.mkstemp(prefix='IDLE_tmp_')
            filename = tempfilename
            os.close(tfd)
            if not self.writefile(tempfilename):
                os.unlink(tempfilename)
                return "break"
        platform = os.name
        printPlatform = True
        if platform == 'posix': #posix platform
            command = idleConf.GetOption('main','General',
                                         'print-command-posix')
            command = command + " 2>&1"
        elif platform == 'nt': #win32 platform
            command = idleConf.GetOption('main','General','print-command-win')
        else: #no printing for this platform
            printPlatform = False
        if printPlatform:  #we can try to print for this platform
            command = command % pipes.quote(filename)
            pipe = os.popen(command, "r")
            # things can get ugly on NT if there is no printer available.
            output = pipe.read().strip()
            status = pipe.close()
            if status:
                output = "Printing failed (exit status 0x%x)\n" % \
                         status + output
            if output:
                output = "Printing command: %s\n" % repr(command) + output
                tkMessageBox.showerror("Print status", output, master=self.text)
        else:  #no printing for this platform
            message = "Printing is not enabled for this platform: %s" % platform
            tkMessageBox.showinfo("Print status", message, master=self.text)
        if tempfilename:
            os.unlink(tempfilename)
        return "break"

    opendialog = None
    savedialog = None

    filetypes = [
        ("Python files", "*.py *.pyw", "TEXT"),
        ("Text files", "*.txt", "TEXT"),
        ("All files", "*"),
        ]

    def askopenfile(self):
        dir, base = self.defaultfilename("open")
        if not self.opendialog:
            self.opendialog = tkFileDialog.Open(master=self.text,
                                                filetypes=self.filetypes)
        filename = self.opendialog.show(initialdir=dir, initialfile=base)
        if isinstance(filename, unicode):
            filename = filename.encode(filesystemencoding)
        return filename

    def defaultfilename(self, mode="open"):
        if self.filename:
            return os.path.split(self.filename)
        elif self.dirname:
            return self.dirname, ""
        else:
            try:
                pwd = os.getcwd()
            except os.error:
                pwd = ""
            return pwd, ""

    def asksavefile(self):
        dir, base = self.defaultfilename("save")
        if not self.savedialog:
            self.savedialog = tkFileDialog.SaveAs(master=self.text,
                                                  filetypes=self.filetypes)
        filename = self.savedialog.show(initialdir=dir, initialfile=base)
        if isinstance(filename, unicode):
            filename = filename.encode(filesystemencoding)
        return filename

    def updaterecentfileslist(self,filename):
        "Update recent file list on all editor windows"
        self.editwin.update_recent_files_list(filename)

def test():
    root = Tk()
    class MyEditWin:
        def __init__(self, text):
            self.text = text
            self.flist = None
            self.text.bind("<Control-o>", self.open)
            self.text.bind("<Control-s>", self.save)
            self.text.bind("<Alt-s>", self.save_as)
            self.text.bind("<Alt-z>", self.save_a_copy)
        def get_saved(self): return 0
        def set_saved(self, flag): pass
        def reset_undo(self): pass
        def open(self, event):
            self.text.event_generate("<<open-window-from-file>>")
        def save(self, event):
            self.text.event_generate("<<save-window>>")
        def save_as(self, event):
            self.text.event_generate("<<save-window-as-file>>")
        def save_a_copy(self, event):
            self.text.event_generate("<<save-copy-of-window-as-file>>")
    text = Text(root)
    text.pack()
    text.focus_set()
    editwin = MyEditWin(text)
    io = IOBinding(editwin)
    root.mainloop()

if __name__ == "__main__":
    test()
