#! /usr/local/bin/wish -f

# $B4D6-$N@_Dj(B
set ifont "*-new century schoolbook-medium-i-normal--18-*"
set lbfont "*-times-bold-r-*-17-*"
set bfont "*-times-bold-r-*-14-*"
set fg_color black
set bg_color bisque3
set select_color goldenrod
set menu_color cornflowerblue
set obj_color antiquewhite2
set enter_color antiquewhite1
set base_color(1) "#f00"
set base_color(2) coral
set base_color(3) aquamarine
set base_color(4) cornflowerblue
set base_name(1) "A"
set base_name(2) "T"
set base_name(3) "C"
set base_name(4) "G"
set save_file "./temporary.ps"
set work_file "./temporary.wrk"
set pad1 0.1c
set pad2 0.2c
set max_x 550
set max_y 550
set min_x 200
set min_y 200
set margin 10
set r1 100
set w 2.0
set bw 2
set l 30
set PI [expr 2*asin(1.0)]
set eps 1.0e-03

# $B=i4|2=(B
set num_states 0

# $B%a%$%s%&%#%s%I%&$N%$%s%9%?%s%9$r@8@.(B
frame .menu -relief raised -borderwidth $bw -bg $menu_color
menubutton .menu.file -text File -menu .menu.file.menubutton \
    -underline 0 -font $ifont -bg $menu_color -activebackground $menu_color
menu .menu.file.menubutton -bg $menu_color -activebackground $menu_color
.menu.file.menubutton add command -label "Save PS file" -underline 0 \
    -command "select save_button" -font $ifont
.menu.file.menubutton add separator
.menu.file.menubutton add command -label "Exit program" -underline 0 \
    -command "select quit_button" -font $ifont
menubutton .menu.operation -text Operation -menu .menu.operation.menubutton \
    -underline 0 -font $ifont -bg $menu_color -activebackground $menu_color
menu .menu.operation.menubutton -bg $menu_color -activebackground $menu_color
.menu.operation.menubutton add command -label "Draw" -underline 0 \
    -command "select draw_button" -font $ifont
.menu.operation.menubutton add command -label "ReDraw" -underline 0 \
    -command "select redraw_button" -font $ifont
.menu.operation.menubutton add separator
.menu.operation.menubutton add command -label "Exchange" -underline 0 \
    -command "select exchange_button" -font $ifont
.menu.operation.menubutton add separator
.menu.operation.menubutton add command -label "Clear" -underline 0 \
    -command "select clear_button" -font $ifont
frame .body

canvas .body.view_canvas -height $max_x -width $max_y -background $bg_color \
    -borderwidth [expr $bw*2] -relief groove \
    -scrollregion "0 0 $max_x $max_y" \
    -xscroll ".body.hscroll set" -yscroll ".body.vscroll set"
scrollbar .body.vscroll  -relief sunken \
    -command ".body.view_canvas yview" -activeforeground $bg_color
scrollbar .body.hscroll -orient horiz -relief sunken \
    -command ".body.view_canvas xview" -activeforeground $bg_color

# $B%a%$%s%&%#%s%I%&$N%$%s%9%?%s%9$r%l%$%"%&%H(B
pack .menu -side top -fill x
pack .menu.file -side left -padx $pad1 -pady $pad1
pack .menu.operation -side left -padx $pad1 -pady $pad1
pack .body -side top -fill both -expand yes
pack .body.vscroll -side right -fill y
pack .body.hscroll -side bottom -fill x
pack .body.view_canvas -side left -padx $pad1 -pady $pad1 -expand yes

# $B$=$NB>(B
wm title . HMMView(Main)
wm minsize . $min_x $min_y

# $B%;%C%F%#%s%0%&%#%s%I%&$N%$%s%9%?%s%9$r@8@.(B
toplevel .setting_window
frame .setting_window.keys -relief raised -borderwidth $bw
label .setting_window.keys.label -text "Keys:" -font $ifont
frame .setting_window.keys.frame1
label .setting_window.keys.frame1.filename_label -text "File name:" \
    -font $lbfont
entry .setting_window.keys.frame1.file_text -bg $bg_color \
    -font $bfont -borderwidth $bw -relief sunken \
    -selectbackground $select_color
frame .setting_window.keys.frame2
label .setting_window.keys.frame2.generation_label -text "Generation:" \
    -font $lbfont
entry .setting_window.keys.frame2.generation_text -bg $bg_color \
    -font $bfont -width 5 -borderwidth $bw -relief sunken \
    -selectbackground $select_color
entry .setting_window.keys.frame2.individual_text -bg $bg_color \
    -font $bfont -width 5 -borderwidth $bw -relief sunken \
    -selectbackground $select_color
label .setting_window.keys.frame2.individual_label -text "Individual:" \
    -font $lbfont
frame .setting_window.condition -relief raised -borderwidth $bw
label .setting_window.condition.label -text "Conditions:" -font $ifont
label .setting_window.condition.a_label \
    -text "State transition probability (%):" -font $lbfont
scale .setting_window.condition.a_scale -orient horizontal \
    -font $lbfont -activeforeground $bg_color -tickinterval 20
label .setting_window.condition.b_label \
    -text "Output symbol distribution (%):" -font $lbfont
scale .setting_window.condition.b_scale -orient horizontal \
    -font $lbfont -activeforeground $bg_color -tickinterval 20
label .setting_window.condition.pi_label \
    -text "Initial state distribution (%):" -font $lbfont
scale .setting_window.condition.pi_scale -orient horizontal \
    -font $lbfont -activeforeground $bg_color -tickinterval 20
# $B%;%C%F%#%s%0%&%#%s%I%&$N%$%s%9%?%s%9$r%l%$%"%&%H(B
pack .setting_window.keys -side top -fill x
pack .setting_window.keys.label -side top -anchor w \
    -padx $pad1 -pady $pad1
pack .setting_window.keys.frame1 -side top -fill x
pack .setting_window.keys.frame1.filename_label -side left \
    -padx $pad1 -pady $pad1
pack .setting_window.keys.frame1.file_text -fill x -padx $pad1 -pady $pad1
pack .setting_window.keys.frame2 -side top -fill x
pack .setting_window.keys.frame2.generation_label -side left \
    -padx $pad1 -pady $pad1
pack .setting_window.keys.frame2.generation_text -side left \
    -padx $pad1 -pady $pad1
pack .setting_window.keys.frame2.individual_text -side right \
    -padx $pad1 -pady $pad1
pack .setting_window.keys.frame2.individual_label -side right \
    -padx $pad1 -pady $pad1
pack .setting_window.condition -side top -fill x
pack .setting_window.condition.label -side top -anchor w \
    -padx $pad1 -pady $pad1
pack .setting_window.condition.a_label -side top -anchor w \
    -padx $pad1 -pady $pad1
pack .setting_window.condition.a_scale -side top -fill x \
    -padx $pad1 -pady $pad1
pack .setting_window.condition.b_label -side top -anchor w \
    -padx $pad1 -pady $pad1
pack .setting_window.condition.b_scale -side top -fill x \
    -padx $pad1 -pady $pad1
pack .setting_window.condition.pi_label -side top -anchor w \
    -padx $pad1 -pady $pad1
pack .setting_window.condition.pi_scale -side top -fill x \
    -padx $pad1 -pady $pad1
# $B$=$NB>(B
wm title .setting_window HMMView(Setting)

