#!/usr/bin/python

import ri_tk as display
import sys
import ri_cmd

class GridManagement:
    ''' implement grid management '''
    def __init__(self, xml_node):
        self.rows = xml_node.attributes['rows'].value
        self.columns = xml_node.attributes['columns'].value
        self.cf_list=[]
        for cf in xml_node.childNodes:
            if cf.nodeType != cf.ELEMENT_NODE or cf.nodeName != "configure":
                continue
            if "row" in cf.attributes.keys():
                cf_func = "rowconfigure"
                n = cf.attributes["row"].value
            elif "column" in cf.attributes.keys():
                cf_func = "columnconfigure"
                n = cf.attributes["column"].value
            else:
                continue
            self.cf_list.append((cf_func, n, cf.attributes["weight"].value))

class GridLocation:
    ''' implement grid_location in interface xml '''
    def __init__(self, xml_node):
        self.dict={}
        for a in xml_node.attributes.values():
            self.dict[a.name] = a.value

class Action:
    ''' implement action in interface xml '''
    def __init__(self, xml_node):
        self.dict={}
        for a in xml_node.attributes.values():
            self.dict[a.name] = a.value
        self.scrolls = []
        for node in xml_node.childNodes:
            if node.nodeName == 'scroll':
                self.scrolls.append((node.attributes['scrolling'].value, node.attributes['scrolled'].value))

class Widget:
    ''' implement widget in interface xml '''
    current_widget=""
    dict={}

    def __init__(self, xml_node):
        if 'name' in xml_node.attributes.keys():
            self.name = xml_node.attributes["name"].value
            Widget.dict[self.name] = self

        self.tp   = xml_node.attributes["type"].value
        self.attr = {}
        self.widgets=[]
        self.variables=[]
        self.bindings = []
        for node in xml_node.childNodes:
            if node.nodeType == node.ELEMENT_NODE:
                if node.nodeName == "grid_management":
                    self.grid_management = GridManagement(node)
                elif node.nodeName == "grid_location":
                    self.grid_location = GridLocation(node)
                elif node.nodeName == "widget_attribute":
                    for a in node.attributes.values():
                      self.attr[a.name] = a.value  
                elif node.nodeName == "widget":
                    self.widgets.append(Widget(node))
                elif node.nodeName == "variable":
                    self.variables.append((node.attributes["name"].value, \
                                       node.attributes["type"].value, \
                                       "value" in node.attributes.keys() and node.attributes["value"].value or "" ))
                elif node.nodeName == "action":
                    self.action = Action(node)
                elif node.nodeName == 'binding':
                    seq = node.attributes["sequence"].value
                    self.bindings.append((seq, \
                                         node.attributes["function"].value))

        if 'construct' in xml_node.attributes.keys():
            getattr(ri_cmd, xml_node.attributes["construct"].value)(self)


    def add_sub_widget(self, w):
        self.widgets.append(w)

    def show(self):
        Widget.current_widget = self
        display.create_widget(self)
       
    def hide(self):
        display.destroy_widget(self)

class MessageBox:
    ''' implement dialog in interface.xml '''
    dict={}

    def __init__(self, xml_node):
        self.name    = xml_node.attributes["name"].value
        self.tp      = xml_node.attributes["type"].value
        self.title   = xml_node.attributes["title"].value
        self.message = xml_node.attributes["message"].value

        MessageBox.dict[self.name] = self

    def show(self):
        ''' display dialog'''
        code = display.create_message_box(self)
        return code

class TopWindow:
    ''' implement top_window in interface.xml - top_window corresponds to Toplevel in Tkinter '''
    dict={}
    def __init__(self, xml_node):
        self.name = xml_node.attributes["name"].value
        TopWindow.dict[self.name] = self
        self.attr = {}
        self.widgets = []
        for node in xml_node.childNodes:
            if node.nodeType == node.ELEMENT_NODE:
                if node.nodeName == 'grid_management':
                    self.grid_management = GridManagement(node)
                elif node.nodeName == "widget_attribute":
                    for a in node.attributes.values():
                      self.attr[a.name] = a.value
                elif node.nodeName == "widget":
                    self.widgets.append(Widget(node))

    def show(self):
        display.create_top_window(self)

    def hide(self):
        display.destroy_top_window(self)

class Sequence:
    ''' implement sequence in interface xml'''
    dict={}

    def __init__(self, xml_node):
        self.steps = [ s.attributes["name"].value for s in xml_node.childNodes
                 if s.nodeType == s.ELEMENT_NODE and s.nodeName == "widget" ]
        self.current_step = 0
        Sequence.dict[xml_node.attributes["name"].value] = self

    def set_current_step(self, st):
        ''' set current step based on input step name'''
        self.current_step = self.steps.index(st)

    @staticmethod
    def set_current_sequence(name):
        Sequence.current_sequence = Sequence.dict[name]

    @staticmethod
    def current():
        return (Sequence.current_sequence, Sequence.current_sequence.steps[Sequence.current_sequence.current_step])

    @staticmethod
    def previous():
        if Sequence.current_sequence.current_step:
            Sequence.current_sequence.current_step -= 1
            return Sequence.current_sequence.steps[Sequence.current_sequence.current_step]

    @staticmethod
    def next():
        if Sequence.current_sequence.current_step < len(Sequence.current_sequence.steps)-1:
            Sequence.current_sequence.current_step += 1
            return Sequence.current_sequence.steps[Sequence.current_sequence.current_step]

class Text:
    ''' implement text in interface.xml '''
    dict={}

    def __init__(self, xml_node):
        for n in xml_node.childNodes:
            if n.nodeType == n.ELEMENT_NODE:
                if n.nodeName == 'English': self.english = n.firstChild.data
                elif n.nodeName == 'Chinese': self.chinese = n.firstChild.data

        if 'key' in xml_node.attributes.keys():
            self.key = xml_node.attributes['key'].value
        else:
            self.key = self.english
        Text.dict[self.key.lower()] = self

def construct(xml_root):
    ''' construct Widget's static members'''
    for n in xml_root.childNodes:
        if n.nodeType == n.ELEMENT_NODE:
            if n.nodeName == "widget": Widget(n)
            elif n.nodeName == "message_box": MessageBox(n)
            elif n.nodeName == "top_window":  TopWindow(n)
            elif n.nodeName == "sequence":    Sequence(n)
            elif n.nodeName == "text":        Text(n)
 
def init_display(bw):
    ''' base widget name'''
    display.init(Widget.dict[bw])

def mainloop():
    '''run message main loop '''
    display.root_window.mainloop()
