# -*- Mode: Python; py-indent-offset: 4 -*-
# vim: tabstop=4 shiftwidth=4 expandtab
#
# Copyright (C) 2009 Johan Dahlin <johan@gnome.org>
#               2010 Simon van der Linden <svdlinden@src.gnome.org>
#
# This library 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.1 of the License, or (at your option) any later version.
#
# This library 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
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301
# USA

import gobject
from gi.repository import Gdk
from gi.repository import GObject
from ..types import override
from ..importer import modules

Gtk = modules['Gtk']

class GenericTreeModel(gobject.GObject, Gtk.TreeModel):
    __gtype_name__ = "GenericTreeModel"

    def __init__(self):
        gobject.GObject.__init__(self)

    def get_iter(self, path):
        result = None
        success = False
        iter = None

        if isinstance(path, basestring):
            (success, iter) = Gtk.TreeModel.get_iter_from_string(self, path)
        elif isinstance(path, Gtk.TreePath):
            (success, iter) = Gtk.TreeModel.get_iter(self, path)
        elif isinstance(path, (tuple, list)):
            # FIXME: We should be doing this but PyGI doesn't support valists yet
            # gtk_path = Gtk.TreePath.new_from_indices(*path, -1)
            gtk_path = Gtk.TreePath.new()
            for i in path:
                gtk_path.append_index(i)
            (success, iter) = Gtk.TreeModel.get_iter(self, gtk_path)

        else:
            raise ValueError('Expected a string, Gtk.TreePath, tuple or list, got %s' % type(path))

        if success:
            result = iter

        return result

class ListStore(Gtk.ListStore):
    __gtype_name__ = "ListStore"

    def __init__(self):
        gobject.GObject.__init__(self)

    def append(self, row):
        iter_ = Gtk.TreeIter()
        Gtk.ListStore.append(self, iter_)
        if row is not None:
            assert len(row) == self.get_n_columns()
            for i in xrange(0, self.get_n_columns()):
                self.set_value(iter_, i, row[i])
        return iter_

class GenericCellRenderer(Gtk.CellRenderer):
    __gtype_name__ = "GenericCellRenderer"
    def __init__(self):
        gobject.GObject.__init__(self)

    def do_get_size(self, widget, cell_area):
        if hasattr(self, 'on_get_size'):
            return self.on_get_size(widget, cell_area)
        else:
            return 0, 0, 0, 0

    def do_render(self, window, widget, background_area, cell_area, expose_area, flags):
        if hasattr(self, 'on_render'):
            self.on_render(window, widget, background_area, cell_area, expose_area, flags)

class CellRenderer(GenericCellRenderer):
    __gtype_name__ = "MyCellRenderer"

    def __init__(self):
        gobject.GObject.__init__(self)

        self._text = None

    def set_text(self, value):
        self._text = value

    def get_text(self, pspec):
        return self._text

    text = gobject.property(type=str, setter=set_text, getter=get_text)

    def on_get_size(self, widget, cell_area):
        return 20, 20, 0, 0

    def on_render(self, window, widget, background_area, cell_area, expose_area, flags):
        cr = Gdk.cairo_create(window)

        cr.set_line_width(1)
        cr.set_source_rgb(0, 1, 0)
        cr.rectangle(cell_area.x, cell_area.y, cell_area.width, cell_area.height)
        cr.stroke()

        cr.set_source_rgb(1, 1, 0)
        cr.rectangle(cell_area.x, cell_area.y, cell_area.width, cell_area.height)
        cr.fill()

        layout = widget.create_pango_layout(self._text)
        Gtk.paint_layout(widget.get_style(), window, widget.get_state(), True, expose_area,
                         widget, "mec", cell_area.x, cell_area.y, layout)

class Builder(Gtk.Builder):

    def connect_signals(self, obj_or_map):
        print "connecting signals"
        def _full_callback(builder, gobj, signal_name, handler_name, connect_obj, flags, dict_or_obj):
            print ("full callback")
            handler = None
            if isinstance(dict_or_obj, dict):
                handler = dict_or_obj.get(handler_name, None)

            if not handler:
                raise AttributeError('Handler %s not found' % handler_name)

            if not callable(handler):
                raise TypeError('Handler %s is not a method or function' % handler_name)

            after = False #flags and GObject.ConnectFlags.AFTER
            if connect_obj:
                if after:
                    gobj.connect_object_after(signal_name, handler, connect_obj)
                else:
                    gobj.connect_object(signal_name, handler, connect_obj)
            else:
                if after:
                    gobj.connect_after(signal_name, handler)
                else:
                    print "conencting %s to %s" %(signal_name, handler)
                    gobj.connect(signal_name, handler)

        self.connect_signals_full(_full_callback,
                                  obj_or_map);

GenericTreeModel = override(GenericTreeModel)
ListStore = override(ListStore)
GenericCellRenderer = override(GenericCellRenderer)
CellRenderer = override(CellRenderer)
Builder = override(Builder)
__all__ = [GenericTreeModel, ListStore, GenericCellRenderer, CellRenderer, Builder]

import sys

initialized, argv = Gtk.init_check(sys.argv)
if not initialized:
    raise RuntimeError("Gtk couldn't be initialized")