# $B%-!<%P%$%s%G%#%s%0(B
bind .body.view_canvas <2> ".body.view_canvas scan mark %x %y"
bind .body.view_canvas <B2-Motion> ".body.view_canvas scan dragto %x %y"
bind all <Control-q> "select quit_button"
bind all <Control-s> "select save_button"
bind all <Control-d> "select draw_button"
bind all <Control-r> "select redraw_button"
bind all <Control-e> "select exchange_button"
bind all <Control-c> "select clear_button"
bind all <Button-1> "focus .body.view_canvas"
bind .setting_window.keys.frame1.file_text <Return> \
    "focus .setting_window.keys.frame2.generation_text"
bind .setting_window.keys.frame1.file_text <Control-n> \
    "focus .setting_window.keys.frame2.generation_text"
bind .setting_window.keys.frame1.file_text <Control-p> \
    "focus .setting_window.keys.frame2.individual_text"
bind .setting_window.keys.frame1.file_text <Control-q> \
    "select quit_button"
bind .setting_window.keys.frame2.generation_text <Return> \
    "focus .setting_window.keys.frame2.individual_text"
bind .setting_window.keys.frame2.generation_text <Control-n> \
    "focus .setting_window.keys.frame2.individual_text"
bind .setting_window.keys.frame2.generation_text <Control-p> \
    "focus .setting_window.keys.frame1.file_text"
bind .setting_window.keys.frame2.generation_text <Control-q> \
    "select quit_button"
bind .setting_window.keys.frame2.individual_text <Return> \
    "select draw_button"
bind .setting_window.keys.frame2.individual_text <Control-n> \
    "focus .setting_window.keys.frame1.file_text"
bind .setting_window.keys.frame2.individual_text <Control-p> \
    "focus .setting_window.keys.frame2.generation_text"
bind .setting_window.keys.frame2.individual_text <Control-q> \
    "select quit_button"

