# Copyright (C) 2005 by Async Open Source
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser 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 Lesser 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.

from gettext import gettext as _

import gtk
from gazpacho.util import get_bool_from_string_with_default

# Register adapters
from kiwi.ui.gazpacholoader import HyperLinkAdaptor, ComboEntryAdaptor

root_library = 'kiwi.ui.widgets'
widget_prefix = 'Kiwi'

# pyflakes
HyperLinkAdaptor
ComboEntryAdaptor

class ColumnDefinitionsAdaptor(object):
    def __init__(self):
        self._editor = ListColumnDefinitionsEditor()

    def set(self, context, kiwilist, value):
        kiwilist.set_property('column-definitions', value)

    def create_editor(self, context):
        button = gtk.Button(_('Edit...'))
        button.set_data('connection-id', -1)
        return button

    def update_editor(self, context, button, kiwilist, proxy):
        connection_id = button.get_data('connection-id')
        if connection_id != -1:
            button.disconnect(connection_id)
        connection_id = button.connect('clicked', self._editor_edit, kiwilist,
                                       proxy, context)
        button.set_data('connection-id', connection_id)

    def _editor_edit(self, button, kiwilist, proxy, context):
        application_window = context.get_application_window()
        self._editor.set_transient_for(application_window)
        self._editor.set_widget(kiwilist, proxy)
        self._editor.present()

(ATTRIBUTE,
 TITLE,
 DATA_TYPE,
 VISIBLE,
 JUSTIFY,
 TOOLTIP,
 FORMAT,
 WIDTH,
 SORTED,
 ORDER) = range(10)

