# File redraw.tcl
#
# Prozeduren zum Neuzeichnen der Chart

#Prozedur zum Neuzeichnen der Chart
# Parameter bestimmt die Art des Neuzeichnens
# - all:  komplett neu
# - passive: Zeichne nur passive Kanten
# - active: Zeichne nur aktive Kanten
# - start #: Zeichne Teilbaum aller Kanten, die in #id starten
# 

proc redraw_chart { name how args } {

    global chart edge token map draw
    
    my_trace "Entering redraw_chart"

    # auf jeden Fall wieder ganzen Graph zeigen
    set chart(result) 0
    
    # delete the whole chart
    .chart$name.canvas.draw delete edge
    .chart$name.canvas.draw delete text
    .chart$name.canvas.draw delete token
    .chart$name.canvas.draw delete parent

    if { [string compare $how "allrules"] == 0} {
        show_in_window "Erasing rule" $name
        .chart$name.canvas.draw delete rule
        set chart($name,ruleheight) -1
    }

    # erase all drawn flags
    erase_drawn_flags $name

    # draw all of the tokens
    for { set i 0 } { $i <= $chart($name,max_token) } { incr i } {
	draw_token $name $i
    }

    my_trace "switch $how"

    switch -exact -- $how {
	
	all { 
	    set chart($name,which_edges) "all"
	    set chart($name,which_token) "all"
            set chart($name,which_extension) "both"
            for { set i 0 } { $i <= $chart($name,drawn_edges) } { incr i } {
                set id $draw($name,$i)
                set edge($name,$id,drawn) 1
                
            }
	    if { [string compare $chart($name,drawingstyle) "timebased"] == 0 } {
		redraw_only_edges $name
	    } else {
		redraw_compact $name
	    }
	}

        allrules { 
            set chart($name,which_edges) "all"
            set chart($name,which_token) "all"
            set chart($name,which_extension) "both"
            for { set i 0 } { $i <= $chart($name,drawn_edges) } { incr i } {
                set id $draw($name,$i)
                set edge($name,$id,drawn) 1
            }
	    if { [string compare $chart($name,drawingstyle) "timebased"] == 0 } {
		redraw_only_edges $name fuck
	    } else {
		redraw_compact $name fuck
	    }
        }

	allactive { 
	    set chart($name,which_edges) "active"
	    set chart($name,which_token) "all"
            set chart($name,which_extension) "both"
            for { set i 0 } { $i <= $chart($name,drawn_edges) } { incr i } {
                set id $draw($name,$i)
                if { $edge($name,$id,status) == 1 } {
                    set edge($name,$id,drawn) 1
                }
            }
            if { [string compare $chart($name,drawingstyle) "timebased"] == 0 } {
		redraw_only_edges $name
	    } else {
		redraw_compact $name
	    }
	}
        
	allpassive { 
	    set chart($name,which_edges) "passive"
	    set chart($name,which_token) "all"
            set chart($name,which_extension) "both"
            for { set i 0 } { $i <= $chart($name,drawn_edges) } { incr i } {
                set id $draw($name,$i)
                if { $edge($name,$id,status) == 0 } {
                    set edge($name,$id,drawn) 1
                }
            }
	    if { [string compare $chart($name,drawingstyle) "timebased"] == 0 } {
		redraw_only_edges $name
	    } else {
		redraw_compact $name
	    }
	}
        
	allleft { 
	    set chart($name,which_edges) "all"
	    set chart($name,which_token) "active"
            set chart($name,which_extension) "left"
            for { set i 0 } { $i <= $chart($name,drawn_edges) } { incr i } {
                set id $draw($name,$i)
                if { $edge($name,$id,extension) == 0 && $edge($name,$id,status) == 1 } {
                    set edge($name,$id,drawn) 1
                }
            }
	    if { [string compare $chart($name,drawingstyle) "timebased"] == 0 } {
		redraw_only_edges $name
	    } else {
		redraw_compact $name
	    }
	}
        
	allright { 
	    set chart($name,which_edges) "all"
	    set chart($name,which_token) "active"
            set chart($name,which_extension) "right"
            for { set i 0 } { $i <= $chart($name,drawn_edges) } { incr i } {
                set id $draw($name,$i)
                if { $edge($name,$id,extension) == 1 && $edge($name,$id,status) == 1 } {
                    set edge($name,$id,drawn) 1
                }
            }
	    if { [string compare $chart($name,drawingstyle) "timebased"] == 0 } {
		redraw_only_edges $name
	    } else {
		redraw_compact $name
	    }
	}
        
        startactive {
            
            set chart($name,which_token) "starting from Token [lindex $args 0]"
            set chart($name,which_edges) "active"
            set chart($name,which_extension) "both"
            set start [lindex $args 0]
            for { set i 0 } { $i <= $chart($name,drawn_edges) } { incr i } {
                set id $draw($name,$i)
                if { $edge($name,$id,start) == $start} {
                    if { $edge($name,$id,status) == 1 } {
                        set edge($name,$id,drawn) 1
                    }
                }
            }
	    if { [string compare $chart($name,drawingstyle) "timebased"] == 0 } {
		redraw_only_edges $name
	    } else {
		redraw_compact $name
	    }
        }
        
        startpassive {
            set chart($name,which_token) "starting from Token [lindex $args 0]"
            set chart($name,which_edges) "passive"
            set chart($name,which_extension) "both"
            set start [lindex $args 0]
            for { set i 0 } { $i <= $chart($name,drawn_edges) } { incr i } {
                set id $draw($name,$i)
                if { $edge($name,$id,start) == $start} {
                    if { $edge($name,$id,status) == 0 } {
                        set edge($name,$id,drawn) 1
                    }
                }
            }
	    if { [string compare $chart($name,drawingstyle) "timebased"] == 0 } {
		redraw_only_edges $name
	    } else {
		redraw_compact $name
	    }
        }
        
        startleft {
            
            set chart($name,which_token) "starting from Token [lindex $args 0]"
            set chart($name,which_edges) "active"
            set chart($name,which_extension) "left"
            set start [lindex $args 0]
            for { set i 0 } { $i <= $chart($name,drawn_edges) } { incr i } {
                set id $draw($name,$i)
                if { $edge($name,$id,start) == $start} {
                    if { $edge($name,$id,extension) == 0 && $edge($name,$id,status) == 1 } {
                        set edge($name,$id,drawn) 1
                    }
                }
            }
	    if { [string compare $chart($name,drawingstyle) "timebased"] == 0 } {
		redraw_only_edges $name
	    } else {
		redraw_compact $name
	    }
        }
        
        startright {
            set chart($name,which_token) "starting from Token [lindex $args 0]"
            set chart($name,which_edges) "active"
            set chart($name,which_extension) "right"
            set start [lindex $args 0]
            for { set i 0 } { $i <= $chart($name,drawn_edges) } { incr i } {
                set id $draw($name,$i)
                if { $edge($name,$id,start) == $start} {
                    if { $edge($name,$id,extension) == 1 && $edge($name,$id,status) == 1 } {
                        set edge($name,$id,drawn) 1
                    }
                }
            }
	    if { [string compare $chart($name,drawingstyle) "timebased"] == 0 } {
		redraw_only_edges $name
	    } else {
		redraw_compact $name
	    }
        }
        
        endactive {
            
            set chart($name,which_token) "ending in Token [lindex $args 0]"
            set chart($name,which_edges) "active"
            set chart($name,which_extension) "both"
            set start [lindex $args 0]
            for { set i 0 } { $i <= $chart($name,drawn_edges) } { incr i } {
                set id $draw($name,$i)
                if { $edge($name,$id,end) == $start} {
                    if { $edge($name,$id,status) == 1 } {
                        set edge($name,$id,drawn) 1
                    }
                }
            }
	    if { [string compare $chart($name,drawingstyle) "timebased"] == 0 } {
		redraw_only_edges $name
	    } else {
		redraw_compact $name
	    }
        }

        endpassive {
            set chart($name,which_token) "ending in Token [lindex $args 0]"
            set chart($name,which_edges) "passive"
            set chart($name,which_extension) "both"
            set start [lindex $args 0]
            for { set i 0 } { $i <= $chart($name,drawn_edges) } { incr i } {
                set id $draw($name,$i)
                if { $edge($name,$id,end) == $start} {
                    if { $edge($name,$id,status) == 0 } {
                        set edge($name,$id,drawn) 1
                    }
                }
            }
	    if { [string compare $chart($name,drawingstyle) "timebased"] == 0 } {
		redraw_only_edges $name
	    } else {
		redraw_compact $name
	    }
        }

        endleft {
         
            set chart($name,which_token) "ending in Token [lindex $args 0]"
            set chart($name,which_edges) "active"
            set chart($name,which_extension) "left"
            set start [lindex $args 0]
            for { set i 0 } { $i <= $chart($name,drawn_edges) } { incr i } {
                set id $draw($name,$i)
                if { $edge($name,$id,end) == $start} {
                    if { $edge($name,$id,extension) == 0 && $edge($name,$id,status) == 1 } {
                        set edge($name,$id,drawn) 1
                    }
                }
            }
	    if { [string compare $chart($name,drawingstyle) "timebased"] == 0 } {
		redraw_only_edges $name
	    } else {
		redraw_compact $name
	    }
        }

        endright {
            set chart($name,which_token) "ending in Token [lindex $args 0]"
            set chart($name,which_edges) "active"
            set chart($name,which_extension) "right"
            set start [lindex $args 0]
            for { set i 0 } { $i <= $chart($name,drawn_edges) } { incr i } {
                set id $draw($name,$i)
                if { $edge($name,$id,end) == $start} {
                    if { $edge($name,$id,extension) == 1 && $edge($name,$id,status) == 1 } {
                        set edge($name,$id,drawn) 1
                    }
                }
            }
	    if { [string compare $chart($name,drawingstyle) "timebased"] == 0 } {
		redraw_only_edges $name
	    } else {
		redraw_compact $name
	    }
        }
        
        start {
            set chart($name,which_token) "starting from Token [lindex $args 0]"
            set chart($name,which_edges) "all"
            set chart($name,which_extension) "both"
            set start [lindex $args 0]
            for { set i 0 } { $i <= $chart($name,drawn_edges) } { incr i } {
                set id $draw($name,$i)
                if { $edge($name,$id,start) == $start} {
                    set edge($name,$id,drawn) 1
                }
            }
	    if { [string compare $chart($name,drawingstyle) "timebased"] == 0 } {
		redraw_only_edges $name
	    } else {
		redraw_compact $name
	    }
        }

        end {
            set chart($name,which_token) "ending in Token [lindex $args 0]"
            set chart($name,which_edges) "all"
            set chart($name,which_extension) "both"
            set start [lindex $args 0]
            for { set i 0 } { $i <= $chart($name,drawn_edges) } { incr i } {
                set id $draw($name,$i)
                if { $edge($name,$id,end) == $start} {
                    set edge($name,$id,drawn) 1
                }
            }
	    if { [string compare $chart($name,drawingstyle) "timebased"] == 0 } {
		redraw_only_edges $name
	    } else {
		redraw_compact $name
	    }
        }
    }
}