# $B%a%K%e!<$,A*Br$5$l$?$i(B...
proc select button {
    global ifont bfont lbfont pad1
    global fg_color bg_color obj_color select_color enter_color
    global base_color base_name
    global save_file work_file
    global max_x max_y margin r1 w l bw
    global PI eps

    global file_name generation individual
    global num_states
    global a b pi log_likelihd num_params aic fitness
    global a_scale b_scale pi_scale
    global states dum_states states1 dum_states1
    global from to
    global status

    if { $button == "draw_button" } {

        # focus$B$r$=$i$9(B
        focus .body.view_canvas

        # $B8!:wBP>]%U%!%$%k$H8!:w%-!<$N3MF@(B
        puts stderr "You selected Draw menu..."
        regsub -all {[	 ]+} [.setting_window.keys.frame1.file_text get] \
            {} file_name
        regsub -all {[	 ]+} \
            [.setting_window.keys.frame2.generation_text get] {} generation
        regsub -all {[	 ]+} \
            [.setting_window.keys.frame2.individual_text get] {} individual
        puts stderr "File name is $file_name..."
        puts stderr "Generation is $generation..."
        puts stderr "Individual is $individual..."

        # $B8!:wBP>]%U%!%$%k$H8!:w%-!<$N%A%'%C%/(B
        if { ([regexp -nocase {^[0-9]+$} $generation] == 0) ||
             ([regexp -nocase {^[1-9][0-9]*$} $individual] == 0) } {
            error "Invalid key..."
            return
        }

        # $B8!:wBP>]%U%!%$%k$rFI$`(B
        set t_message ""
        set i_message ""
        set file_id1 [open $file_name r]
        set file_id2 [open $work_file w]
        while { [gets $file_id1 a_line] >= 0 } {

            # $B3:Ev$9$k@$Be?t$N8!:w(B
            if { [regexp {^--- generation= [0-9]+ ...$} $a_line] == 1 } {
                set fields [split $a_line]
                set dum_generation [lindex $fields 2]
                if { [string compare $generation $dum_generation] == 0 } {
                    set t_message "I got the generation."
                    puts stderr "I got the generation."
                    puts $file_id2 $a_line
                }
            }

            # $B3:Ev$9$k8DBN$N8!:w(B
            if { [string compare $t_message "I got the generation."] == 0 } {
                if { [regexp {^--- id= [1-9][0-9]* ...\(after learning\)$} \
                    $a_line] == 1 } {
                    set fields [split $a_line]
                    set dum_individual [lindex $fields 2]
                    if { [string compare $individual $dum_individual] == 0 } {
                        set i_message "I got the individual."
                        puts stderr "I got the individual."
                        puts $file_id2 $a_line

                        # $B3F%Q%i%a!<%?$NFI$_9~$_(B
                        # $B>uBV?t(B
                        gets $file_id1 a_line
                        puts $file_id2 $a_line
                        set fields [split $a_line]
                        set num_states \
                            [lindex $fields [expr [llength $fields]-1]]
                        # $B>uBVA+0\3NN((B
                        gets $file_id1 a_line
                        puts $file_id2 $a_line
                        for { set i 1 } { $i <= $num_states } { incr i } {
                            gets $file_id1 a_line
                            puts $file_id2 $a_line
                        }
                        gets $file_id1 a_line
                        puts $file_id2 $a_line
                        for { set i 1 } { $i <= $num_states } { incr i } {
                            gets $file_id1 dum1
                            puts $file_id2 $dum1
                            regsub {^	} $dum1 {} dum2
                            regsub { $} $dum2 {} a_line
                            set fields [split $a_line]
                            for { set j 1 } { $j <= $num_states } { incr j } {
                                set a($i,$j) [lindex $fields [expr $j-1]]
                            }
                        }
                        # $B=PNO%7%s%\%k3NN((B
                        gets $file_id1 a_line
                        puts $file_id2 $a_line
                        for { set i 1 } { $i <= $num_states } { incr i } {
                            gets $file_id1 a_line
                            puts $file_id2 $a_line
                            for { set j 1 } { $j <= 4 } { incr j } {
                                gets $file_id1 a_line
                                puts $file_id2 $a_line
                                set fields [split $a_line]
                                set b($i,$j) \
                                    [lindex $fields [expr [llength $fields]-1]]
                            }
                        }
                        # $B=i4|>uBVJ,I[3NN((B
                        gets $file_id1 a_line
                        puts $file_id2 $a_line
                        gets $file_id1 dum1
                        puts $file_id2 $dum1
                        regsub {^	} $dum1 {} dum2
                        regsub { $} $dum2 {} a_line
                        set fields [split $a_line]
                        for { set i 1 } { $i <= $num_states } { incr i } {
                            set pi($i) [lindex $fields [expr $i-1]]
                        }
                        # $BBP?tL`EY(B
                        gets $file_id1 dum1
                        puts $file_id2 $dum1
                        regsub {^[ ]+} $dum1 {} a_line
                        set fields [split $a_line]
                        set log_likelihd [lindex $fields 1]
                        # $B<+M3%Q%i%a!<%??t(B
                        set num_params [lindex $fields 3]
                        # AIC$B4p=`(B
                        gets $file_id1 dum1
                        puts $file_id2 $dum1
                        regsub {^[ ]+} $dum1 {} a_line
                        set fields [split $a_line]
                        set aic [lindex $fields 1]
                        # $BE,1~EY(B
                        set fitness [lindex $fields 3]

                        break
                    }
                }
            }

        }
        close $file_id1
        flush $file_id2
        close $file_id2

        # $B8!:w7k2L$N%A%'%C%/(B
        if { ([string compare $t_message ""] == 0) || 
             ([string compare $i_message ""] == 0) } {
            error "No such generation or individual..."
            return
        }

        # $B3F>uBV$rI=<($9$k:BI8(B(states)$B$H(B
        # $B3F>uBV$N%7%s%\%k=PNO3NN($rI=<($9$k:BI8(B(states1)$B$r;;=P(B
        # ($B$H$j$"$($:(B)$B86E@$rCf?4$KG[CV(B
        # $B2sE>3Q(B($B;~7W2s$j(B)
        set angle [expr 2*$PI/$num_states]
        # $B>uBV(B1$B$O86E@$+$i(B12$B;~$NJ}8~(B
        set dum_states(1,x) [expr round(0)]
        set dum_states(1,y) [expr round(-$r1)]
        set dum_states1(1,x) [expr round(0)]
        set dum_states1(1,y) [expr round([expr -$r1-3.0*$l])]
        # $B>uBV(B1$B$r4p$K2sE>0\F0$K$h$j3F>uBV$N:BI8$r;;=P(B
        for { set i 2 } { $i <= $num_states } { incr i } {
            set dum_states($i,x) [expr round(\
                [expr cos($angle)*$dum_states([expr $i-1],x)\
                -sin($angle)*$dum_states([expr $i-1],y)])]
            set dum_states($i,y) [expr round(\
                [expr sin($angle)*$dum_states([expr $i-1],x)\
                +cos($angle)*$dum_states([expr $i-1],y)])]
            set dum_states1($i,x) [expr round(\
                [expr cos($angle)*$dum_states1([expr $i-1],x)\
                -sin($angle)*$dum_states1([expr $i-1],y)])]
            set dum_states1($i,y) [expr round(\
                [expr sin($angle)*$dum_states1([expr $i-1],x)\
                +cos($angle)*$dum_states1([expr $i-1],y)])]
        }
        # canvas$B$NCf?4$KJB9T0\F0(B
        set move_x [expr round([expr $max_x/2.0])]
        set move_y [expr round([expr $max_y/2.0])]
        for { set i 1 } { $i <= $num_states } { incr i } {
            # $B>uBV$rCV$/:BI8(B
            set states($i,x) [expr round([expr $dum_states($i,x)+$move_x])]
            set states($i,y) [expr round([expr $dum_states($i,y)+$move_y])]
            # $B=PNO%7%s%\%k3NN($rCV$/:BI8(B
            set states1($i,x) [expr round([expr $dum_states1($i,x)+$move_x])]
            set states1($i,y) [expr round([expr $dum_states1($i,y)+$move_y])]
            # $B>uBVA+0\$rI=$9;OE@$H=*E@$N:BI8(B
            if { ($dum_states($i,x) > 0) && ($dum_states($i,y) > 0) } {
                set from($i,x) \
                    [expr round([expr $dum_states($i,x)+$move_x])]
                set from($i,y) \
                    [expr round([expr $dum_states($i,y)+$move_y])-2*$w]
                set to($i,x) \
                    [expr round([expr $dum_states($i,x)+$move_x])-2*$w]
                set to($i,y) \
                    [expr round([expr $dum_states($i,y)+$move_y])]
            } elseif { ($dum_states($i,x) < 0) && ($dum_states($i,y) > 0) } {
                set from($i,x) \
                    [expr round([expr $dum_states($i,x)+$move_x])+2*$w]
                set from($i,y) \
                    [expr round([expr $dum_states($i,y)+$move_y])]
                set to($i,x) \
                    [expr round([expr $dum_states($i,x)+$move_x])]
                set to($i,y) \
                    [expr round([expr $dum_states($i,y)+$move_y])-2*$w]
            } elseif { ($dum_states($i,x) < 0) && ($dum_states($i,y) < 0) } {
                set from($i,x) \
                    [expr round([expr $dum_states($i,x)+$move_x])]
                set from($i,y) \
                    [expr round([expr $dum_states($i,y)+$move_y])+2*$w]
                set to($i,x) \
                    [expr round([expr $dum_states($i,x)+$move_x])+2*$w]
                set to($i,y) \
                    [expr round([expr $dum_states($i,y)+$move_y])]
            } elseif { ($dum_states($i,x) > 0) && ($dum_states($i,y) < 0) } {
                set from($i,x) \
                    [expr round([expr $dum_states($i,x)+$move_x])-2*$w]
                set from($i,y) \
                    [expr round([expr $dum_states($i,y)+$move_y])]
                set to($i,x) \
                    [expr round([expr $dum_states($i,x)+$move_x])]
                set to($i,y) \
                    [expr round([expr $dum_states($i,y)+$move_y])+2*$w]
            } elseif { ($dum_states($i,x) == 0) && ($dum_states($i,y) > 0) } {
                set from($i,x) \
                    [expr round([expr $dum_states($i,x)+$move_x])+2*$w]
                set from($i,y) \
                    [expr round([expr $dum_states($i,y)+$move_y])]
                set to($i,x) \
                    [expr round([expr $dum_states($i,x)+$move_x])-2*$w]
                set to($i,y) \
                    [expr round([expr $dum_states($i,y)+$move_y])]
            } elseif { ($dum_states($i,x) == 0) && ($dum_states($i,y) < 0) } {
                set from($i,x) \
                    [expr round([expr $dum_states($i,x)+$move_x])-2*$w]
                set from($i,y) \
                    [expr round([expr $dum_states($i,y)+$move_y])]
                set to($i,x) \
                    [expr round([expr $dum_states($i,x)+$move_x])+2*$w]
                set to($i,y) \
                    [expr round([expr $dum_states($i,y)+$move_y])]
            } elseif { ($dum_states($i,x) > 0) && ($dum_states($i,y) == 0) } {
                set from($i,x) \
                    [expr round([expr $dum_states($i,x)+$move_x])]
                set from($i,y) \
                    [expr round([expr $dum_states($i,y)+$move_y])-2*$w]
                set to($i,x) \
                    [expr round([expr $dum_states($i,x)+$move_x])]
                set to($i,y) \
                    [expr round([expr $dum_states($i,y)+$move_y])+2*$w]
            } elseif { ($dum_states($i,x) < 0) && ($dum_states($i,y) == 0) } {
                set from($i,x) \
                    [expr round([expr $dum_states($i,x)+$move_x])]
                set from($i,y) \
                    [expr round([expr $dum_states($i,y)+$move_y])+2*$w]
                set to($i,x) \
                    [expr round([expr $dum_states($i,x)+$move_x])]
                set to($i,y) \
                    [expr round([expr $dum_states($i,y)+$move_y])-2*$w]
            }
        }

        # $B3($r=q$/(B
        drawing

    } elseif { $button == "redraw_button" } {

        # $BIA2h>r7o$N$_$r99?7$7$F3($r=q$/(B
        puts stderr "You selected ReDraw menu..."
        # $B%(%i!<=hM}(B
        if { $num_states == 0 } {
            error "There are no items on the canvas..."
            return
        }
        # $B3($r=q$/(B
        drawing


    } elseif { $button == "save_button" } {

        # $B%]%9%H%9%/%j%W%H7A<0$G(Bcanvas$B$N(Bitems$B$rJ]B8(B
        puts stderr "You selected Save menu..."
        .body.view_canvas postscript -file $save_file -colormode color \
            -height $max_y -width $max_x -x 0 -y 0

    } elseif { $button == "quit_button" } {

        # $B=*N;$9$k(B
        puts stderr "You selected Quit menu..."
        exit

    } elseif { $button == "exchange_button" } {

        # $B%(%i!<=hM}(B
        if { $num_states == 0 } {
            error "There are no items on the canvas..."
            return
        }

        # $B%$%s%9%?%s%9$N@8@.(B
        puts stderr "You selected Exchange menu..."
        toplevel .exchange_window
        frame .exchange_window.frame1 -borderwidth $bw -relief groove
        frame .exchange_window.frame2 -borderwidth $bw -relief raised
        label .exchange_window.frame2.exchange1_label -text "Exchange state" \
            -font $ifont
        label .exchange_window.frame2.exchange2_label -text "for state" \
            -font $ifont
        entry .exchange_window.frame2.exchange1_text -background $bg_color \
            -font $bfont -width 4 -borderwidth $bw -relief sunken \
            -selectbackground $select_color
        entry .exchange_window.frame2.exchange2_text -background $bg_color \
            -font $bfont -width 4 -borderwidth $bw -relief sunken \
            -selectbackground $select_color
        button .exchange_window.frame1.cancel_button -text Cancel \
            -font $ifont -command "select cancel_button"
        button .exchange_window.frame1.exchange_button -text OK -font $ifont \
            -command "select ok_button"

        # $B%$%s%9%?%s%9$N%l%$%"%&%H(B
        pack .exchange_window.frame1 -side bottom -fill x
        pack .exchange_window.frame2 -side top -fill x
        pack .exchange_window.frame2.exchange1_label -side left \
            -padx $pad1 -pady $pad1
        pack .exchange_window.frame2.exchange1_text -side left \
            -padx $pad1 -pady $pad1
        pack .exchange_window.frame2.exchange2_label -side left \
            -padx $pad1 -pady $pad1
        pack .exchange_window.frame2.exchange2_text -side left \
            -padx $pad1 -pady $pad1
        pack .exchange_window.frame1.exchange_button -side left \
            -padx $pad1 -pady $pad1
        pack .exchange_window.frame1.cancel_button -side right \
            -padx $pad1 -pady $pad1
        wm title .exchange_window HMMView(Exchange)

       # $B%-!<%P%$%s%I(B
       bind .exchange_window.frame2.exchange1_text <Return> \
           "focus .exchange_window.frame2.exchange2_text"
       bind .exchange_window.frame2.exchange1_text <Control-n> \
           "focus .exchange_window.frame2.exchange2_text"
       bind .exchange_window.frame2.exchange1_text <Control-p> \
           "focus .exchange_window.frame2.exchange2_text"
       bind .exchange_window.frame2.exchange1_text <Control-q> \
           "select quit_button"
       bind .exchange_window.frame2.exchange2_text <Return> \
           "select ok_button"
       bind .exchange_window.frame2.exchange2_text <Control-n> \
           "focus .exchange_window.frame2.exchange1_text"
       bind .exchange_window.frame2.exchange2_text <Control-p> \
           "focus .exchange_window.frame2.exchange1_text"
       bind .exchange_window.frame2.exchange2_text <Control-q> \
           "select quit_button"

    } elseif { $button == "cancel_button" } {

        # $B%5%V%&%#%s%I%&$r>C5n(B
        puts stderr "You selected Cancel button..."
        destroy .exchange_window

    } elseif { $button == "ok_button" } {

        # focus$B$r$=$i$9(B
        focus .body.view_canvas

        # $B>uBV$r8r49(B
        puts stderr "You selected OK button..."
        regsub -all {[ ]+} [.exchange_window.frame2.exchange1_text get] \
            {} state1
        regsub -all {[ ]+} [.exchange_window.frame2.exchange2_text get] \
            {} state2
        puts stderr "Excanging state $state1 for $state2..."
        if { ([regexp -nocase {^[1-9][0-9]*$} $state1] == 0) || \
             ([regexp -nocase {^[1-9][0-9]*$} $state2] == 0) || \
             ($state1 > $num_states) || ($state2 > $num_states) } {
            error "Invalid state..."
            return
        }
        # $B:BI8$r8r49$9$k(B
        exchange_coordinates $state1 $state2

        # $B%5%V%&%#%s%I%&$r>C5n(B
        destroy .exchange_window

        # $B3($r=q$/(B
        drawing

    } elseif { $button == "clear_button" } {

        puts stderr "You selected Clear button..."

        # $B3F@_Dj$N=i4|2=(B
        set num_states 0
        .setting_window.keys.frame1.file_text delete 0 end
        .setting_window.keys.frame2.generation_text delete 0 end
        .setting_window.keys.frame2.individual_text delete 0 end
        .setting_window.condition.a_scale set 0
        .setting_window.condition.b_scale set 0
        .setting_window.condition.pi_scale set 0

        # canvas$B$N=i4|2=(B
        .body.view_canvas delete all

    }

}

