# A minimal text editor using MLTE. Based on wed.py.
#
# To be done:
# - Functionality: find, etc.

from Menu import DrawMenuBar
from FrameWork import *
from Carbon import Win
from Carbon import Ctl
from Carbon import Qd
from Carbon import Res
from Carbon import Scrap
import os
from Carbon import MacTextEditor
from Carbon import Mlte

UNDOLABELS = [ # Indexed by MLTECanUndo() value
        "Typing", "Cut", "Paste", "Clear", "Font Change", "Color Change", "Size Change",
        "Style Change", "Align Left", "Align Center", "Align Right", "Drop", "Move"]

class MlteWindow(Window):
    def open(self, path, name, data):
        self.path = path
        self.name = name
        r = windowbounds(400, 400)
        w = Win.NewWindow(r, name, 1, 0, -1, 1, 0)
        self.wid = w
        flags = MacTextEditor.kTXNDrawGrowIconMask|MacTextEditor.kTXNWantHScrollBarMask| \
                        MacTextEditor.kTXNWantVScrollBarMask
        self.ted, self.frameid = Mlte.TXNNewObject(None, w, None, flags, MacTextEditor.kTXNTextEditStyleFrameType,
                        MacTextEditor.kTXNTextFile, MacTextEditor.kTXNMacOSEncoding)
        self.ted.TXNSetData(MacTextEditor.kTXNTextData, data, 0, 0x7fffffff)
        self.changed = 0
        self.do_postopen()
        self.do_activate(1, None)

    def do_idle(self, event):
        self.ted.TXNIdle()
        self.ted.TXNAdjustCursor(None)



    def do_activate(self, onoff, evt):
        if onoff:
##                      self.ted.TXNActivate(self.frameid, 0)
            self.ted.TXNFocus(1)
            self.parent.active = self
        else:
            self.ted.TXNFocus(0)
            self.parent.active = None
        self.parent.updatemenubar()

    def do_update(self, wid, event):
        self.ted.TXNDraw(None)

    def do_postresize(self, width, height, window):
        self.ted.TXNResizeFrame(width, height, self.frameid)

    def do_contentclick(self, local, modifiers, evt):
        self.ted.TXNClick(evt)
        self.parent.updatemenubar()

    def do_char(self, ch, event):
        self.ted.TXNKeyDown(event)
        self.parent.updatemenubar()

    def close(self):
        if self.changed:
            save = EasyDialogs.AskYesNoCancel('Save window "%s" before closing?'%self.name, 1)
            if save > 0:
                self.menu_save()
            elif save < 0:
                return
        if self.parent.active == self:
            self.parent.active = None
        self.ted.TXNDeleteObject()
        del self.ted
##              del self.tedtexthandle
        self.do_postclose()

    def menu_save(self):
        if not self.path:
            self.menu_save_as()
            return # Will call us recursively
        dhandle = self.ted.TXNGetData(0, 0x7fffffff)
        data = dhandle.data
        fp = open(self.path, 'wb')  # NOTE: wb, because data has CR for end-of-line
        fp.write(data)
        if data[-1] <> '\r': fp.write('\r')
        fp.close()
        self.changed = 0

    def menu_save_as(self):
        path = EasyDialogs.AskFileForSave(message='Save as:')
        if not path: return
        self.path = path
        self.name = os.path.split(self.path)[-1]
        self.wid.SetWTitle(self.name)
        self.menu_save()

    def menu_cut(self):
##              self.ted.WESelView()
        self.ted.TXNCut()
###             Mlte.ConvertToPublicScrap()
##              Scrap.ZeroScrap()
##              self.ted.WECut()
##              self.updatescrollbars()
        self.parent.updatemenubar()
        self.changed = 1

    def menu_copy(self):
##              Scrap.ZeroScrap()
        self.ted.TXNCopy()
###             Mlte.ConvertToPublicScrap()
##              self.updatescrollbars()
        self.parent.updatemenubar()

    def menu_paste(self):
###             Mlte.ConvertFromPublicScrap()
        self.ted.TXNPaste()
##              self.updatescrollbars()
        self.parent.updatemenubar()
        self.changed = 1

    def menu_clear(self):
##              self.ted.WESelView()
        self.ted.TXNClear()
##              self.updatescrollbars()
        self.parent.updatemenubar()
        self.changed = 1

    def menu_undo(self):
        self.ted.TXNUndo()
##              self.updatescrollbars()
        self.parent.updatemenubar()

    def menu_redo(self):
        self.ted.TXNRedo()
##              self.updatescrollbars()
        self.parent.updatemenubar()

    def have_selection(self):
        start, stop = self.ted.TXNGetSelection()
        return start < stop

    def can_paste(self):
        return Mlte.TXNIsScrapPastable()

    def can_undo(self):
        can, which = self.ted.TXNCanUndo()
        if not can:
            return None
        if which >= len(UNDOLABELS):
            # Unspecified undo
            return "Undo"
        which = UNDOLABELS[which]

        return "Undo "+which

    def can_redo(self):
        can, which = self.ted.TXNCanRedo()
        if not can:
            return None
        if which >= len(UNDOLABELS):
            # Unspecified undo
            return "Redo"
        which = UNDOLABELS[which]

        return "Redo "+which

