"""
Abstract classes for element-like Diagram items.
"""

import gobject
import cairo
import gaphas
from zope import component
from diagramitem import DiagramItem
from gaphor.diagram.style import get_text_point


class ElementItem(gaphas.Element, DiagramItem):
    __style__ = {
        'min-size': (0, 0),
        'stereotype-padding': (5, 10, 5, 10),
	'background': 'solid',
	'background-color': (1, 1, 1, 0.8),
	'highlight-color': (0, 0, 1, 0.4),
	'background-gradient': ((0.8, 0.8, 0.8, 0.5), (1.0, 1.0, 1.0, 0.5))
    }

    def __init__(self, id=None):
        gaphas.Element.__init__(self)
        DiagramItem.__init__(self, id)

        self.min_width   = self.style.min_size[0]
        self.min_height  = self.style.min_size[1]
        self.auto_resize = 0


    def save(self, save_func):
        save_func('matrix', tuple(self.matrix))
        for prop in ('width', 'height'):
            self.save_property(save_func, prop)
        DiagramItem.save(self, save_func)


    def load(self, name, value):
        if name == 'matrix':
            self.matrix = eval(value)
        else:
            DiagramItem.load(self, name, value)


    def setup_canvas(self):
        gaphas.Element.setup_canvas(self)
        self.register_handlers()


    def teardown_canvas(self):
        gaphas.Element.teardown_canvas(self)
        self.unregister_handlers()


    def pre_update(self, context):
        #super(ElementItem, self).pre_update(context)
        self.update_stereotype()
        DiagramItem.pre_update(self, context)
        gaphas.Element.pre_update(self, context)


    def point(self, pos):
        d1 = gaphas.Element.point(self, pos)
        d2 = DiagramItem.point(self, pos)
        return min(d1, d2)


    def post_update(self, context):
        gaphas.Element.post_update(self, context)
        DiagramItem.post_update(self, context)


    def fill_background(self, context):
	cr = context.cairo
	cr.save()
	try:
	    if self.style.background == 'solid':
		cr.set_source_rgba(*self.style.background_color)
		cr.fill_preserve()
		
	    elif self.style.background == 'gradient':
		# TODO: check if style is gradient
		g = cairo.LinearGradient(0, 0, self.width, self.height)
		for i, c in enumerate(self.style.background_gradient):
		    g.add_color_stop_rgba(i, *c)
		cr.set_source(g)
		cr.fill_preserve()
	finally:
	    cr.restore()

    def highlight(self, context):
	cr = context.cairo
	cr.save()
	try:
	    if context.dropzone:
		cr.set_source_rgba(*self.style.highlight_color)
		cr.set_line_width(cr.get_line_width() * 3.141)
		cr.stroke_preserve()
	finally:
	    cr.restore()

    def draw(self, context):
	self.fill_background(context)
        self.highlight(context)
        gaphas.Element.draw(self, context)
        DiagramItem.draw(self, context)


    def text_align(self, extents, align, padding, outside):
        x, y = get_text_point(extents, self.width, self.height,
                align, padding, outside)

        return x, y


# vim:sw=4:et:ai