# color map$B$rJV$9(B...
proc get_cmap value {

    if { ($value >= 0.9) && ($value <= 1.0) } {
        set cmap "#f00"
    } elseif { ($value >= 0.8) && ($value < 0.9) } {
        set cmap "#f70"
#        set cmap "#f90"
    } elseif { ($value >= 0.7) && ($value < 0.8) } {
        set cmap "#fb0"
#        set cmap "#fd0"
    } elseif { ($value >= 0.6) && ($value < 0.7) } {
        set cmap "#ff0"
    } elseif { ($value >= 0.5) && ($value < 0.6) } {
        set cmap "#bf0"
    } elseif { ($value >= 0.4) && ($value < 0.5) } {
        set cmap "#0f0"
    } elseif { ($value >= 0.3) && ($value < 0.4) } {
        set cmap "#4fd"
    } elseif { ($value >= 0.2) && ($value < 0.3) } {
        set cmap "#2af"
    } elseif { ($value >= 0.1) && ($value < 0.2) } {
        set cmap "#05f"
#        set cmap "#00f"
    } elseif { ($value >= 0.0) && ($value < 0.1) } {
        set cmap "#00a"
    }

    return $cmap
}

# $B3($r=q$/(B
proc drawing {} {
    global ifont bfont lbfont pad1
    global fg_color bg_color obj_color select_color enter_color
    global base_color base_name
    global save_file work_file
    global max_x max_y margin r1 w l bw
    global PI eps

    global file_name generation individual
    global num_states
    global a b pi log_likelihd num_params aic fitness
    global a_scale b_scale pi_scale
    global states dum_states states1 dum_states1
    global from to
    global status

    # $BIA2h>r7o$N3MF@(B
    set a_scale [expr [.setting_window.condition.a_scale get]/100.0]
    set b_scale [expr [.setting_window.condition.b_scale get]/100.0]
    set pi_scale [expr [.setting_window.condition.pi_scale get]/100.0]
    puts stderr "Threshold of a is $a_scale..."
    puts stderr "Threshold of b is $b_scale..."
    puts stderr "Threshold of pi is $pi_scale..."

    # canvas$B$N=i4|2=(B
    .body.view_canvas delete all

    # $B%F%-%9%H$rI=<((B
    .body.view_canvas create text $margin $margin -anchor nw -font $lbfont -text "File: $file_name\nGeneration: $generation\nIndividual: $individual"
    .body.view_canvas create text $margin [expr $max_y-$margin] -anchor sw -font $lbfont -text [format "Log likelihood: %6.3e\tFree parameters: %2d\nAIC criterion: %6.3e\tFitness: %6.3e" $log_likelihd $num_params $aic $fitness]

    # $B?'8+K\(B($B3NN((B)$B$rI=<((B
    for { set i 0 } { $i < 10 } { incr i } {
        set cmap [get_cmap [expr $i/10.0]]
        .body.view_canvas create rectangle \
            [expr $max_x-$margin-$l] \
            [expr $max_y-$margin-$l/2*($i+1)] \
            [expr $max_x-$margin] \
            [expr $max_y-$margin-$l/2*$i] \
            -fill $cmap -outline $cmap
    }
    for { set i 0 } { $i <= 10 } { incr i 2 } {
        .body.view_canvas create text [expr $max_x-2*$margin-$l] \
            [expr $max_y-$margin-$l/2*$i] \
            -anchor e -font $bfont -text [format "%4.2f" [expr $i/10.0]]
    }
    # $B?'8+K\(B($B1v4p(B)$B$rI=<((B
    for { set i 0 } { $i < 4 } { incr i } {
        .body.view_canvas create rectangle \
            [expr $max_x-$margin-$l] \
            [expr $margin+$l/2*($i+1)] \
            [expr $max_x-$margin] \
            [expr $margin+$l/2*$i] \
            -fill $base_color([expr $i+1]) \
            -outline $base_color([expr $i+1])
        .body.view_canvas create text \
             [expr $max_x-$margin-$l/2.0] \
             [expr $margin+$i*$l/2.0+$l/4.0] \
             -font $lbfont -text $base_name([expr $i+1])
    }

    # $B3F>uBVA+0\$rI=<((B
    for { set i 1 } { $i <= $num_states } { incr i } {
        for { set j 1 } { $j <= $num_states } { incr j } {
            if { ($a($i,$j) >= [expr -$eps]) && \
                ($a($i,$j) <= [expr $eps]) } {
                continue
            } elseif { $a($i,$j) >= $a_scale } {
                set cmap [get_cmap $a($i,$j)]
                if { $i != $j } {
                    .body.view_canvas create line \
                        $from($i,x) $from($i,y) $to($j,x) $to($j,y) \
                        -fill $cmap -arrow last -width $w \
                        -tags $i->$j
                    # $B%-!<%P%$%s%I(B
                    .body.view_canvas bind $i->$j <Enter> \
                        ".body.view_canvas itemconfigure current \
                        -fill $enter_color"
                    .body.view_canvas bind $i->$j <Leave> \
                        ".body.view_canvas itemconfigure current \
                        -fill [get_cmap $a($i,$j)]"
                    .body.view_canvas bind $i->$j <ButtonPress-1> \
                        "item_start_drag .body.view_canvas %x %y"
                    .body.view_canvas bind $i->$j <Button1-Motion> \
                        "item_drag .body.view_canvas %x %y"
                    .body.view_canvas bind $i->$j <ButtonRelease-1> \
                        "item_end_drag .body.view_canvas %x %y"
                } else {
                    if { ($dum_states($i,x) > 0) && \
                        ($dum_states($i,y) > 0) } {
                        .body.view_canvas create oval \
                            [expr $states($i,x)+0.5*$l] \
                            [expr $states($i,y)+1.5*$l] \
                            [expr $states($i,x)+1.5*$l] \
                            [expr $states($i,y)+0.5*$l] \
                            -outline $cmap -width $w
                        .body.view_canvas create line \
                            [expr $states($i,x)+0.5*$l] \
                            [expr $states($i,y)+1.0*$l+1] \
                            [expr $states($i,x)+0.5*$l] \
                            [expr $states($i,y)+1.0*$l] \
                            -fill $cmap -arrow last -width $w
                    } elseif { ($dum_states($i,x) < 0) && \
                        ($dum_states($i,y) > 0) } {
                        .body.view_canvas create oval \
                            [expr $states($i,x)-0.5*$l] \
                            [expr $states($i,y)+1.5*$l] \
                            [expr $states($i,x)-1.5*$l] \
                            [expr $states($i,y)+0.5*$l] \
                            -outline $cmap -width $w
                        .body.view_canvas create line \
                            [expr $states($i,x)-1.0*$l-1] \
                            [expr $states($i,y)+0.5*$l] \
                            [expr $states($i,x)-1.0*$l] \
                            [expr $states($i,y)+0.5*$l] \
                            -fill $cmap -arrow last -width $w
                    } elseif { ($dum_states($i,x) < 0) && \
                        ($dum_states($i,y) < 0) } {
                        .body.view_canvas create oval \
                            [expr $states($i,x)-0.5*$l] \
                            [expr $states($i,y)-1.5*$l] \
                            [expr $states($i,x)-1.5*$l] \
                            [expr $states($i,y)-0.5*$l] \
                            -outline $cmap -width $w
                        .body.view_canvas create line \
                            [expr $states($i,x)-0.5*$l] \
                            [expr $states($i,y)-1.0*$l-1] \
                            [expr $states($i,x)-0.5*$l] \
                            [expr $states($i,y)-1.0*$l] \
                            -fill $cmap -arrow last -width $w
                    } elseif { ($dum_states($i,x) > 0) && \
                        ($dum_states($i,y) < 0) } {
                        .body.view_canvas create oval \
                            [expr $states($i,x)+0.5*$l] \
                            [expr $states($i,y)-1.5*$l] \
                            [expr $states($i,x)+1.5*$l] \
                            [expr $states($i,y)-0.5*$l] \
                            -outline $cmap -width $w
                        .body.view_canvas create line \
                            [expr $states($i,x)+1.0*$l+1] \
                            [expr $states($i,y)-0.5*$l] \
                            [expr $states($i,x)+1.0*$l] \
                            [expr $states($i,y)-0.5*$l] \
                            -fill $cmap -arrow last -width $w
                    } elseif { ($dum_states($i,x) == 0) && \
                        ($dum_states($i,y) > 0) } {
                        .body.view_canvas create oval \
                            [expr $states($i,x)-$l] \
                            [expr $states($i,y)+1.5*$l] \
                            [expr $states($i,x)] \
                            [expr $states($i,y)+0.5*$l] \
                            -outline $cmap -width $w
                        .body.view_canvas create line \
                            [expr $states($i,x)-0.5*$l-1] \
                            [expr $states($i,y)+0.5*$l] \
                            [expr $states($i,x)-0.5*$l] \
                            [expr $states($i,y)+0.5*$l] \
                            -fill $cmap -arrow last -width $w
                    } elseif { ($dum_states($i,x) == 0) && \
                        ($dum_states($i,y) < 0) } {
                        .body.view_canvas create oval \
                            [expr $states($i,x)+$l] \
                            [expr $states($i,y)-1.5*$l] \
                            [expr $states($i,x)] \
                            [expr $states($i,y)-0.5*$l] \
                            -outline $cmap -width $w
                        .body.view_canvas create line \
                            [expr $states($i,x)+0.5*$l+1] \
                            [expr $states($i,y)-0.5*$l] \
                            [expr $states($i,x)+0.5*$l] \
                            [expr $states($i,y)-0.5*$l] \
                            -fill $cmap -arrow last -width $w
                    } elseif { ($dum_states($i,x) > 0) && \
                        ($dum_states($i,y) == 0) } {
                        .body.view_canvas create oval \
                            [expr $states($i,x)+0.5*$l] \
                            [expr $states($i,y)] \
                            [expr $states($i,x)+1.5*$l] \
                            [expr $states($i,y)+1.0*$l] \
                            -outline $cmap -width $w
                        .body.view_canvas create line \
                            [expr $states($i,x)+0.5*$l] \
                            [expr $states($i,y)+0.5*$l+1] \
                            [expr $states($i,x)+0.5*$l] \
                            [expr $states($i,y)+0.5*$l] \
                            -fill $cmap -arrow last -width $w
                    } elseif { ($dum_states($i,x) < 0) && \
                        ($dum_states($i,y) == 0) } {
                        .body.view_canvas create oval \
                            [expr $states($i,x)-0.5*$l] \
                            [expr $states($i,y)-1.0*$l] \
                            [expr $states($i,x)-1.5*$l] \
                            [expr $states($i,y)] \
                            -outline $cmap -width $w
                        .body.view_canvas create line \
                            [expr $states($i,x)-0.5*$l] \
                            [expr $states($i,y)-0.5*$l-1] \
                            [expr $states($i,x)-0.5*$l] \
                            [expr $states($i,y)-0.5*$l] \
                            -fill $cmap -arrow last -width $w
                    }
                }
            }
        }
    }

    # $B3F>uBV$H=i4|>uBVJ,I[3NN($rI=<((B
    for { set i 1 } { $i <= $num_states } { incr i } {
        set cmap [get_cmap $pi($i)]
        if { $pi($i) < $pi_scale } {
            set cmap $obj_color
        }
        if { ($dum_states($i,x) > 0) && ($dum_states($i,y) > 0) } {
            .body.view_canvas create rectangle $states($i,x) $states($i,y) \
                 [expr $states($i,x)+$l] [expr $states($i,y)+$l] \
                 -fill $cmap -width $w
            .body.view_canvas create text \
                 [expr $states($i,x)+round([expr $l/2.0])] \
                 [expr $states($i,y)+round([expr $l/2.0])] \
                 -font $lbfont -text "S$i" -fill $fg_color -tags S$i
        } elseif { ($dum_states($i,x) < 0) && ($dum_states($i,y) > 0) } {
            .body.view_canvas create rectangle \
                 [expr $states($i,x)] [expr $states($i,y)] \
                 [expr $states($i,x)-$l] [expr $states($i,y)+$l] \
                 -fill $cmap -width $w
            .body.view_canvas create text \
                 [expr $states($i,x)-round([expr $l/2.0])] \
                 [expr $states($i,y)+round([expr $l/2.0])] \
                 -font $lbfont -text "S$i" -fill $fg_color -tags S$i
        } elseif { ($dum_states($i,x) < 0) && ($dum_states($i,y) < 0) } {
            .body.view_canvas create rectangle \
                 [expr $states($i,x)] [expr $states($i,y)] \
                 [expr $states($i,x)-$l] [expr $states($i,y)-$l] \
                 -fill $cmap -width $w
            .body.view_canvas create text \
                 [expr $states($i,x)-round([expr $l/2.0])] \
                 [expr $states($i,y)-round([expr $l/2.0])] \
                 -font $lbfont -text "S$i" -fill $fg_color -tags S$i
        } elseif { ($dum_states($i,x) > 0) && ($dum_states($i,y) < 0) } {
            .body.view_canvas create rectangle \
                 [expr $states($i,x)] [expr $states($i,y)] \
                 [expr $states($i,x)+$l] [expr $states($i,y)-$l] \
                 -fill $cmap -width $w
            .body.view_canvas create text \
                 [expr $states($i,x)+round([expr $l/2.0])] \
                 [expr $states($i,y)-round([expr $l/2.0])] \
                 -font $lbfont -text "S$i" -fill $fg_color -tags S$i
        } elseif { ($dum_states($i,x) == 0) && ($dum_states($i,y) > 0) } {
            .body.view_canvas create rectangle \
                 [expr $states($i,x)-round([expr $l/2.0])] \
                 [expr $states($i,y)] \
                 [expr $states($i,x)+round([expr $l/2.0])] \
                 [expr $states($i,y)+$l] \
                 -fill $cmap -width $w
            .body.view_canvas create text \
                 [expr $states($i,x)] \
                 [expr $states($i,y)+round([expr $l/2.0])] \
                 -font $lbfont -text "S$i" -fill $fg_color -tags S$i
        } elseif { ($dum_states($i,x) == 0) && ($dum_states($i,y) < 0) } {
            .body.view_canvas create rectangle \
                 [expr $states($i,x)+round([expr $l/2.0])] \
                 [expr $states($i,y)] \
                 [expr $states($i,x)-round([expr $l/2.0])] \
                 [expr $states($i,y)-$l] \
                 -fill $cmap -width $w
            .body.view_canvas create text \
                 [expr $states($i,x)] \
                 [expr $states($i,y)-round([expr $l/2.0])] \
                 -font $lbfont -text "S$i" -fill $fg_color -tags S$i
        } elseif { ($dum_states($i,x) > 0) && ($dum_states($i,y) == 0) } {
            .body.view_canvas create rectangle \
                 [expr $states($i,x)] \
                 [expr $states($i,y)-round([expr $l/2.0])] \
                 [expr $states($i,x)+$l] \
                 [expr $states($i,y)+round([expr $l/2.0])] \
                 -fill $cmap -width $w
            .body.view_canvas create text \
                 [expr $states($i,x)+round([expr $l/2.0])] \
                 [expr $states($i,y)] \
                 -font $lbfont -text "S$i" -fill $fg_color -tags S$i
        } elseif { ($dum_states($i,x) < 0) && ($dum_states($i,y) == 0) } {
            .body.view_canvas create rectangle \
                 [expr $states($i,x)] \
                 [expr $states($i,y)+round([expr $l/2.0])] \
                 [expr $states($i,x)-$l] \
                 [expr $states($i,y)-round([expr $l/2.0])] \
                 -fill $cmap -width $w
            .body.view_canvas create text \
                 [expr $states($i,x)-round([expr $l/2.0])] \
                 [expr $states($i,y)] \
                 -font $lbfont -text "S$i" -fill $fg_color -tags S$i
        }

        # $B%-!<%P%$%s%I(B
        set status($i) 0
        .body.view_canvas bind S$i <Enter> \
            ".body.view_canvas itemconfigure current -fill $enter_color"
        .body.view_canvas bind S$i <Leave> \
            "leave_state .body.view_canvas $i"
        .body.view_canvas bind S$i <ButtonPress-1> \
            "select_state .body.view_canvas $i"
    }
    # $B%7%s%\%k=PNO3NN($NI=<((B
    for { set i 1 } { $i <= $num_states } { incr i } {
        set base 90
        if { ($dum_states($i,x) > 0) && ($dum_states($i,y) > 0) } {
            for { set j 1 } { $j <= 4 } { incr j } {
                set angle [expr -$b($i,$j)*360]
                if { ($b($i,$j) >= [expr 1.0-$eps]) && \
                    ($b($i,$j) <= [expr 1.0+$eps]) } {
                    .body.view_canvas create oval \
                        [expr $states1($i,x)-0.75*$l] \
                        [expr $states1($i,y)-0.75*$l] \
                        [expr $states1($i,x)+0.75*$l] \
                        [expr $states1($i,y)+0.75*$l] \
                        -width 0 -fill $base_color($j) \
                        -outline $base_color($j)
                } elseif { ($b($i,$j) >= [expr -$eps]) && \
                    ($b($i,$j) <= [expr $eps]) } {
                    continue
                } elseif { $b_scale <= $b($i,$j) } {
                    .body.view_canvas create arc \
                        [expr $states1($i,x)-0.75*$l] \
                        [expr $states1($i,y)-0.75*$l] \
                        [expr $states1($i,x)+0.75*$l] \
                        [expr $states1($i,y)+0.75*$l] \
                        -extent $angle \
                        -start $base \
                        -width 0 -fill $base_color($j) \
                        -outline $base_color($j)
                } else {
                    .body.view_canvas create arc \
                        [expr $states1($i,x)-0.75*$l] \
                        [expr $states1($i,y)-0.75*$l] \
                        [expr $states1($i,x)+0.75*$l] \
                        [expr $states1($i,y)+0.75*$l] \
                        -extent $angle \
                        -start $base \
                        -width [expr $w/2.0] -fill $obj_color
                }
                set base [expr $angle+$base]
            }
        } elseif { ($dum_states($i,x) < 0) && ($dum_states($i,y) > 0) } {
            for { set j 1 } { $j <= 4 } { incr j } {
                set angle [expr -$b($i,$j)*360]
                if { ($b($i,$j) >= [expr 1.0-$eps]) && \
                    ($b($i,$j) <= [expr 1.0+$eps]) } {
                    .body.view_canvas create oval \
                        [expr $states1($i,x)+0.75*$l] \
                        [expr $states1($i,y)-0.75*$l] \
                        [expr $states1($i,x)-0.75*$l] \
                        [expr $states1($i,y)+0.75*$l] \
                        -width 0 -fill $base_color($j) \
                        -outline $base_color($j)
                } elseif { ($b($i,$j) >= [expr -$eps]) && \
                    ($b($i,$j) <= [expr $eps]) } {
                    continue
                } elseif { $b_scale <= $b($i,$j) } {
                    .body.view_canvas create arc \
                        [expr $states1($i,x)+0.75*$l] \
                        [expr $states1($i,y)-0.75*$l] \
                        [expr $states1($i,x)-0.75*$l] \
                        [expr $states1($i,y)+0.75*$l] \
                        -extent $angle \
                        -start $base \
                        -width 0 -fill $base_color($j) \
                        -outline $base_color($j)
                } else {
                    .body.view_canvas create arc \
                        [expr $states1($i,x)+0.75*$l] \
                        [expr $states1($i,y)-0.75*$l] \
                        [expr $states1($i,x)-0.75*$l] \
                        [expr $states1($i,y)+0.75*$l] \
                        -extent $angle \
                        -start $base \
                        -width [expr $w/2.0] -fill $obj_color
                }
                set base [expr $angle+$base]
            }
        } elseif { ($dum_states($i,x) < 0) && ($dum_states($i,y) < 0) } {
            for { set j 1 } { $j <= 4 } { incr j } {
                set angle [expr -$b($i,$j)*360]
                if { ($b($i,$j) >= [expr 1.0-$eps]) && \
                    ($b($i,$j) <= [expr 1.0+$eps]) } {
                    .body.view_canvas create oval \
                        [expr $states1($i,x)+0.75*$l] \
                        [expr $states1($i,y)+0.75*$l] \
                        [expr $states1($i,x)-0.75*$l] \
                        [expr $states1($i,y)-0.75*$l] \
                        -width 0 -fill $base_color($j) \
                        -outline $base_color($j)
                } elseif { ($b($i,$j) >= [expr -$eps]) && \
                    ($b($i,$j) <= [expr $eps]) } {
                    continue
                } elseif { $b_scale <= $b($i,$j) } {
                    .body.view_canvas create arc \
                        [expr $states1($i,x)+0.75*$l] \
                        [expr $states1($i,y)+0.75*$l] \
                        [expr $states1($i,x)-0.75*$l] \
                        [expr $states1($i,y)-0.75*$l] \
                        -extent $angle \
                        -start $base \
                        -width 0 -fill $base_color($j) \
                        -outline $base_color($j)
                } else {
                    .body.view_canvas create arc \
                        [expr $states1($i,x)+0.75*$l] \
                        [expr $states1($i,y)+0.75*$l] \
                        [expr $states1($i,x)-0.75*$l] \
                        [expr $states1($i,y)-0.75*$l] \
                        -extent $angle \
                        -start $base \
                        -width [expr $w/2.0] -fill $obj_color
                }
                set base [expr $angle+$base]
            }
        } elseif { ($dum_states($i,x) > 0) && ($dum_states($i,y) < 0) } {
            for { set j 1 } { $j <= 4 } { incr j } {
                set angle [expr -$b($i,$j)*360]
                if { ($b($i,$j) >= [expr 1.0-$eps]) && \
                    ($b($i,$j) <= [expr 1.0+$eps]) } {
                    .body.view_canvas create oval \
                        [expr $states1($i,x)-0.75*$l] \
                        [expr $states1($i,y)+0.75*$l] \
                        [expr $states1($i,x)+0.75*$l] \
                        [expr $states1($i,y)-0.75*$l] \
                        -width 0 -fill $base_color($j) \
                        -outline $base_color($j)
                } elseif { ($b($i,$j) >= [expr -$eps]) && \
                    ($b($i,$j) <= [expr $eps]) } {
                    continue
                } elseif { $b_scale <= $b($i,$j) } {
                    .body.view_canvas create arc \
                        [expr $states1($i,x)-0.75*$l] \
                        [expr $states1($i,y)+0.75*$l] \
                        [expr $states1($i,x)+0.75*$l] \
                        [expr $states1($i,y)-0.75*$l] \
                        -extent $angle \
                        -start $base \
                        -width 0 -fill $base_color($j) \
                        -outline $base_color($j)
                } else {
                    .body.view_canvas create arc \
                        [expr $states1($i,x)-0.75*$l] \
                        [expr $states1($i,y)+0.75*$l] \
                        [expr $states1($i,x)+0.75*$l] \
                        [expr $states1($i,y)-0.75*$l] \
                        -extent $angle \
                        -start $base \
                        -width [expr $w/2.0] -fill $obj_color
                }
                set base [expr $angle+$base]
            }
        } elseif { ($dum_states($i,x) == 0) && ($dum_states($i,y) > 0) } {
            for { set j 1 } { $j <= 4 } { incr j } {
                set angle [expr -$b($i,$j)*360]
                if { ($b($i,$j) >= [expr 1.0-$eps]) && \
                    ($b($i,$j) <= [expr 1.0+$eps]) } {
                    .body.view_canvas create oval \
                        [expr $states1($i,x)+0.75*$l] \
                        [expr $states1($i,y)-0.75*$l] \
                        [expr $states1($i,x)-0.75*$l] \
                        [expr $states1($i,y)+0.75*$l] \
                        -width 0 -fill $base_color($j) \
                        -outline $base_color($j)
                } elseif { ($b($i,$j) >= [expr -$eps]) && \
                    ($b($i,$j) <= [expr $eps]) } {
                    continue
                } elseif { $b_scale <= $b($i,$j) } {
                    .body.view_canvas create arc \
                        [expr $states1($i,x)+0.75*$l] \
                        [expr $states1($i,y)-0.75*$l] \
                        [expr $states1($i,x)-0.75*$l] \
                        [expr $states1($i,y)+0.75*$l] \
                        -extent $angle \
                        -start $base \
                        -width 0 -fill $base_color($j) \
                        -outline $base_color($j)
                } else {
                    .body.view_canvas create arc \
                        [expr $states1($i,x)+0.75*$l] \
                        [expr $states1($i,y)-0.75*$l] \
                        [expr $states1($i,x)-0.75*$l] \
                        [expr $states1($i,y)+0.75*$l] \
                        -extent $angle \
                        -start $base \
                        -width [expr $w/2.0] -fill $obj_color
                }
                set base [expr $angle+$base]
            }
        } elseif { ($dum_states($i,x) == 0) && ($dum_states($i,y) < 0) } {
            for { set j 1 } { $j <= 4 } { incr j } {
                set angle [expr -$b($i,$j)*360]
                if { ($b($i,$j) >= [expr 1.0-$eps]) && \
                    ($b($i,$j) <= [expr 1.0+$eps]) } {
                    .body.view_canvas create oval \
                        [expr $states1($i,x)+0.75*$l] \
                        [expr $states1($i,y)-0.75*$l] \
                        [expr $states1($i,x)-0.75*$l] \
                        [expr $states1($i,y)+0.75*$l] \
                        -width 0 -fill $base_color($j) \
                        -outline $base_color($j)
                } elseif { ($b($i,$j) >= [expr -$eps]) && \
                    ($b($i,$j) <= [expr $eps]) } {
                    continue
                } elseif { $b_scale <= $b($i,$j) } {
                    .body.view_canvas create arc \
                        [expr $states1($i,x)+0.75*$l] \
                        [expr $states1($i,y)-0.75*$l] \
                        [expr $states1($i,x)-0.75*$l] \
                        [expr $states1($i,y)+0.75*$l] \
                        -extent $angle \
                        -start $base \
                        -width 0 -fill $base_color($j) \
                        -outline $base_color($j)
                } else {
                    .body.view_canvas create arc \
                        [expr $states1($i,x)+0.75*$l] \
                        [expr $states1($i,y)-0.75*$l] \
                        [expr $states1($i,x)-0.75*$l] \
                        [expr $states1($i,y)+0.75*$l] \
                        -extent $angle \
                        -start $base \
                        -width [expr $w/2.0] -fill $obj_color
                }
                set base [expr $angle+$base]
            }
        } elseif { ($dum_states($i,x) > 0) && ($dum_states($i,y) == 0) } {
            for { set j 1 } { $j <= 4 } { incr j } {
                set angle [expr -$b($i,$j)*360]
                if { ($b($i,$j) >= [expr 1.0-$eps]) && \
                    ($b($i,$j) <= [expr 1.0+$eps]) } {
                    .body.view_canvas create oval \
                        [expr $states1($i,x)+0.75*$l] \
                        [expr $states1($i,y)-0.75*$l] \
                        [expr $states1($i,x)-0.75*$l] \
                        [expr $states1($i,y)+0.75*$l] \
                        -width 0 -fill $base_color($j) \
                        -outline $base_color($j)
                } elseif { ($b($i,$j) >= [expr -$eps]) && \
                    ($b($i,$j) <= [expr $eps]) } {
                    continue
                } elseif { $b_scale <= $b($i,$j) } {
                    .body.view_canvas create arc \
                        [expr $states1($i,x)+0.75*$l] \
                        [expr $states1($i,y)-0.75*$l] \
                        [expr $states1($i,x)-0.75*$l] \
                        [expr $states1($i,y)+0.75*$l] \
                        -extent $angle \
                        -start $base \
                        -width 0 -fill $base_color($j) \
                        -outline $base_color($j)
                } else {
                    .body.view_canvas create arc \
                        [expr $states1($i,x)+0.75*$l] \
                        [expr $states1($i,y)-0.75*$l] \
                        [expr $states1($i,x)-0.75*$l] \
                        [expr $states1($i,y)+0.75*$l] \
                        -extent $angle \
                        -start $base \
                        -width [expr $w/2.0] -fill $obj_color
                }
                set base [expr $angle+$base]
            }
        } elseif { ($dum_states($i,x) < 0) && ($dum_states($i,y) == 0) } {
            for { set j 1 } { $j <= 4 } { incr j } {
                set angle [expr -$b($i,$j)*360]
                if { ($b($i,$j) >= [expr 1.0-$eps]) && \
                    ($b($i,$j) <= [expr 1.0+$eps]) } {
                    .body.view_canvas create oval \
                        [expr $states1($i,x)+0.75*$l] \
                        [expr $states1($i,y)-0.75*$l] \
                        [expr $states1($i,x)-0.75*$l] \
                        [expr $states1($i,y)+0.75*$l] \
                        -width 0 -fill $base_color($j) \
                        -outline $base_color($j)
                } elseif { ($b($i,$j) >= [expr -$eps]) && \
                    ($b($i,$j) <= [expr $eps]) } {
                    continue
                } elseif { $b_scale <= $b($i,$j) } {
                    .body.view_canvas create arc \
                        [expr $states1($i,x)+0.75*$l] \
                        [expr $states1($i,y)-0.75*$l] \
                        [expr $states1($i,x)-0.75*$l] \
                        [expr $states1($i,y)+0.75*$l] \
                        -extent $angle \
                        -start $base \
                        -width 0 -fill $base_color($j) \
                        -outline $base_color($j)
                } else {
                    .body.view_canvas create arc \
                        [expr $states1($i,x)+0.75*$l] \
                        [expr $states1($i,y)-0.75*$l] \
                        [expr $states1($i,x)-0.75*$l] \
                        [expr $states1($i,y)+0.75*$l] \
                        -extent $angle \
                        -start $base \
                        -width [expr $w/2.0] -fill $obj_color
                }
                set base [expr $angle+$base]
            }
        }
    }
}