proc redraw_children { name id } {
    
    global chart token edge draw
    
    my_trace "Entering redraw_children"

    # beachte wieder den ganzen Graphen
    set chart(result) 0

    .chart$name.canvas.draw delete token
    .chart$name.canvas.draw delete edge
    .chart$name.canvas.draw delete text
    .chart$name.canvas.draw delete parent
    
    # draw all of the tokens
    for { set i 0 } { $i <= $chart($name,max_token) } { incr i } {
	draw_token $name $i
    }
    
    # Loesche alle drawn flags
    erase_drawn_flags $name

    #setze queue auf startkante

    set queue $id

    # solange queue nicht leer

    while { [llength $queue] != 0 } {


        my_trace "Queue is now: $queue"
        # nimm erstes Element von queue
        set this_id [lindex $queue 0]
        set queue [lrange $queue 1 end]


        # wenn ID == -1, dann nicht zeichnen
        if { $this_id != -1 } {

            # wenn Kante schon als gezeichnet markiert, dann Kinder schon auf queue

            if { $edge($name,$this_id,drawn) != 1 } {
                # markiere Element als zu zeichnend
                set edge($name,$this_id,drawn) 1
                
                # expandiere Kinder auf queue, aber nur wenn Kinder da sind
                if { $edge($name,$this_id,children) != -1 } {
                    set queue [concat $queue $edge($name,$this_id,children)]
                }
            }

        }
    }
    if { [string compare $chart($name,drawingstyle) "timebased"] == 0 } {
        redraw_only_edges $name
    } else {
        redraw_compact $name
    }
}

