#
#   This script generates an interaction diagram from an
#   object diagram.
#   The object diagram has to be active
#

# Some Globals
set msgIncr 50


#
#   this is the callback procedure for the sort command
#   this procedure will compare the sequence id of the messages
#
proc sort_by_message_id {a b} {
	set as [$a get sequence]
	set bs [$b get sequence]
	set d  [expr $as - $bs]
	return  $d
}

#
# this routine creates a mapping between a obejct in the
# object diagram and an object in the interaction diagram
# (note this can probably be coded using associative arrays
# as well
proc map_object {object objl mapol dia objLength} {
  upvar $objl objectl
  upvar $mapol mapobjectl
  set x  [lsearch  $objectl $object]
  if { $x == -1} {
	  # create a new object
	  set no [$dia add object  interactionObject]
	  lappend objectl $object
	  lappend mapobjectl $no
          set x [ expr [llength $objectl]  * 110]
          # set bounding box of object
          $no set bbx [ expr $x - 50 ] 50 [ expr $x + 50 ] [ expr $objLength + 70 ]
          $no set name [$object get name]
	  $no set  className [$object get className]
	  return $no
  }
  return [lindex $mapobjectl $x]
}


#
# main entry point for this script
#

global msgIncr

# get the active diagram
set d [OD_getActiveDiagram]

# check if it is an object diagram
if {[$d get type] == "object" } {
	# prompt for a diagram name
	set dianame [OD_getInput "diagram name" "diagram name"]
	if [string length $dianame] {
		# create the interaction diagram
		set id [OD_createDiagram interaction $dianame]
		# create a list with all the messages
		set ol [$d get objects]
		list ml
                foreach o $ol {
                        if {[$o get objectType] == "message"} {
                                if {[$o get sequence] == ""} { } else {
                                        lappend ml $o
                                }
			}
                }

                # sort the list
		set ml [lsort -command sort_by_message_id  $ml]
		# now loop trough all the messages and add to the interaction
		# diagram
		set ol [list]
		set mol [list]
		set y 100
                set objLength [ expr  $msgIncr * [llength $ml] ]
		foreach o $ml {
			# get the two objects of the message
			set f [[$o get relation] get from]
			set t [[$o get relation] get to]
			# find or create the corresponding objects in the interaction diagram
                        set nf [map_object $f ol mol $id $objLength]
                        set nt [map_object $t ol mol $id $objLength]
			# create an interaction event
			set ie [$id add object interactionEvent  $nf $nt]
			# copy the event data : object name
			$ie set name "[$o get operation] \( [$o get arguments] \)"
			$ie set origin 0 $y
			incr y $msgIncr
		}
	}

} else {
	 OD_giveMessage "Error" "Current diagram is not an obejct diagram" hand
}