#!/usr/bin/env python
import os
from coral.modeler import modeler
import coral
import time

XMIDI = coral.lang.XMIDI20
UML14 = coral.lang.UML14

m=modeler.ModelerWindow()
storage=m.openProject("2classes_with_association.xmi")
m.main(loop=0)


diagram = None
for r in storage.contents():
    if r.oclIsKindOf(XMIDI.Diagram) and r.semanticModel.typeInfo == "ClassDiagram":
        diagram = r
        break

assert diagram #this should be the diagram with the two classes

print "DIAGRAM", diagram

aclass_di = None
bclass_di = None
for e in diagram.contained:
    if e.semanticModel.element.__type__() == UML14.Class and e.semanticModel.element.name == "Class_1":
        aclass_di = e
    if e.semanticModel.element.__type__() == UML14.Class and e.semanticModel.element.name == "Class_2":
        bclass_di = e

assert aclass_di
assert bclass_di

#Check original position
assert aclass_di.position.y==100.0
assert bclass_di.position.y==100.0

print "edge start X",aclass_di.anchorage[0].graphEdge[0].waypoints[0].x
print "edge start Y",aclass_di.anchorage[0].graphEdge[0].waypoints[0].y
print "edge end X",aclass_di.anchorage[0].graphEdge[0].waypoints[-1].x
print "edge end Y",aclass_di.anchorage[0].graphEdge[0].waypoints[-1].y

print "aclass_di.anchorage[0].position.x before",aclass_di.anchorage[0].position.x
print "aclass_di.anchorage[0].position.y before",aclass_di.anchorage[0].position.y

#Check original association position
assert aclass_di.anchorage[0].position.x==100.0
assert aclass_di.anchorage[0].position.y==35.0
#Check other end of association
assert bclass_di.anchorage[0].position.x==0.0
assert bclass_di.anchorage[0].position.y==35.0

m.getDiagramEditorManager().editorSet.notifyFocusOn(diagram)

m.processEvents()

#time.sleep(1)

coral.getTransactionManager().beginModifyCmd()
try:
    aclass_di.position.y=200
finally:
    coral.getTransactionManager().endModifyCmd()

#Check new class position
print aclass_di.position.y," is y position of aclass"
assert aclass_di.position.x==80.0
assert aclass_di.position.y==200.0

#Check new association end position at first class
assert aclass_di.anchorage[0].position.x==99.0#one smaller than the class height???
assert aclass_di.anchorage[0].position.y==0.0

#Check new association end position at second class
assert bclass_di.anchorage[0].position.x==0.0
assert bclass_di.anchorage[0].position.y==74.0#one smaller than the class height???

m.processEvents()
#time.sleep(1)

#Swap positions of the both classes
coral.getTransactionManager().beginModifyCmd()
try:
    aclass_di.position.x=280.0
    aclass_di.position.y=100.0
finally:
    coral.getTransactionManager().endModifyCmd()
#    m.processEvents()
coral.getTransactionManager().beginModifyCmd()
try:
    bclass_di.position.x=80.0
    bclass_di.position.y=200.0
finally:
    coral.getTransactionManager().endModifyCmd()

m.processEvents()

#Check if the assoc. is swapped too.
assert aclass_di.anchorage[0].position.x==0.0
assert aclass_di.anchorage[0].position.y==74.0

assert bclass_di.anchorage[0].position.x==99.0
assert bclass_di.anchorage[0].position.y==0.0

m.processEvents()
#time.sleep(1)

coral.getTransactionManager().beginModifyCmd()
try:
    bclass_di.position.x=480.0
    bclass_di.position.y=200.0
finally:
    coral.getTransactionManager().endModifyCmd()

m.processEvents()
#time.sleep(1)