proc redraw_parents { name id } {
    
    global chart token edge draw
    
    my_trace "Entering redraw_parents"

    # beachte wieder den ganzen Graphen
    set chart(result) 0
    
    .chart$name.canvas.draw delete token
    .chart$name.canvas.draw delete edge
    .chart$name.canvas.draw delete text
    .chart$name.canvas.draw delete parent

    
    # draw all of the tokens
    for { set i 0 } { $i <= $chart($name,max_token) } { incr i } {
	draw_token $name $i
    }
    
    # Loesche alle drawn flags
    erase_drawn_flags $name

    #setze queue auf startkante

    set queue $id

    # solange queue nicht leer

    while { [llength $queue] != 0 } {


        my_trace "Queue is now: $queue"
        # nimm erstes Element von queue
        set this_id [lindex $queue 0]
        set queue [lrange $queue 1 end]


        # wenn es die Kante gibt...
        if { [info exists edge($name,$this_id,label)] == 1 } {

            # wenn Kante schon als gezeichnet markiert, dann Eltern schon auf queue

            if { $edge($name,$this_id,drawn) != 1 } {
                # markiere Element als zu zeichnend
                set edge($name,$this_id,drawn) 1
                
                # expandiere Eltern auf queue, aber nur wenn Eltern da sind
                if { [info exists edge($name,$this_id,parents)] == 1 } {
                    set queue [concat $queue $edge($name,$this_id,parents)]
                }
            }

        }
    }
    if { [string compare $chart($name,drawingstyle) "timebased"] == 0 } {
        redraw_only_edges $name
    } else {
        redraw_compact $name
    }
}


