#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
import os.path
import wx
import re

my_name = "ShowSchedule"
gpl_notice = "\
This program 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 3 of the License, or \
(at your option) any later version.\n\n\
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.\n\n\
You should have received a copy of the GNU General Public License \
along with this program.  If not, see <http://www.gnu.org/licenses/>."

class MainWindow(wx.Frame):
    def __init__(self, parent, title):
        wx.Frame.__init__(self, parent, title=title, size=(500,400))
        self.tree = wx.TreeCtrl(self, 1, wx.DefaultPosition, (-1,-1),
                                wx.TR_HAS_BUTTONS|wx.TR_HIDE_ROOT)
        self.CreateStatusBar() # A Statusbar in the bottom of the window

        # Setting up the menu.
        filemenu= wx.Menu()

        # wx.ID_ABOUT and wx.ID_EXIT are standard IDs provided by wxWidgets.
        menuAbout = filemenu.Append(wx.ID_ABOUT, "&About"," Information about "+my_name)
        filemenu.AppendSeparator()
        menuExit  = filemenu.Append(wx.ID_EXIT,"E&xit"," Terminate "+my_name)

        # Creating the menubar.
        menuBar = wx.MenuBar()
        menuBar.Append(filemenu,"&"+my_name) # Adding the "filemenu" to the MenuBar
        self.SetMenuBar(menuBar)  # Adding the MenuBar to the Frame content.

        # Check command line argument
        if (len(sys.argv) < 2):
            if (len(sys.argv) < 1):
                print "Please specify schedule file to parse (or '-' for standard input)."
            else:
                print sys.argv[0]+" <filename>"
            exit(1)
        if (sys.argv[1] == '-'):
            input = sys.stdin
        elif (os.path.isfile(sys.argv[1])):
            input = open(sys.argv[1], 'r')
        else:
            print "Could not open file "+sys.argv[1]+"."
            exit(1)

        # Populate tree
        tree_root = self.tree.AddRoot("root")
        cactusstring = input.read()
        cactusstring = re.compile("^.*  Startup routines\n", re.S|re.M).\
                                 sub("  Startup routines\n", cactusstring)
        cactusstring = re.compile("---------------------.*", re.S|re.M).sub("", cactusstring)
        self.parse_tree(tree_root, cactusstring.split("\n"), 0, 1)

        # Set Events
        self.Bind(wx.EVT_MENU, self.OnAbout, menuAbout)
        self.Bind(wx.EVT_MENU, self.OnExit, menuExit)

        self.Show(True)

    def parse_tree(self, root, lines, index, depth):
        child = root
        # Go through the lines line by line
        while index < len(lines):
            if (re.match(" {"+str(2*(depth))+"}end ?(if|while|do)", lines[index])):
                index += 1
            # If we find something on the given depth, add it to the list and go on
            elif (re.match(" {"+str(2*(depth))+"}[^ ]", lines[index])):
                line  = lines[index].strip()
                child = self.tree.AppendItem(root, line);
                # Some syntax-coloring
                if (re.match("\[[^\]]+\]", line)):
                    self.tree.SetItemTextColour(child, wx.Colour(0,0,255))
                elif (re.match("GROUP ", line)):
                    self.tree.SetItemTextColour(child, wx.Colour(0,127,0))
                index += 1
            # If we find something one level deeper, call myself with that level
            elif (re.match(" {"+str(2*(depth+1))+"}[^ ]", lines[index])):
                index = self.parse_tree(child, lines, index, depth+1)
            # If we find something else (than an empty line), return
            # the current index to the caller
            elif (len(lines[index]) > 0):
                return index
            else:
                index += 1
        return index

    def OnAbout(self, event):
        # A message dialog box with an OK button. wx.OK is a standard ID in wxWidgets.
        dlg = wx.MessageDialog( self, "© 2010, Frank Löffler\n\n"+
                                      gpl_notice, "About "+my_name, wx.OK)
        dlg.ShowModal() # Show it
        dlg.Destroy() # finally destroy it when finished.

    def OnExit(self,e):
        self.Close(True)  # Close the frame.


app = wx.App(False)  # Create a new app, don't redirect stdout/stderr to a window.
frame = MainWindow(None, my_name) # A Frame is a top-level window.
frame.Show(True)     # Show the frame.
app.MainLoop()