class ListColumnDefinitionsEditor(object):
    """This dialog is used to edit the column definitions of a Kiwi List"""

    def set_widget(self, widget, proxy):
        super(ListColumnDefinitionsEditor, self).set_widget(widget, proxy)
        self.set_title((_('Editing columns of list %s') % self.gwidget.name))
        self._load_columns()

    def _create_widgets(self):
        h_button_box = gtk.HButtonBox()
        h_button_box.set_layout(gtk.BUTTONBOX_START)
        self.add = gtk.Button(stock=gtk.STOCK_ADD)
        self.add.connect('clicked', self._on_add_clicked)
        h_button_box.pack_start(self.add)
        self.remove = gtk.Button(stock=gtk.STOCK_REMOVE)
        self.remove.connect('clicked', self._on_remove_clicked)
        h_button_box.pack_start(self.remove)
        self.up = gtk.Button(stock=gtk.STOCK_GO_UP)
        self.up.connect('clicked', self._on_up_clicked)
        h_button_box.pack_start(self.up)
        self.down = gtk.Button(stock=gtk.STOCK_GO_DOWN)
        self.down.connect('clicked', self._on_down_clicked)
        h_button_box.pack_start(self.down)
        self.vbox.pack_start(h_button_box, False, False)
        self.model = gtk.ListStore(str, str, str, bool, str, str, str, int,
                                   bool, str)
        self.treeview = gtk.TreeView(self.model)
        self.treeview.set_size_request(580, 300)
        selection = self.treeview.get_selection()
        selection.connect('changed', self._on_selection__changed)
        for i, title in enumerate(('Attribute',
                                      'Title',
                                      'Data type')):
            self.treeview.append_column(self._create_text_column(title, i))

        self.treeview.append_column(self._create_bool_column('Visible', 3))
        for i, title in enumerate(('Justify',
                                      'Tooltip',
                                      'Format')):
            self.treeview.append_column(self._create_text_column(title,
                                                                 (i + 4)))

        self.treeview.append_column(self._create_int_column('Width', 7))
        self.treeview.append_column(self._create_bool_column('Sorted', 8))
        self.treeview.append_column(self._create_text_column('Order', 9))
        sw = gtk.ScrolledWindow()
        sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
        sw.add(self.treeview)
        self.vbox.pack_start(sw, True, True)
        label = gtk.Label()
        instructions = """<small>Valid values:
        <b>Data type:</b> str, int, float or date
        <b>Justify:</b> left, center or right
        <b>Order:</b> ascending or descending</small>"""
        label.set_alignment(0.0, 0.0)
        label.set_markup(instructions)
        self.vbox.pack_start(label, False, False)

    def _create_text_column(self, title, index):
        renderer = gtk.CellRendererText()
        renderer.set_property('editable', True)
        renderer.connect('edited', self._on_text_renderer__edited, index)
        col = gtk.TreeViewColumn(title, renderer, text=index)
        return col

    def _create_bool_column(self, title, index):
        renderer = gtk.CellRendererToggle()
        renderer.set_property('activatable', True)
        renderer.connect('toggled', self._on_toggle_renderer__toggled, index)
        col = gtk.TreeViewColumn(title, renderer, active=index)
        return col

    def _create_int_column(self, title, index):
        col = self._create_text_column(title, index)
        return col

    def _get_default_values(self):
        return ('unnamed', '', 'str', True, 'left', '', '', 1, False, '')

    def _update_proxy(self):
        cols = []
        for column in self.model:
            cols.append('|'.join(map(str, tuple(column))))

        data = '^'.join(cols)
        self.proxy.set_value(data)

    def _load_columns(self):
        self.model.clear()
        cd = self.gwidget.get_glade_property('column-definitions').value
        if not cd:
            return

        for col in cd.split('^'):
            (attr, title, data_type,
             visible, justify, tooltip,
             format, width, sorted, order) = col.split('|')

            visible = get_bool_from_string_with_default(visible, True)
            width = int(width)
            sorted = get_bool_from_string_with_default(sorted, False)
            self.model.append((attr, title, data_type,
                               visible, justify, tooltip,
                               format, width, sorted, order))

    def _on_add_clicked(self, button):
        row_iter = self.model.append(self._get_default_values())
        path = self.model.get_path(row_iter)
        col = self.treeview.get_column(0)
        self.treeview.set_cursor(path, col, True)
        self._update_proxy()

    def _on_remove_clicked(self, button):
        model, selected_iter = self.treeview.get_selection().get_selected()
        if selected_iter:
            model.remove(selected_iter)
            self._update_proxy()

    def _on_up_clicked(self, button):
        model, selected_iter = self.treeview.get_selection().get_selected()
        if not selected_iter:
            return

        path = self.model.get_path(selected_iter)
        prev_iter = self.model.get_iter(((path[0] - 1)))
        if not prev_iter:
            return

        model.swap(prev_iter, selected_iter)
        self._update_proxy()
        self._update_buttons()

    def _on_down_clicked(self, button):
        model, selected_iter = self.treeview.get_selection().get_selected()
        if not selected_iter:
            return

        next_iter = model.iter_next(selected_iter)
        if not next_iter:
            return

        model.swap(selected_iter, next_iter)
        self._update_proxy()
        self._update_buttons()

    def _on_text_renderer__edited(self, renderer, path, new_text, col_index):
        value = new_text
        if col_index == WIDTH:
            try:
                value = int(new_text)
            except ValueError:
                return

        row = self.model[path[0]]
        row[col_index] = value
        if col_index == ATTRIBUTE:
            title = row[TITLE]
            if not title:
                row[TITLE] = value.capitalize()
        self._update_proxy()

    def _on_toggle_renderer__toggled(self, renderer, path, col_index):
        row = self.model[path[0]]
        row[col_index] = not row[col_index]
        self._update_proxy()

    def _on_selection__changed(self, selection):
        self._update_buttons()

    def _update_buttons(self):
        selection = self.treeview.get_selection()
        model, selected_iter = selection.get_selected()
        if not selected_iter:
            self.remove.set_sensitive(False)
            self.down.set_sensitive(False)
            self.up.set_sensitive(False)
            return

        self.remove.set_sensitive(True)
        path = model.get_path(selected_iter)[0]
        size = len(model)
        if path == 0:
            self.up.set_sensitive(False)
            if size > 1:
                self.down.set_sensitive(True)

        if path == size - 1:
            self.down.set_sensitive(False)
            if size > 1:
                self.up.set_sensitive(True)

        if path > 0 and path < (size - 1):
            self.up.set_sensitive(True)
            self.down.set_sensitive(True)
