from gi import pygtkcompat

pygtkcompat.enable()
pygtkcompat.enable_gtk(version='3.0')

import gtk

from . import commands
import odml
from .TreeView import TerminologyPopupTreeView
from .DragProvider import DragProvider

from .dnd.targets import ValueDrop, PropertyDrop, SectionDrop
from .dnd.odmldrop import OdmlDrag, OdmlDrop
from .dnd.text import TextDrag, TextDrop, TextGenericDropForSectionTV

class SectionView(TerminologyPopupTreeView):
    """
    A key-value ListStore based TreeView

    showing properties and allows to edit them
    based on the format-description of the obj's class
    """
    def __init__(self, registry):
        super(SectionView, self).__init__()
        self.add_column(name="Name", edit_func=self.on_edited)
        self._treeview.show()

        # set up our drag provider
        dp = DragProvider(self._treeview)
        _exec = lambda cmd: self.execute(cmd)
        pd = PropertyDrop(exec_func=_exec)
        sd = SectionDrop(exec_func=_exec)
        for target in [
            OdmlDrag(mime="odml/section-ref", inst=odml.section.Section),
            TextDrag(mime="odml/section", inst=odml.section.Section),
            TextDrag(mime="TEXT"),
            OdmlDrop(mime="odml/property-ref", target=pd, registry=registry, exec_func=_exec),
            OdmlDrop(mime="odml/section-ref", target=sd, registry=registry, exec_func=_exec),
            TextDrop(mime="odml/property", target=pd),
            TextDrop(mime="odml/section", target=sd),
            TextGenericDropForSectionTV(exec_func=_exec),
            ]:
            dp.append(target)
        dp.execute = _exec
        dp.connect()

    def set_model(self, model):
        self._treeview.set_model(model)

    def on_object_edit(self, tree_iter, attr, new_value):
        section = tree_iter._obj
        cmd = commands.ChangeValue(
            object    = section,
            attr      = "name",
            new_value = new_value)

        self.execute(cmd)

    def get_popup_menu_items(self):
        model, path, obj = self.popup_data
        original_object = obj
        if obj is None:
            obj = model.document
        menu_items = self.create_popup_menu_items("Add Section", "Empty Section", obj, self.add_section, lambda sec: sec.sections, lambda sec: "%s [%s]" % (sec.name, sec.type), stock="odml-add-Section")
        if original_object is not None:
            menu_items.append(self.create_popup_menu_del_item(original_object))
            if original_object.is_merged:
                menu_items.append(self.create_menu_item("Unresolve links (collapse)", self.on_expand, original_object))
            elif original_object.can_be_merged:
                menu_items.append(self.create_menu_item("Resolve links (expand)", self.on_expand, original_object))
        return menu_items

    def on_expand(self, widget, obj):
        """
        called when the user requests an object to be expanded/collapsed
        """
        if obj.is_merged:
            obj.clean()
        else:
            obj.merge()

    def add_section(self, widget, obj_section_pair):
        """
        popup menu action: add section

        add a section to the selected section (or document if None selected)
        """
        (obj, section) = obj_section_pair
        
        if section is None:
            name = self.get_new_obj_name(obj.sections, prefix='Unnamed Section')
            section = odml.Section(name=name)
        else:
            prefix = section.name
            name = self.get_new_obj_name(obj.sections, prefix=prefix)
            section = section.clone()
            section.name = name

            # It is a terminology section. By default, pull in all its properties.
            section.merge()

        cmd = commands.AppendValue(obj=obj, val=section)

        self.execute(cmd)

        # Expand tree if the parent object is a section
        if isinstance(obj, odml.section.Section):
            tv = self._treeview
            (model, tree_iter) = tv.get_selection().get_selected()
            tv.expand_row(model.get_path(tree_iter), False)

    def on_selection_change(self, tree_selection):
        """
        the selection moved

        now callback another method with more meaningful information
        """
        (model, tree_iter) = tree_selection.get_selected()
        if not tree_iter:
            return

        return self.on_section_change(model.get_object(tree_iter))

    def on_section_change(self, section):
        """
        the user selected a new section
        """
        pass

    def on_get_tooltip(self, model, path, iter, tooltip):
        """
        set the tooltip text, if the gui queries for it
        """
        obj = model.get_object(iter)

        merged = obj.get_merged_equivalent()
        info = []
        if merged is not None:
            # the object is only merged
            info.append('merged:%s' % merged.get_path())
            if not merged == obj:
                # the object is merged but differs from its merged equivalent
                info[-1] += ' (modified)'

        merged = obj.get_terminology_equivalent()
        if merged is not None:
            # the object has an associated terminology equivalent
            info.append('terminology: %s:%s' % (obj.get_repository(), merged.get_path()))

        text = "%s [%s]" % (obj.name, obj.type)
        if info:
            text += "\n\n" + '\n'.join(info)

        doc = obj.document
        error = ""
        if doc and hasattr(doc, "validation_result"):
            errors = doc.validation_result[obj]
            if errors:
                error = "\n\nErrors:\n" + "\n".join([e.msg for e in errors])

        tooltip.set_text(text + error)
        return True