# this procedure draws all edges marked with the drawn flag
proc redraw_only_edges { name args} {

    global chart token edge draw map

    my_trace "Entering proc redraw_only_edges $name $args"

    if { [llength $args] > 0 } {
        set chart($name,ruleheight) -1
    }

    for { set i 0 } { $i <= $chart($name,drawn_edges) } { incr i } {

	set id $draw($name,$i)
        if { $edge($name,$id,drawn) == 1 } {
            if { $edge($name,$id,start) != -1 } {
                physical_draw_edge $name $id $edge($name,$id,start) $edge($name,$id,end) $edge($name,$id,label) $edge($name,$id,status) $edge($name,$id,extension) $edge($name,$id,children)
            } else {
                if { [llength $args] > 0} {
                    draw_physical_rule $name $id
                }
            }
        }
    }
}

# this procedure rearranges the chart and draws it more compact
proc redraw_compact { name args} {

    global chart token edge draw map
    
    my_trace "Entering proc redraw_compact $name $args"

    if { [llength $args] > 0 } {
        set chart($name,ruleheight) -1
        for { set i 0 } { $i <= $chart($name,max_edges) } { incr i} {
            if { $map($name,$i,original) == 1 } {
                set id $map($name,$i,id)
                if { $edge($name,$id,start) == -1 } {
                    draw_rule $name $id
                }
            }
        }
    }
    
    # gehe alle Token durch wegen Spans
    for { set i 0 } { $i <= $chart($name,max_token) } { incr i } {
	# gehe wirklich durch alle Token
	for { set u 0 } { $u <= $chart($name,max_token) } { incr u } {
	    # gehe durch alle Kanten, die in Token starten
	    if { [info exists token($name,$u,edges_start)] == 1 } {
		set anzahl [llength $token($name,$u,edges_start)]
		for { set k 0 } { $k < $anzahl } { incr k } {
		    set edge_id [lindex $token($name,$u,edges_start) $k]
		    if { $edge($name,$edge_id,span) == $i && $edge($name,$edge_id,drawn) == 1 } {
			physical_draw_edge $name $edge_id $edge($name,$edge_id,start) $edge($name,$edge_id,end) $edge($name,$edge_id,label) $edge($name,$edge_id,status) $edge($name,$edge_id,extension) $edge($name,$edge_id,children)
		    }
		}
	    }
	}
    }
}