class Mlted(Application):
    def __init__(self):
        Application.__init__(self)
        self.num = 0
        self.active = None
        self.updatemenubar()

    def makeusermenus(self):
        self.filemenu = m = Menu(self.menubar, "File")
        self.newitem = MenuItem(m, "New window", "N", self.open)
        self.openitem = MenuItem(m, "Open...", "O", self.openfile)
        self.closeitem = MenuItem(m, "Close", "W", self.closewin)
        m.addseparator()
        self.saveitem = MenuItem(m, "Save", "S", self.save)
        self.saveasitem = MenuItem(m, "Save as...", "", self.saveas)
        m.addseparator()
        self.quititem = MenuItem(m, "Quit", "Q", self.quit)

        self.editmenu = m = Menu(self.menubar, "Edit")
        self.undoitem = MenuItem(m, "Undo", "Z", self.undo)
        self.redoitem = MenuItem(m, "Redo", None, self.redo)
        m.addseparator()
        self.cutitem = MenuItem(m, "Cut", "X", self.cut)
        self.copyitem = MenuItem(m, "Copy", "C", self.copy)
        self.pasteitem = MenuItem(m, "Paste", "V", self.paste)
        self.clearitem = MenuItem(m, "Clear", "", self.clear)

        # Groups of items enabled together:
        self.windowgroup = [self.closeitem, self.saveitem, self.saveasitem, self.editmenu]
        self.focusgroup = [self.cutitem, self.copyitem, self.clearitem]
        self.windowgroup_on = -1
        self.focusgroup_on = -1
        self.pastegroup_on = -1
        self.undo_label = "never"
        self.redo_label = "never"

    def updatemenubar(self):
        changed = 0
        on = (self.active <> None)
        if on <> self.windowgroup_on:
            for m in self.windowgroup:
                m.enable(on)
            self.windowgroup_on = on
            changed = 1
        if on:
            # only if we have an edit menu
            on = self.active.have_selection()
            if on <> self.focusgroup_on:
                for m in self.focusgroup:
                    m.enable(on)
                self.focusgroup_on = on
                changed = 1
            on = self.active.can_paste()
            if on <> self.pastegroup_on:
                self.pasteitem.enable(on)
                self.pastegroup_on = on
                changed = 1
            on = self.active.can_undo()
            if on <> self.undo_label:
                if on:
                    self.undoitem.enable(1)
                    self.undoitem.settext(on)
                    self.undo_label = on
                else:
                    self.undoitem.settext("Nothing to undo")
                    self.undoitem.enable(0)
                changed = 1
            on = self.active.can_redo()
            if on <> self.redo_label:
                if on:
                    self.redoitem.enable(1)
                    self.redoitem.settext(on)
                    self.redo_label = on
                else:
                    self.redoitem.settext("Nothing to redo")
                    self.redoitem.enable(0)
                changed = 1
        if changed:
            DrawMenuBar()

    #
    # Apple menu
    #

    def do_about(self, id, item, window, event):
        EasyDialogs.Message("A simple single-font text editor based on MacTextEditor")

    #
    # File menu
    #

    def open(self, *args):
        self._open(0)

    def openfile(self, *args):
        self._open(1)

    def _open(self, askfile):
        if askfile:
            path = EasyDialogs.AskFileForOpen(typeList=('TEXT',))
            if not path:
                return
            name = os.path.split(path)[-1]
            try:
                fp = open(path, 'rb') # NOTE binary, we need cr as end-of-line
                data = fp.read()
                fp.close()
            except IOError, arg:
                EasyDialogs.Message("IOERROR: %r" % (arg,))
                return
        else:
            path = None
            name = "Untitled %d"%self.num
            data = ''
        w = MlteWindow(self)
        w.open(path, name, data)
        self.num = self.num + 1

    def closewin(self, *args):
        if self.active:
            self.active.close()
        else:
            EasyDialogs.Message("No active window?")

    def save(self, *args):
        if self.active:
            self.active.menu_save()
        else:
            EasyDialogs.Message("No active window?")

    def saveas(self, *args):
        if self.active:
            self.active.menu_save_as()
        else:
            EasyDialogs.Message("No active window?")


    def quit(self, *args):
        for w in self._windows.values():
            w.close()
        if self._windows:
            return
        self._quit()

    #
    # Edit menu
    #

    def undo(self, *args):
        if self.active:
            self.active.menu_undo()
        else:
            EasyDialogs.Message("No active window?")

    def redo(self, *args):
        if self.active:
            self.active.menu_redo()
        else:
            EasyDialogs.Message("No active window?")

    def cut(self, *args):
        if self.active:
            self.active.menu_cut()
        else:
            EasyDialogs.Message("No active window?")

    def copy(self, *args):
        if self.active:
            self.active.menu_copy()
        else:
            EasyDialogs.Message("No active window?")

    def paste(self, *args):
        if self.active:
            self.active.menu_paste()
        else:
            EasyDialogs.Message("No active window?")

    def clear(self, *args):
        if self.active:
            self.active.menu_clear()
        else:
            EasyDialogs.Message("No active window?")

    #
    # Other stuff
    #

    def idle(self, event):
        if self.active:
            self.active.do_idle(event)
        else:
            Qd.SetCursor(Qd.GetQDGlobalsArrow())

def main():
    Mlte.TXNInitTextension(0)
    try:
        App = Mlted()
        App.mainloop()
    finally:
        Mlte.TXNTerminateTextension()

if __name__ == '__main__':
    main()
