# This file is part of the Coral project.
# Please read the copyright notice in the LICENSE file.

from coral import log
logger=log.getLogger("petester")

from coral.modeler.window import *
import sys
from coral import kernel as coral
import os
from coral.modeler.property.propertyeditor import *
from coral import ModelCopy_One
from coral.modeler.coralmodeler import CoralModeler
class PEtester(CoralMainWindow):
    def __init__(self,language):
        CoralMainWindow.__init__(self)
                        
        self.language = language
        self.processEvents()
        self.move(100,100)
        self.resize(700,500)
                
    def test(self,PEClass,show=0):
        assert(issubclass(PEClass,PropertyEditor))
        logger.debug("Testing "+unicode(PEClass.__name__))
        self.pemanager=PropertyEditorManager(self,subEditors=[PEClass])

        self.pemanager.resize(700,500)
        self.pemanager.show()
        self.processEvents()

        self.pemanager.focusOn(None)
        self.processEvents()
        
        supportedElements=[]
        allElements=[]

        kl=coral.Language.__getLanguage__(self.language[0],self.language[1],self.language[2])
        
        assert(kl)
        
        self.model=kl.getRoot()()

        for pe in self.pemanager.subEditors:
            self.pe=pe

        s=coral.Project()
        
        for c in kl.__elements__():
            if not c.isDatatypeDefinition():
                e=c()
                e.__setProject__(s)
                allElements.append(e)
                if self.pe.canEdit(e):
                    supportedElements.append(e)
                    

        if not supportedElements:
            logger.error("PropertEditor "+unicode(PEClass)+" cannot edit anything!")
            assert(0)

        for c in supportedElements:
            self.pemanager.focusOn(c)
                

        self.setCentralWidget(self.pemanager)


        if show:
            CoralModeler.getInstance().getQtApp().setMainWidget(self)
            self.main(loop=1)
        else:
            self.main(loop=0)

        if issubclass(PEClass,CompositePropertyEditor):
            # Check that all mandatory methods exist
            assert pe.getAssociationName()
            assert pe.getName()
            assert pe.getSubEditors()
            
            firstSub=self.pe.getSubEditors()[0](None)
            for e in supportedElements:
                self.pe.focusOn(e)
            for a in allElements:
                if firstSub.canEdit(a) and self.pe.filterAssociation(a):
                    toAdd1=ModelCopy_One(a)
                    toAdd1.__setProject__(s)
                    toAdd2=ModelCopy_One(a)
                    toAdd2.__setProject__(s)
                    toAdd3=ModelCopy_One(a)
                    toAdd3.__setProject__(s)
            
            self.processEvents()
            self.pe.add(toAdd1)
            self.pe.add(toAdd2)
            # Check that the elements have actually been added
            assert len(getattr(e,self.pe.getAssociationName()))==2
            self.pe.deleteSelection([0,1])
            self.processEvents()

            # check that elements are deleted:
            assert(not eval("e.%s"%self.pe.getAssociationName()))


            # checking that moving elements in compositePE works
            # Check only for ordered associations
            if getattr(e,self.pe.getAssociationName()).getProperty().isOrdered():
                
                self.processEvents()
                self.pe.add(toAdd1)
                self.pe.add(toAdd2)
                self.pe.add(toAdd3)
                propertyBeforeSwaps=[a for a in getattr(e,self.pe.getAssociationName())]

                a=self.pe.list[2]
                g=self.pe.itable.item(2, 1)
                self.pe.moveUp()
                b=self.pe.list[1]
                h=self.pe.itable.item(1, 1)

                propertyBetweenSwaps=[a for a in getattr(e,self.pe.getAssociationName())]

                self.pe.moveDown()
                self.pe.apply()
                i=self.pe.list[2]
                k=self.pe.itable.item(2, 1)

                propertyAfterSwaps=[a for a in getattr(e,self.pe.getAssociationName())]
                # asserting that elements have been swapped both in the list and in the model:
                assert (not propertyBeforeSwaps==propertyBetweenSwaps)
                assert (propertyBeforeSwaps==propertyAfterSwaps)
                assert(a==b and g==h)
                assert(b==i and h==k)

                # checking that it is not possible to move elements out of list range

                # start by removing old elements
                self.pe.deleteSelection([0,2])
                self.processEvents()
                
                self.pe.add(toAdd1)
                self.pe.add(toAdd2)

                self.pe.moveUp()
                self.pe.moveUp()
                self.pe.moveUp()
                self.pe.moveDown()
                self.pe.moveDown()
                self.pe.moveDown()
                self.pe.moveDown()
                self.pe.apply()
                self.processEvents()


                # asserting that if no element is selected nothing happens
                # when trying to move elements

                # start by removing old elements
                self.pe.deleteSelection([0,1])
                self.processEvents()
                
                self.pe.add(toAdd1)
                self.pe.add(toAdd2)
                self.pe.add(toAdd3)
                a=self.pe.list
                self.pe.itable.currentItem=None
                self.pe.moveDown()
                self.pe.moveDown()
                self.pe.moveUp()
                self.pe.apply()
                b=self.pe.list
                self.processEvents()

                assert(a==b)

                # checking that you can't move more than one element
                # start by removing old elements
                self.pe.deleteSelection([0,2])
                self.processEvents()
                
                self.pe.add(toAdd1)
                self.pe.add(toAdd2)
                self.pe.add(toAdd3)
                a=self.pe.list

                self.pe.itable.setCurrentCell(0,0)
                cellSelect=QTableSelection()
                cellSelect.init(0,0)
                cellSelect.expandTo(0,0)
                self.pe.itable.addSelection(cellSelect)
                self.pe.itable.setCurrentCell(1,0)
                cellSelect2=QTableSelection()
                cellSelect2.init(1,0)
                cellSelect2.expandTo(1,0)
                self.pe.itable.addSelection(cellSelect2)

                self.pe.moveDown()
                self.pe.moveDown()
                self.pe.moveUp()
                self.pe.apply()
                b=self.pe.list

                self.processEvents()

                assert(a==b)


    