proc item_start_drag {c x y} {
    global first_x first_y
    global last_x last_y

    set first_x [$c canvasx $x]
    set first_y [$c canvasy $y]
    set last_x [$c canvasx $x]
    set last_y [$c canvasy $y]
}

proc item_drag {c x y} {
    global last_x last_y

    set x [$c canvasx $x]
    set y [$c canvasy $y]
    $c move current [expr $x-$last_x] [expr $y-$last_y]
    set last_x $x
    set last_y $y
}

proc item_end_drag {c x y} {
    global last_x last_y
    global first_x first_y

    set x [$c canvasx $x]
    set y [$c canvasy $y]
    $c move current [expr $first_x-$x] [expr $first_y-$y]
}

proc select_state {c i} {
    global status
    global fg_color
    global select_color
    global num_states

    if { $status($i) == 0 } {
        set status($i) 1
        $c itemconfigure current -fill $select_color
        puts "You selected S$i..."
    } else {
        set status($i) 0
        $c itemconfigure current -fill $fg_color
        puts "You unselected S$i..."
    }

    set count 0
    for { set i 1 } { $i <= $num_states } { incr i } {
        if { $status($i) == 1 } {
            incr count
            set dum($count) $i
        }
    }
    if { $count == 2 } {
        puts stderr "Excanging state $dum(1) for $dum(2)..."
        # $B:BI8$r8r49$9$k(B
        exchange_coordinates $dum(1) $dum(2)
        # $B3($r=q$/(B
        drawing
    }
}

