"""
Object node item.
"""

import itertools

from gaphas.state import observed, reversible_property
from gaphor import UML
from gaphor.core import inject

from gaphor.diagram.nameditem import NamedItem
from gaphor.diagram.style import ALIGN_CENTER, ALIGN_BOTTOM


DEFAULT_UPPER_BOUND = '*'


class ObjectNodeItem(NamedItem):
    """
    Representation of object node. Object node is ordered and has upper bound
    specification.

    Ordering information can be hidden by user.
    """
    
    element_factory = inject('element_factory')

    __uml__ = UML.ObjectNode

    STYLE_BOTTOM = {
        'text-align': (ALIGN_CENTER, ALIGN_BOTTOM),
        'text-outside': True,
        'text-align-group': 'bottom',
    }

    def __init__(self, id = None):
        NamedItem.__init__(self, id)

        self._show_ordering = False

        self._upper_bound = self.add_text('upperBound',
            pattern='{ upperBound = %s }',
            style=self.STYLE_BOTTOM,
            visible=self.is_upper_bound_visible)

        self._ordering = self.add_text('ordering',
            pattern = '{ ordering = %s }',
            style = self.STYLE_BOTTOM,
            visible=self._get_show_ordering)

        self.watch('subject<ObjectNode>.upperBound', self.on_object_node_upper_bound)\
            .watch('subject<ObjectNode>.ordering', self.on_object_node_ordering)


    def on_object_node_ordering(self, event):
        if self.subject:
            self._ordering.text = self.subject.ordering
        self.request_update()


    def on_object_node_upper_bound(self, event):
        subject = self.subject
        if subject and subject.upperBound:
            self._upper_bound.text = subject.upperBound
            self.request_update()



    def is_upper_bound_visible(self):
        """
        Do not show upper bound, when it's set to default value.
        """
        subject = self.subject
        return subject and subject.upperBound != DEFAULT_UPPER_BOUND


    @observed
    def _set_show_ordering(self, value):
        self._show_ordering = value
        self.request_update()


    def _get_show_ordering(self):
        return self._show_ordering

    show_ordering = reversible_property(_get_show_ordering, _set_show_ordering)

    def save(self, save_func):
        save_func('show-ordering', self._show_ordering)
        super(ObjectNodeItem, self).save(save_func)

    def load(self, name, value):
        if name == 'show-ordering':
            self._show_ordering = eval(value)
        else:
            super(ObjectNodeItem, self).load(name, value)

    def postload(self):
        if self.subject and self.subject.upperBound:
            self._upper_bound.text = self.subject.upperBound
        if self.subject and self._show_ordering:
            self.set_ordering(self.subject.ordering)
        super(ObjectNodeItem, self).postload()


    def draw(self, context):
        cr = context.cairo
        cr.rectangle(0, 0, self.width, self.height)
        cr.stroke()

        super(ObjectNodeItem, self).draw(context)


    def set_upper_bound(self, value):
        """
        Set upper bound value of object node.
        """
        subject = self.subject
        if subject:
            if not value:
                value = DEFAULT_UPPER_BOUND

            subject.upperBound = value
            #self._upper_bound.text = value


    def set_ordering(self, value):
        """
        Set object node ordering value.
        """
        subject = self.subject
        subject.ordering = value
        self._ordering.text = value



# vim:sw=4:et:ai
