# debpartial_mirror_ui - User Interface for partial debian mirror package tool
# (c) 2006 Otavio Salvador <otavio@debian.org>
# (c) 2006 Marco Presi <zufus@debian.org>
#
# 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 2 of the License, or
# (at your option) any later version.
#
# 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.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA


#TODO: Create a CellRenderer that contains both the toggle button and the text.



import gobject
from gtk import VBox, Label, TreeView, \
                 TreeIter, TreeViewColumn, TreeStore, \
                 CellRendererToggle, CellRendererText, \
                 gdk, Frame, SHADOW_IN, SELECTION_SINGLE

from debpartial_mirror import Backend
from debpartial_mirror import Config


class BackendBrowser(VBox):
    """ A widget to browse Backend configuration """


    __gsignals__ = dict(backend_changed=(gobject.SIGNAL_RUN_FIRST,
                                         gobject.TYPE_NONE,
                                         (gobject.TYPE_STRING,)))

    
    def __init__(self, cnf, debug=True):
        super(BackendBrowser, self).__init__()

        self._debug_mode = debug
        self.l = Label ('Backend Browser')
        bframe = Frame ()
        
        self.b = TreeView ()

        self.read_backends (cnf)
        
        (self.COLUMN_SEL,
         self.COLUMN_NAME) = range(2)

        self.create_browser (self.b)
        bframe.add (self.b)

        self.pack_start (self.l, False, False, 5)
        self.pack_start (bframe, True)

        self.show_all()



    def _get_backends (self, cnf, type):
        """Get the backend list from config file"""
        backend = []
        for b in cnf.get_backends ()[type]:
            backend.append(Backend.MirrorBackend (b.section, cnf))
        return backend

    def _get_mirrors (self, cnf):
        return self._get_backends (cnf, 0)
    
    def _get_merges (self, cnf):
        return self._get_backends (cnf, 1)

    def read_backends (self, cnf):
        """Read the backends defined in the conf file """
        self.mirrors = self._get_mirrors(cnf)
        self.merges  = self._get_merges(cnf)


    def create_browser (self, b):
        ''' Create a TreeView that allows to browse all the backend
            defined in the Config file'''

        b.set_property ('visible', True)
        b.set_property ('can_focus', True)
        b.set_property ('headers_visible', True)
        b.set_property ('enable_search', True)
        b.set_property ('reorderable', True)
        b.set_property ('rules_hint',False)
        b.set_property ('fixed_height_mode', False)
        b.set_property ('hover_selection', False)
        b.set_property ('hover_expand', False)

        b.connect ("event", self.on_b_event)

        model = TreeStore (gobject.TYPE_BOOLEAN,
                           gobject.TYPE_STRING)

        self.update_backends_treeview (model)
        b.set_model (model)

        #column for backend selection 
        toggle = CellRendererToggle ()
        toggle.set_property ("activatable", True)
        toggle.connect ('toggled', self.backend_toggled_cb, model)

        text = CellRendererText ()
        text.set_property ("xalign", 0.0)
        
        col = TreeViewColumn()

        col.pack_start (toggle, False)
        col.pack_start (text, True)

        col.add_attribute (toggle, 'active', self.COLUMN_SEL)
        col.add_attribute (text, 'markup', self.COLUMN_NAME)

        col.set_clickable (True)
        col.set_sort_column_id (self.COLUMN_NAME)
        b.append_column (col)

        select = b.get_selection ()
        select.set_mode (SELECTION_SINGLE)
        select.connect ('changed', self.backend_selection_changed_cb)
        b.expand_all()
        b.set_rules_hint (True)
        b.set_headers_visible (False)
        b.show_all()

    def update_backends_treeview (self, model):
        """ Update the browser """
        model.clear ()

        global_iter = model.append (None)
        model.set (global_iter,
                   self.COLUMN_NAME, "<b>Global</b>")
        
        mirrors_iter = model.append(None)
        model.set (mirrors_iter,
                   self.COLUMN_SEL, False,
                   self.COLUMN_NAME, "<b>Mirrors</b>")

        merges_iter = model.append(None)
        model.set (merges_iter,
                   self.COLUMN_SEL, False,
                   self.COLUMN_NAME, "<b>Merges</b>")

        for i in self.mirrors:
            mirrors_list_iter = model.append (mirrors_iter)
            model.set (mirrors_list_iter,
                       #self.COLUMN_SEL, None,
                       self.COLUMN_NAME, i._name)

        if len(self.mirrors) == 0:
            mirrors_list_iter = model.append (mirrors_iter)
            model.set (mirrors_list_iter,
                       #self.COLUMN_SEL, None,
                       self.COLUMN_NAME, "<i>No Mirrors defined</i>")


        for i in self.merges:
            merges_list_iter = model.append (merges_iter)
            model.set (merges_list_iter,
                       #self.COLUMN_SEL, None,
                       self.COLUMN_NAME, i._name)
        
        if len(self.merges) == 0:
            merges_list_iter = model.append (merges_iter)
            model.set (merges_list_iter,
                       #self.COLUMN_SEL, None,
                       self.COLUMN_NAME, "<i>No Merges defined</i>")

        

    def backend_toggled_cb (self, toggle, path, model):
        """ Change the toggle status of the selected backend.
        If a class of backends is choosen (mirrors, merges,..) it
        toggles all the backends of that category
        
        toggle: is the toggle widget that has been toggled
        path:   represent the item path
        app:    main app
        
        """
        status = toggle.get_active()
        iter = model.get_iter (path)

        
        model.set (iter, self.COLUMN_SEL, (not status))
        
        if model.iter_has_child (iter):
            child = model.iter_children (iter)
            while (isinstance(child, TreeIter)):
                model.set (child, self.COLUMN_SEL, (not status))
                child = model.iter_next(child)
                
                self.b.set_model (model)


    def backend_selection_changed_cb (self, selection):
        """ When a backend is selected, we show its properties in the property
        treeview."""
        print self
        print selection
        (model, iter) = selection.get_selected ()
        if isinstance (iter, TreeIter):
            print "%s selected\n" % model.get_value (iter, self.COLUMN_NAME)
            self.emit ('backend_changed', model.get_value (iter, self.COLUMN_NAME))
            


    def on_b_event(self, treeview, event):
        if event.type == gdk.BUTTON_PRESS and event.button == 3:
            self.do_popup (event)

    def do_popup(self, event):
        """open popup """
        print "Opening popup"