proc leave_state {c i} {
    global status
    global fg_color
    global select_color

    if { $status($i) == 0 } {
        .body.view_canvas itemconfigure current -fill $fg_color
    } else {
        .body.view_canvas itemconfigure current -fill $select_color
    }
}

proc exchange_coordinates {state1 state2} {
    global states dum_states states1 dum_states1
    global from to

    # $B>uBV$N:BI8$r8r49$9$k(B
    set xdum $dum_states($state1,x)
    set ydum $dum_states($state1,y)
    set dum_states($state1,x) $dum_states($state2,x)
    set dum_states($state1,y) $dum_states($state2,y)
    set dum_states($state2,x) $xdum
    set dum_states($state2,y) $ydum
    set xdum $states($state1,x)
    set ydum $states($state1,y)
    set states($state1,x) $states($state2,x)
    set states($state1,y) $states($state2,y)
    set states($state2,x) $xdum
    set states($state2,y) $ydum
    # $B>uBVA+0\$N;OE@$H=*E@$N:BI8$r8r49$9$k(B
    set xdum $from($state1,x)
    set ydum $from($state1,y)
    set from($state1,x) $from($state2,x)
    set from($state1,y) $from($state2,y)
    set from($state2,x) $xdum
    set from($state2,y) $ydum
    set xdum $to($state1,x)
    set ydum $to($state1,y)
    set to($state1,x) $to($state2,x)
    set to($state1,y) $to($state2,y)
    set to($state2,x) $xdum
    set to($state2,y) $ydum
    # $B=PNO%7%s%\%k$N:BI8$r8r49$9$k(B
    set xdum $dum_states1($state1,x)
    set ydum $dum_states1($state1,y)
    set dum_states1($state1,x) $dum_states1($state2,x)
    set dum_states1($state1,y) $dum_states1($state2,y)
    set dum_states1($state2,x) $xdum
    set dum_states1($state2,y) $ydum
    set xdum $states1($state1,x)
    set ydum $states1($state1,y)
    set states1($state1,x) $states1($state2,x)
    set states1($state1,y) $states1($state2,y)
    set states1($state2,x) $xdum
    set states1($state2,y) $ydum
}