print "aclass anc[0] x ", aclass_di.anchorage[0].position.x
print "aclass anc[0] y ", aclass_di.anchorage[0].position.y
print "bclass anc[0] x ", bclass_di.anchorage[0].position.x
print "bclass anc[0] y ", bclass_di.anchorage[0].position.y
print "edge start X",aclass_di.anchorage[0].graphEdge[0].waypoints[0].x
print "edge start Y",aclass_di.anchorage[0].graphEdge[0].waypoints[0].y
print "edge end X",aclass_di.anchorage[0].graphEdge[0].waypoints[-1].x
print "edge end Y",aclass_di.anchorage[0].graphEdge[0].waypoints[-1].y

assert aclass_di.anchorage[0].position.x==99.0
assert aclass_di.anchorage[0].position.y==74.0

assert bclass_di.anchorage[0].position.x==0.0
assert bclass_di.anchorage[0].position.y==0.0

m.processEvents()
#time.sleep(1)

#Move both class equidistantly
coral.getTransactionManager().beginModifyCmd()
try:
    aclass_di.position.x+=100.0
    aclass_di.position.y+=100.0
    bclass_di.position.x+=100.0
    bclass_di.position.y+=100.0
finally:
    coral.getTransactionManager().endModifyCmd()

#Test that the association is still at the same relative position to the classes
assert aclass_di.anchorage[0].position.x==99.0
assert aclass_di.anchorage[0].position.y==74.0

assert bclass_di.anchorage[0].position.x==0.0
assert bclass_di.anchorage[0].position.y==0.0

m.processEvents()

print "aclass_di.position.x ",aclass_di.position.x
print "aclass_di.position.y ",aclass_di.position.y

print "bclass_di.position.x ",bclass_di.position.x
print "bclass_di.position.y ",bclass_di.position.y

#Test if the grapEdges waypoints are the same as the di.positions
print "X waypoint:",aclass_di.anchorage[0].graphEdge[0].waypoints[0].x," di.pos:", (aclass_di.anchorage[0].position.x+aclass_di.position.x)
print "Y waypoint:",aclass_di.anchorage[0].graphEdge[0].waypoints[0].y," di.pos:", (aclass_di.anchorage[0].position.y+aclass_di.position.y)
assert aclass_di.anchorage[0].graphEdge[0].waypoints[0].x == aclass_di.anchorage[0].position.x+aclass_di.position.x
assert aclass_di.anchorage[0].graphEdge[0].waypoints[0].y == aclass_di.anchorage[0].position.y+aclass_di.position.y

print "X waypoint:", bclass_di.anchorage[0].graphEdge[0].waypoints[-1].x," di.pos", bclass_di.position.x
print "Y waypoint:", bclass_di.anchorage[0].graphEdge[0].waypoints[-1].y," di.pos", bclass_di.position.y
assert bclass_di.anchorage[0].graphEdge[0].waypoints[-1].x == bclass_di.position.x
assert bclass_di.anchorage[0].graphEdge[0].waypoints[-1].y == bclass_di.position.y


edge=aclass_di.anchorage[0].graphEdge[0]

coral.getTransactionManager().beginModifyCmd()
try:
    aclass_di.position.y = 100
    bclass_di.position.y = 150
finally:
    coral.getTransactionManager().endModifyCmd()

assert edge.waypoints[-1].y == edge.waypoints[0].y
assert max(aclass_di.position.y,bclass_di.position.y) <= edge.waypoints[0].y <= min(aclass_di.position.y+aclass_di.size.height,bclass_di.position.y+bclass_di.size.height)

coral.getTransactionManager().beginModifyCmd()
try:
    aclass_di.size.height = 300
    bclass_di.position.y = 150
finally:
    coral.getTransactionManager().endModifyCmd()

# Resizing should layout the edges
assert edge.waypoints[-1].y == edge.waypoints[0].y
assert max(aclass_di.position.y,bclass_di.position.y) <= edge.waypoints[0].y <= min(aclass_di.position.y+aclass_di.size.height,bclass_di.position.y+bclass_di.size.height)

time.sleep(2)
