#!/usr/bin/env python
import coral
from coral import modeler
from coral.modeler.modeler import *
from coral.modeler.diagram import xmidi_diagrams
from coral.modeler.diagram.degen import searchForSimpleGraphNode

m=ModelerWindow()
m.main(loop=0)

L = coral.lang.UML14
DI = coral.lang.XMIDI20

tm = coral.getTransactionManager()

tm.beginModifyCmd()
try:
    prj=coral.Project()
    
    sm=L.StateMachine()
    sm.__setProject__(prj)
    topstate = L.CompositeState()
    sm.top = topstate
    
    ## Create a StateDiagram from the model
    cd = xmidi_diagrams.createDiagram(prj,owner_elem=sm,typeinfo="StateDiagram")
    assert cd
    
finally:
    tm.endModifyCmd()

m.getDiagramEditorManager().editorSet.notifyFocusOn(cd)
m.processEvents()

assert len(topstate.subvertex) == 0
assert len(cd.contained) == 0

## Create a composite state
cs1 = L.CompositeState(name="CS1")

tm.beginModifyCmd()
try:
    topstate.subvertex.insert(cs1)
finally:
    tm.endModifyCmd()

assert len(topstate.subvertex) == 1
assert len(cd.contained) == 1

x_cs1 = cs1.xmidi_get_graphelements()[0]

assert x_cs1

## Create a concurrent state with two regions
cs2 = L.CompositeState(name="CS2", isConcurrent=True)
r1 = L.CompositeState(name="R1", container=cs2)
r2 = L.CompositeState(name="R2", container=cs2)

tm.beginModifyCmd()
try:
    topstate.subvertex.insert(cs2)
finally:
    tm.endModifyCmd()

assert len(topstate.subvertex) == 2
assert len(cd.contained) == 2

x_cs2 = cs2.xmidi_get_graphelements()[0]
x_r1 = r1.xmidi_get_graphelements()[0]
x_r2 = r2.xmidi_get_graphelements()[0]

tm.beginModifyCmd()
try:
    ## For the curious unittest follower
    x_cs2.position.x = 300
finally:
    tm.endModifyCmd()

assert x_cs2
assert x_r1
assert x_r2

## Make sure there are no compartments in the regions
assert len(x_r1.contained) == 0 
assert len(x_r2.contained) == 0 


m.processEvents()

## Create 4 states 

ss1 = L.SimpleState(name="SS1")
ss2 = L.CompositeState(name="SS2")
ss3 = L.CompositeState(name="SS3")
ss4 = L.SimpleState(name="SS4")

assert ss1
assert ss2
assert ss3
assert ss4


## Insert the states to the two states in the diagram
tm.beginModifyCmd()
try:
    cs1.subvertex.insert(ss1)
    cs1.subvertex.insert(ss2)
    r1.subvertex.insert(ss3)
    r2.subvertex.insert(ss4)
finally:
    tm.endModifyCmd()

## Check that graphnodes were created for the states
x_ss1 = ss1.xmidi_get_graphelements()[0]
x_ss2 = ss2.xmidi_get_graphelements()[0]
x_ss3 = ss3.xmidi_get_graphelements()[0]
x_ss4 = ss4.xmidi_get_graphelements()[0]

assert x_ss1
assert x_ss2
assert x_ss3
assert x_ss4

## Look for SubStateCompartment in composite state
cnt, idx =  searchForSimpleGraphNode(x_cs1.contained, "SubStateCompartment")
assert cnt

## Check that the states added to cs1 went to the right place
assert len(cnt.contained) == 2
assert x_ss1 in cnt.contained
assert x_ss1 in cnt.contained

## Check that the states in the regions went to the
## element-graphnode directly
assert len(x_r1.contained) == 1
assert len(x_r2.contained) == 1
assert x_ss3 in x_r1.contained
assert x_ss4 in x_r2.contained

## Kill 'ss1', check it disappears
tm.beginModifyCmd()
try:
    ss1.__resetAttrs__()
finally:
    tm.endModifyCmd()

assert len(cnt.contained) == 1

## Kill 'ss2', check it disappears
tm.beginModifyCmd()
try:
    ss2.__resetAttrs__()
finally:
    tm.endModifyCmd()

assert len(cnt.contained) == 0


## Kill 'ss3' and 'ss4', check they disappear
tm.beginModifyCmd()
try:
    ss3.__resetAttrs__()
    ss4.__resetAttrs__()
finally:
    tm.endModifyCmd()

assert len(x_r1.contained) == 0
assert len(x_r2.contained) == 0


## Finally, kill all elements in the diagram
tm.beginModifyCmd()
try:
    cs1.__resetAttrs__()
    cs2.__resetAttrs__()
finally:
    tm.endModifyCmd()

assert len(topstate.subvertex) == 0
assert len(cd.contained) == 0
