import mforms
import option
#import options_layout

utest = False
if __name__ == "__main__":
    utest = True
    import pprint


#===============================================================================
#
#===============================================================================
# A mere container for some utility info
class WBAOptionLayoutRow(object):
    path    = None
    visible = None

    #---------------------------------------------------------------------------
    def __init__(self, path):
        self.path    = path
        self.visible = True

    #---------------------------------------------------------------------------
    def reset_path(self):
        self.path = None


#===============================================================================
#
#===============================================================================
class WBAOptionsLayout(object):
    grid         = None # UI widget
    layout       = None # layout dict used to build current layout
    rows_index   = None # dict: Option name -> WBAOptionLayoutRow
    column_names = None # dict: column name -> column id
    sources      = None # List of entities which can return data based on (tag, col_id)

    #---------------------------------------------------------------------------
    def __init__(self, grid, layout_dict, columns):
        object.__init__(self)
        self.grid = grid
        self.column_names = {}

        for column_name in columns:
            colid = self.grid.add_column(column_name);
            self.column_names[column_name] = colid

        self.sources = {}
        #[None] * max(self.column_names.values())
        self.rebuild_ui(layout_dict)


    #---------------------------------------------------------------------------
    def add_source(self, source, column_name):
        colid = self.column_names[column_name]
        self.sources[colid] = source

    #---------------------------------------------------------------------------
    # In case internal repr was changed (the layout must remain untouched)
    # updates view
    def update_ui(self):
        # walk rows_index and request 
        for name, option_layout_row in self.rows_index.iteritems():
            if type(option_layout_row) is WBAOptionLayoutRow:
                # request data from each source and set values to self.grid accordingly
                for column_name, colid in self.column_names.iteritems():
                    source = self.sources.get(colid)
                    if source:
                        value, vtype, aux_param = source.get_typed_value(name)
                        if vtype == mforms.CellText:
                            editable = aux_param
                            self.grid.set_str_value(option_layout_row.path, colid, value, editable)
                        elif vtype == mforms.CellBool:
                            editable = aux_param
                            self.grid.set_bool_value(option_layout_row.path, colid, value, editable)
                        elif vtype == mforms.CellEnum:
                            enum_list = aux_param
                            self.grid.set_enum(option_layout_row.path, colid, enum_list)
                            self.grid.set_str_value(option_layout_row.path, colid, value, True)

    #---------------------------------------------------------------------------
    # The method resets current internal repr together with view. After that the
    # internal repr is rebuilt, the view is rebuilt accordingly.
    def rebuild_ui(self, new_layout_dict):
        # Clear mapped paths
        self.layout = new_layout_dict # we may have simpler/shorted layout passed, e.g. for diff viewing
        self.rows_index = {} # as internal view repr will be rebuilt, we do not need old rows
        self.grid.clear(); # clear the grid itself

        for top_group_name, top_group_content in self.layout:
            group_path = self.grid.append_header(top_group_name)
            for group_name, group_items in top_group_content:
                if type(group_items) is list:
                    path = self.grid.append_row(group_path)
                    self.grid.set_row_caption(path, group_name) # That should be the data to display for the group header
                    self.grid.set_cell_type(path, -1, mforms.CellGroupHeader)
                    for item in group_items:
                        if type(item) is str or type(item) is unicode:
                            path = self.grid.append_row(group_path)
                            self.rows_index[item] = WBAOptionLayoutRow(path)
                elif type(item) is str or type(item) is unicode:
                    path = self.grid.append_row(group_path)
                    self.rows_index[item] = WBAOptionLayoutRow(path)

    #---------------------------------------------------------------------------
    def value_edited(self, path, colid):
        option_name = self.grid.get_row_tag(path, colid)
        src = self.sources[colid] if colid < len(self.sources) else None
        if src:
            src.value_changed(self.grid, path, colid)


if utest:
    class mforms:
        CellGroupHeader = 5


    class TestGrid:
        def __init__(self):
            self.cols = 0
            self.storage = []

        def add_column(self, s):
            self.cols += 1
            return self.cols

        def clear(self):
            self.storage = []

        def append_header(self, v):
            self.storage.append((v, []))
            print "Appending header %s" % str(v)
            return (len(self.storage) - 1,)

        def append_row(self, v):
            group_name, group = self.storage[v[0]]
            group.append([])
            r = (v[0], len(group) - 1)
            print "Appending row to group path %s" % str(r)
            return r

        def set_row_tag(self, v, c):
            pass

        def set_cell_type(self, v, c, t):
            pass

    class DummySource:
        def get_value(self, name):
            return "Value of " + name

    olayout = [ ( 'General',
                        [ ('Networking', ['enable-named-pipe', 'port', 'skip-networking']),
                          ('Directories', ['datadir', 'basedir', 'tmpdir']),
                          ('Memory usage', ['sort_buffer_size']),
                        ]
               ),
               ( 'Advanced',
                        [
                          ( 'Localization', [ 'default-collation', 'default-time-zone', 'language' ] )
                        ]
               )
             ]

    grid = TestGrid()
    layout = WBAOptionsLayout(grid, olayout, ["Column1", "Column2"])
    layout.add_source(DummySource(), "Column1")
    layout.add_source(DummySource(), "Column2")
    layout.update_ui()
    layout.rebuild_ui(olayout)
