#!/usr/bin/env python

import os
import Tkinter
import ScrolledText
import tkFileDialog
import tkMessageBox
import argparse

# temporary files
TMP_MSQ = '.msqgui.msq'
TMP_PNG = '.msqgui.png'

def run_meseq(contents):
    # create a temporary file
    f = open(TMP_MSQ, 'w')
    f.write(contents.encode('utf8'))
    f.close()
    os.system('meseq -o %s %s' % (TMP_PNG, TMP_MSQ))

class MeseqGui(object):

    def __init__(self):
        self.root = Tkinter.Tk(className="MeseqGui")
        self.paned_window = Tkinter.PanedWindow(self.root, orient=Tkinter.HORIZONTAL)

        # menu bar
        self.menubar = Tkinter.Menu(self.root)
        filemenu = Tkinter.Menu(self.menubar, tearoff=0)
        filemenu.add_command(label="Save", command=self.save)
        filemenu.add_command(label="Quit", command=self.quit)
        self.menubar.add_cascade(label="File", menu=filemenu)
        self.root.config(menu=self.menubar)

        # shorcuts
        self.root.bind('<Control-q>', self.quit)
        self.root.bind('<Control-s>', self.save)

        # editor
        self.editor = ScrolledText.ScrolledText(self.paned_window, wrap=Tkinter.N)
        self.editor.bind('<KeyRelease>', self.cb_text_changed)
        self.editor.bind('<ButtonRelease-2>', self.cb_text_changed) # take pasting via the middle button
        self.editor.focus()

        self.image = Tkinter.Label(self.paned_window)
        self.paned_window.add(self.editor)
        self.paned_window.add(self.image)
        self.filename = None
        self.needs_save = False

    def save(self, event=None):
        contents = self.editor.get('1.0', Tkinter.END)
        if self.filename:
            f = open(self.filename, 'w')
            f.write(contents.encode('utf8'))
            f.close()
            self.needs_save = False
        else:
            filename = tkFileDialog.asksaveasfilename()
            if filename:
                self.filename = filename
                self.save()

    def quit(self, event=None):
        if self.needs_save:
            do_quit_anyway = tkMessageBox.askyesno('Quit',
                    'There are unsaved changes.\n' +
                    'If you quit now, these changes will be lost.\n' +
                    'Quit anyway?')
            if not do_quit_anyway: return
        self.root.quit()

    def set_file_contents(self, filename):
        if os.path.exists(filename):
            f = open(filename)
            text = f.read()
            self.editor.insert(Tkinter.END, text.decode('utf-8'))
            
        self.filename = filename

    def cb_text_changed(self, event):
        if event.char == '': return
        self.needs_save = True
        self.update_diagram()

    def update_diagram(self):
        contents = self.editor.get('1.0', Tkinter.END)
        run_meseq(contents)
        self.update_image(TMP_PNG)

    def update_image(self, filename):
        try:
            img = Tkinter.PhotoImage(file=filename)
            self.image.config(image=img)
            self.img_ref = img # keep a reference
        except Tkinter.TclError:
            self.image.config(text='no image')

    def display(self):
        self.update_diagram()
        self.paned_window.pack(side=Tkinter.TOP, expand=Tkinter.Y, fill=Tkinter.BOTH, pady=2, padx=2)
        self.root.mainloop()


def parse_cmdline():
    parser = argparse.ArgumentParser(description=main.__doc__, prog='meseqgui')
    parser.add_argument('file', nargs='?', help='msq file')
    return parser.parse_args()

def main():
    args = parse_cmdline()

    filename = args.file

    # clean up the temporary files
    for tmp in [ TMP_MSQ, TMP_PNG ]:
        try:
            os.unlink(tmp)
        except OSError:
            pass

    msqgui = MeseqGui()
    if filename: msqgui.set_file_contents(filename)
    msqgui.display()


if __name__ == '__main__':
    main()

