from coral.modeler.extension import ContextMenuAction
import coral
import qt
from coral.modeler.coralmodeler import CoralModeler
from coral.modeler import modeler
DI = coral.lang.XMIDI20
import coral.modeler.diagram.xmidi_diagrams as diagrams

CQUERY=coral.lang.CQUERY10
TM=coral.getTransactionManager()

def languageSort(a, b):
    a_name=unicode(a.name)+unicode(a.version)+unicode(a.revision)
    b_name=unicode(b.name)+unicode(b.version)+unicode(b.revision)
    return cmp(a_name,b_name)>-1

class Menu(ContextMenuAction):
    def createMenuItem(self,menu,lElement,lPresentation=[], diagram=None, position=None):

        self.diagram = diagram
        self.elements = lElement
        self.position = position
        self.menu=menu
        if lElement:
            self.element=lElement[0]
        else:
            self.element=None
            
        self.presentation=lPresentation

        if self.element and (type(self.element) != coral.kernel.ProjectPtr):

            if self.element.__parent__():
                self.container=self.element.__parent__()
                if self.container.oclIsKindOf(coral.lang.CORE01.AnyAbstractElement):
                    
                    query_slot=self.container.__getSlotByOppositeName__(CQUERY.Query,"container")
                    if query_slot:
                        self.query=query_slot[0]
                        queryMenu=qt.QPopupMenu(menu,"CQuery")
                        menu.insertItem("Populate Query",self.createQueryElements)
                    

            if self.element.oclIsKindOf(CQUERY.Query):
                self.language_list=self.getAllLanguages()
                self.all_diagram_creators=self.getAllDiagramTypes()
                for lang in self.language_list[:]:
                    l=coral.Language.__getLanguage__(str(lang.name),lang.version,lang.revision)
                    if not l.getRoot().isSubclass(coral.AnyAbstractElement):
                        self.language_list.remove(lang)
                languageMenu=qt.QPopupMenu(menu,"CQuery")
                menu.insertItem("Select language/diagram",languageMenu)

                id=0                
                for lang in self.language_list:
                    #languageMenu.insertItem(lang_name, ContainerElement(self.element,lang_name))
                    lang_name=unicode(lang.name)+unicode(lang.version)+unicode(lang.revision)

                    languageHasDiagram = False
                    for dcreator in self.all_diagram_creators:
                        if str(dcreator.path).__contains__(lang_name):
                            languageHasDiagram = True
                    if languageHasDiagram:
                        dgrMenu = qt.QPopupMenu(menu,"dgr")
                        languageMenu.insertItem(lang_name, dgrMenu,0,id)

                        #id2 is offset with the length of language_list so that it won't clash with the value of id,
                        #used when creating containers without diagrams
                        id2 = len(self.language_list)
                        for dcreator in self.all_diagram_creators:
                            if str(dcreator.path).__contains__(lang_name):
                                dgrType = str(dcreator.path).split(".")[-1]
                                dgrMenu.insertItem(dgrType, self.createContainerAndDiagram,0,id2)
                            id2+=1
                        dgrMenu.insertSeparator()
                        dgrMenu.insertItem("<no diagram>", self.createContainerElement,0,id)
                    else:
                        languageMenu.insertItem(lang_name, self.createContainerElement,0,id)
                    id+=1

    def createQueryElements(self):
        TM.beginModifyCmd()
        try:
            id=0
            
            for elem in self.elements:
                for part in elem.__getAllParts__():
                    name=unicode(hex(id))

                    if hasattr(part,"name"):
                        name=unicode(part.name)
                    else:
                        id+=1

                    CQUERY.QueryElement(query=self.query,abstractElement=part,name=name)

        finally:
            TM.endModifyCmd()

    def languageSort(self, a, b):
        a_name=unicode(a.name)+unicode(a.version)+unicode(a.revision)
        b_name=unicode(b.name)+unicode(b.version)+unicode(b.revision)
        return cmp(a_name,b_name)>0

    def getAllLanguages(self):
        lang_list = [lang for lang in coral.modeler.extension.getLanguages()]
        lang_list.sort(languageSort)
        return lang_list


    def createContainerElement(self,id):
        language=self.language_list[id]
        kl=coral.Language.__getLanguage__(str(language.name),language.version,language.revision)
        TM.beginTransaction()
        try:
            self.element.container = kl.getRoot()()
        finally:
            TM.endTransaction()

    def createContainerAndDiagram(self,id2):
        #the offset is subtracted so that id2 can be used as index in the list of diagram creators.
        id2 -= len(self.language_list)
        l_name = str(self.all_diagram_creators[id2].path).split(".")[-3]
        d_type = str(self.all_diagram_creators[id2].path).split(".")[-1]
        for language in self.language_list:
            if l_name == unicode(language.name)+unicode(language.version)+unicode(language.revision):
                kl=coral.Language.__getLanguage__(str(language.name),language.version,language.revision)
                TM.beginTransaction()
                try:
                    self.element.container = kl.getRoot()()
                finally:
                    TM.endTransaction()


                if not self.element:
                    return
                st = self.element.__getRootsProject__()
                assert st
                managedModel=self.element
                while managedModel and not managedModel.oclIsKindOf(coral.lang.Manage10.ManagedModel):
                    managedModel=managedModel.__parent__()

                if not managedModel:
                    parent=st
                else:
                    parent=managedModel
                parent = self.element    
                TM.beginTransaction()
                try:
                    self.element.container = kl.getRoot()()
                    diagram = diagrams.createDiagram(parent, typeinfo=d_type, owner_elem = self.element.container)
                finally:
                    TM.endTransaction()

    def getAllDiagramTypes(self):
        return coral.modeler.extension.config.__getAllParts__().select(lambda p: p.oclIsKindOf(coral.lang.CoralEx10.Addins.DiagramCreator))
