########################################################################
#                                                                      #
#      Joint Motion Editor for Swumsuit                                #
#                                         since 2004.12.16             #
#                                         (c) Motomu Nakashima         #
########################################################################

# Main window
proc EditJointMotion {} {
    # make window (if does not exist)
    if { [winfo exists .editjm ]==0 } {
        toplevel .editjm
        wm title .editjm "Swumsuit: Edit Joint Motion"

        # list box and scroll bars
        listbox .editjm.list -height 30 -width 40 -relief groove \
                          -xscrollcommand ".editjm.xsc set" \
                          -yscrollcommand ".editjm.ysc set" \
                          -exportselection false \
                          -selectmode extended
        bind .editjm.list <Double-Button> EditEachMotion
        scrollbar .editjm.xsc -orient horizontal \
                          -command ".editjm.list xview"
        scrollbar .editjm.ysc -orient vertical \
                          -command ".editjm.list yview"
        global Segment_Axis_Angles
        label .editjm.label -text $Segment_Axis_Angles \
                            -relief groove -anchor w

        grid .editjm.label -row 0 -column 1 -sticky ew
        grid .editjm.list  -row 1 -column 1 -sticky nsew
        grid .editjm.xsc   -row 2 -column 1 -sticky ew
        grid .editjm.ysc   -row 1 -column 2 -sticky ns
        grid rowconfigure    .editjm 1 -weight 100
        grid columnconfigure .editjm 1 -weight 100

        # create, cut, copy, paste, etc...
        frame .editjm.frame
        global Create
        global Cut
        global Copy
        global Paste
        global Save
        global Apply
        global Cancel
        global Edit_motion
        global Animation
        global Number_of_frames
        global Change_number_of_frames
        global Anybody_output
        global Import_images1
        global Import_images2
        global Import_images3
        global Import_images4
        button .editjm.frame.create -text $Create \
                              -command CreateNewMotion
        button .editjm.frame.cut    -text $Cut \
                              -command CutJointMotion
        button .editjm.frame.copy   -text $Copy \
                              -command CopyJointMotion
        button .editjm.frame.paste  -text $Paste \
                              -command PasteJointMotion
        button .editjm.frame.save   -text $Save \
                              -command "SaveJointMotion ; exit"
        button .editjm.frame.apply  -text $Apply \
                              -command "SaveJointMotion"
        button .editjm.frame.cancel -text $Cancel \
                              -command exit
                              # -command "wm withdraw .editjm"
        button .editjm.frame.edit   -text $Edit_motion \
                              -command EditEachMotion
        button .editjm.frame.animation -text $Animation \
                              -command OpenJointAnimation
        button .editjm.frame.importimages1 -text $Import_images1 \
                              -command { OpenImportImages 1 }
        button .editjm.frame.importimages2 -text $Import_images2 \
                              -command { OpenImportImages 2 }
        button .editjm.frame.importimages3 -text $Import_images3 \
                              -command { OpenImportImages 3 }
        button .editjm.frame.importimages4 -text $Import_images4 \
                              -command { OpenImportImages 4 }
        button .editjm.frame.anybody -text $Anybody_output \
                              -command StartAnybodyOutputSetting
        label .editjm.frame.num_frames -text $Number_of_frames
        button .editjm.frame.changeframe \
              -text $Change_number_of_frames -command AskNumFrames

        pack .editjm.frame.num_frames \
             .editjm.frame.changeframe \
                   -side top -fill x 
        pack .editjm.frame.create -side top -fill x -pady 15
        pack \
             .editjm.frame.cut \
             .editjm.frame.copy \
             .editjm.frame.paste \
                 -side top -fill x

        pack .editjm.frame.edit -side top -fill x -pady 15
        pack .editjm.frame.animation -side top -fill x -pady 10
        pack .editjm.frame.importimages1 -side top -fill x
        pack .editjm.frame.importimages2 -side top -fill x
        pack .editjm.frame.importimages3 -side top -fill x
        pack .editjm.frame.importimages4 -side top -fill x
        #pack .editjm.frame.anybody -side top -fill x -pady 20

        pack .editjm.frame.cancel -side bottom -fill x
        #pack .editjm.frame.apply  -side bottom -fill x -pady 5
        pack .editjm.frame.save   -side bottom -fill x -pady 5

        grid .editjm.frame -row 1 -column 0 -sticky ns -padx 2

        ChangeIcon .editjm

    } else {
        wm deiconify .editjm
    }
    # After making window, load data file
    LoadAndShowJointMotion
}

# Load data and show them
proc LoadAndShowJointMotion {} {
        global right_elevation
        global left_elevation
        global segm_name
        global axis_name
        set axis_name(0) ""
        set axis_name(1) "xb"
        set axis_name(2) "yb"
        set axis_name(3) "zb"
        set axis_name(4) xb$right_elevation
        set axis_name(5) yb$right_elevation
        set axis_name(6) zb$right_elevation
        set axis_name(7) xb$left_elevation
        set axis_name(8) yb$left_elevation
        set axis_name(9) zb$left_elevation

    if {[file exists joint_motion.dat]==1} {
        # judge whether AnyBody data are inluded or not
        set f [open joint_motion.dat r]    
        while {[gets $f line]>=0} {
            set lastline $line
        }
        close $f
        if {[llength $lastline]=="2"&&[string trim [lindex $lastline 0]]=="0"&&[string trim [lindex $lastline 1]]=="0"} {
            set any_yes "0"
        } else {
            set any_yes "1"
        }

        # open file and read first line (number of frames)
        set f [open joint_motion.dat r]    
        gets $f line
        global num_frames
        set num_frames [string trim $line]
        global Number_of_frames
        .editjm.frame.num_frames configure -text $Number_of_frames$num_frames

        # first, all clear
        .editjm.list delete 0 end

        # then solve text to be inserted (ins_text)
        set rot_num 1
        while {[gets $f line]>=0} {
            set segm_num [string trim [lindex $line 0]]
            set axis_num [string trim [lindex $line 1]]
            if {$segm_num=="0"} { break }

            # load each motion
            for {set i 1} {$i<=$num_frames} {incr i} {
                gets $f line
                set angle($segm_num,$axis_num,$i) [string trim $line]
            }

            # insert segment name and axis_name
            set ins_text1 "$segm_name($segm_num)  $axis_name($axis_num)"
            set ins_text2 ""
            # insert angles
            for {set i 1} {$i<=$num_frames} {incr i} {
                set blank "  "
                set ins_text2 \
                     $ins_text2$blank$angle($segm_num,$axis_num,$i)
            }
            #.editjm.list insert end $ins_text
            set ins_txt1($rot_num) $ins_text1
            set ins_txt2($rot_num) $ins_text2
            incr rot_num
        }

        # 
        if {$any_yes=="1"} {
            # load additional lines
            for {set i 1} {$i<=[expr $rot_num -1]} {incr i} {
                gets $f line
                if {[string trim $line]=="1"} {
                    .editjm.list insert end \
                        "Y  $ins_txt1($i)  $ins_txt2($i)"
                } elseif {[string trim $line]=="0"} {
                    .editjm.list insert end \
                        "N  $ins_txt1($i)  $ins_txt2($i)"
                } else {
                    break
                }
            }

        } else {
            # set all lines as "Y"
            for {set i 1} {$i<=[expr $rot_num -1]} {incr i} {
                .editjm.list insert end \
                      "Y  $ins_txt1($i)  $ins_txt2($i)"
            }
        }
        close $f

    } else {
    # No joint motion case

        # clear lines
        .editjm.list delete 0 end
        
        global num_frames
        global Number_of_frames
        set num_frames ""
        .editjm.frame.num_frames configure \
                       -text $Number_of_frames$num_frames

        # popup warning window
        global No_joint_motion_file
        global At_least_number_frames
        tk_messageBox -type ok \
           -message "$No_joint_motion_file $At_least_number_frames" \
                      -icon warning

        # ask frame number
        if { [winfo exists .askfm ]==0 } {
            set num_frames ""
            toplevel .askfm 
            wm title .askfm  "Swumsuit:"
            entry .askfm.entry -textvariable num_frames
            label .askfm.label -text "$Number_of_frames :"
            global OK
            button .askfm.ok -text $OK -command AskfmOK 

            grid .askfm.label -row 0 -column 0
            grid .askfm.entry -row 0 -column 1
            grid .askfm.ok    -row 1 -column 0 -columnspan 2 -pady 5

            bind .askfm <Key-Return> AskfmOK
            ChangeIcon .askfm

        } else {
            wm deiconify .askfm
        }
    }
}

proc AskfmOK {} {
    global Number_of_frames
    global num_frames
    .editjm.frame.num_frames configure \
        -text $Number_of_frames$num_frames 
    wm withdraw .askfm
}

# Create new motion
proc CreateNewMotion {} {
        if { [winfo exists .createnm ]==0 } {
            toplevel .createnm
            wm title .createnm "Swumsuit:"

            global segm_name

            frame .createnm.askbs
            listbox .createnm.askbs.c \
                      -yscrollcommand ".createnm.askbs.s set" \
                      -exportselection false
            scrollbar .createnm.askbs.s \
                      -command ".createnm.askbs.c yview"
            for {set j 1} {$j<=21} {incr j} {
                .createnm.askbs.c insert end $segm_name($j)
            }
            .createnm.askbs.c selection set 0
            global Body_segment
            label .createnm.askbs.l -text "$Body_segment :"
            pack .createnm.askbs.l -side left
            pack .createnm.askbs.c -side left
            pack .createnm.askbs.s -side left -fill y


            global right_elevation
            global left_elevation
            global ax_list
            set ax_list "xb yb zb xb$right_elevation yb$right_elevation zb$right_elevation xb$left_elevation yb$left_elevation zb$left_elevation"

            frame .createnm.askax
            #ComboBox .createnm.askax.c -values $ax_list
            #.createnm.askax.c setvalue first
            listbox .createnm.askax.c -height 9 \
                      -exportselection false
            foreach e $ax_list {
                .createnm.askax.c insert end $e
            }
            .createnm.askax.c selection set 0
            global Rotation_axis
            label .createnm.askax.l -text "$Rotation_axis :"
            pack .createnm.askax.l -side left
            pack .createnm.askax.c -side left

            global OK Cancel
            frame  .createnm.okcan
            button .createnm.okcan.ok -text $OK -command CreatenmOK 
            button .createnm.okcan.cancel -text $Cancel \
                                    -command "wm withdraw .createnm"
            pack .createnm.okcan.ok .createnm.okcan.cancel \
                     -side left

            pack .createnm.askbs .createnm.askax -side top -fill x
            pack .createnm.okcan -side top -pady 5

            ChangeIcon .createnm

        } else {
            wm deiconify .createnm
        }
}

proc CreatenmOK {} {
    global num_frames
    set bs_var [.createnm.askbs.c get [.createnm.askbs.c curselection]]
    set ax_var [.createnm.askax.c get [.createnm.askax.c curselection]]
    #set ins_text "$bs_var  $ax_var"
    set ins_text "Y  $bs_var  $ax_var"
    for {set i 1} {$i<=$num_frames} {incr i} {
        set ins_text "$ins_text   0."
    }
    set active [.editjm.list index active]
    set active1 [expr 1+$active]
    .editjm.list insert $active1 $ins_text
    wm withdraw .createnm
    # reset selection
    .editjm.list selection set $active $active

    StoreJointMotion
}

# Cut
proc CutJointMotion {} {
    global sel_list
    global sel_num_m1
    global sel_line
    # first, store selected lines
    set sel_list [.editjm.list curselection ]
    set sel_num [llength $sel_list]
    set sel_num_m1 [expr $sel_num -1]
    for {set i 0} {$i<=$sel_num_m1} {incr i} {
        set sel_line($i) [.editjm.list get [lindex $sel_list $i]]
    }
    # next, cut the lines
    set offset 0
    for {set i $sel_num_m1} {$i>=0} {incr i -1} {
        .editjm.list delete [expr [lindex $sel_list $i]]
    }
    # clear selection
    .editjm.list selection clear 0 end

    StoreJointMotion
}

# Copy
proc CopyJointMotion {} {
    global sel_list
    global sel_num_m1
    global sel_line
    set sel_list [.editjm.list curselection ]
    set sel_num [llength $sel_list]
    set sel_num_m1 [expr $sel_num -1]
    for {set i 0} {$i<=$sel_num_m1} {incr i} {
        set sel_line($i) [.editjm.list get [lindex $sel_list $i]]
    }
}

# Paste
proc PasteJointMotion {} {
    global sel_list
    global sel_num_m1
    global sel_line
    set active [.editjm.list index active]
    set active1 [expr 1+$active]
    for {set i 0} {$i<=$sel_num_m1} {incr i} {
        .editjm.list insert $active1 $sel_line($i) 
        set active1 [expr 1+$active1]
    }
    # reset selection
    #.editjm.list selection set $active $active
    StoreJointMotion
}

# Save
proc SaveJointMotion {} {
    # first, get number of lines
    set num_line [.editjm.list index end]
    # next, read line one by one
    for {set i 0} {$i<=[expr $num_line -1]} {incr i} {
        set line [.editjm.list get $i]
        set num_element [llength $line]
        for {set j 0} {$j<=[expr $num_element -1]} {incr j} {
            set element($i,$j) [lindex $line $j]
            # trimming
            set element($i,$j) [string trim $element($i,$j)]
            # trim "Local_blank", too
            global Local_blank
            set element($i,$j) [string trim $element($i,$j) $Local_blank]
        }
    }

    # save
    set f [open joint_motion.dat w]    
    fconfigure $f -translation lf
    #puts $f " [expr $num_element -2]"
    puts $f " [expr $num_element -3]"
    for {set i 0} {$i<=[expr $num_line -1]} {incr i} {

        # find appropriate Anybody setting
        if {$element($i,0)=="Y"} {
            set any_num($i) 1
        } else {
            set any_num($i) 0
        }

        # find appropriate segment number
        global segm_name
        for {set j 1} {$j<=21} {incr j} {
            set trim_name [string trim $segm_name($j) $Local_blank]
            if {$trim_name==$element($i,1)} {
                set segm_num $j
            }
        }

        # find appropriate rotation axis
        global axis_name
        for {set j 1} {$j<=9} {incr j} {
            if {$axis_name($j)==$element($i,2)} {
                set axis_num $j
            }
        }

        # write segment number and axis number
        puts $f " $segm_num $axis_num"

        # write angles
        for {set j 3} {$j<=[expr $num_element -1]} {incr j} {
            set ins_text [string trim $element($i,$j)]
            if {[string index $ins_text 0]=="-" } {
                puts $f " $ins_text"
            } else {
                puts $f "  $ins_text"
            }
        }
    }
    puts $f "0 0"

    # write Anybody setting
    for {set i 0} {$i<=[expr $num_line -1]} {incr i} {
        puts $f $any_num($i)
    }

    close $f
    #wm withdraw .editjm
    #exit

    # Save display data for import images
    SaveDisplayData
}


# Ask number of frames for change 
proc AskNumFrames { } {
    global Number_of_frames OK Cancel
    global num_frames num_frames_new
    set num_frames_new $num_frames

    if { [winfo exists .askcfm ]==0 } {
        toplevel .askcfm 
        wm title .askcfm  "Swumsuit:"
        entry .askcfm.entry -textvariable num_frames_new
        label .askcfm.label -text "$Number_of_frames :"
        global OK
        button .askcfm.ok -text $OK -command ChangeNumFrames
        button .askcfm.cancel -text $Cancel \
                              -command "wm withdraw .askcfm"
        grid .askcfm.label  -row 0 -column 0
        grid .askcfm.entry  -row 0 -column 1
        grid .askcfm.ok     -row 1 -column 0 -columnspan 1 -pady 5
        grid .askcfm.cancel -row 1 -column 1 -columnspan 1 -pady 5

        #bind .askcfm <Key-Return> ChangeNumFrames
        ChangeIcon .askcfm

    } else {
        wm deiconify .askcfm
    }
}



# Change number of frames
proc ChangeNumFrames { } {
    global OS Platform sourcedir num_frames num_frames_new

    if {$OS=="Linux"} {
        set CONVBIN  "SWUM_FRAMECONV_LINUX"
        set CONVEXEC "exec echo $num_frames_new | ./$CONVBIN"
    } elseif {$OS=="Darwin"} {
        set CONVBIN  "SWUM_FRAMECONV_MAC"
        set CONVEXEC "exec echo $num_frames_new | ./$CONVBIN"
    } else {
        set CONVBIN  "SWUM_FRAMECONV_WINDOWS.EXE"
        set CONVEXEC "exec cmd.exe /c echo $num_frames_new | $CONVBIN"
    }
    file copy -force $sourcedir/$CONVBIN $CONVBIN
    file copy -force joint_motion.dat joint_motion_org.dat

    # Obtain and save Anybody information
    set line_num [.editjm.list index end]
    for {set i 0} {$i<=[expr $line_num -1]} {incr i} {
        set line [.editjm.list get $i]
        set a [string range $line 0 0]
        if {$a=="Y" } {
            set any_info($i) 1
        } else {
            set any_info($i) 0
        }
    }

    SaveJointMotion

    update
    eval $CONVEXEC
    update
    file copy -force joint_motion_converted.dat joint_motion.dat

    # append anybody information
    set f [open joint_motion.dat a]
    #fconfigure $f -translation lf
    for {set i 0} {$i<=[expr $line_num -1]} {incr i} {
        puts $f $any_info($i)
    }
    close $f

    LoadAndShowJointMotion

    # restore original data file
    file copy -force joint_motion_org.dat joint_motion.dat

    file delete $CONVBIN
    wm withdraw .askcfm
}


# Start Anybody output setting
proc StartAnybodyOutputSetting { } {
    global anybody_setting_mode
    if {$anybody_setting_mode=="0"} {

        global Anybody_setting_ok
        set a [tk_messageBox -type okcancel -default ok \
                      -message $Anybody_setting_ok]
        if {$a=="cancel"} { return }

        .editjm.frame.anybody configure -relief sunken
        .editjm.frame.create configure -state disabled
        .editjm.frame.cut    configure -state disabled
        .editjm.frame.copy   configure -state disabled
        .editjm.frame.paste  configure -state disabled
        
        # Load setting information
        .editjm.list selection set 0 end

        .editjm.list configure -selectmode multiple
        set anybody_setting_mode "1"
    } else {
        .editjm.frame.anybody configure -relief raised
        .editjm.frame.create configure -state normal
        .editjm.frame.cut    configure -state normal
        .editjm.frame.copy   configure -state normal
        .editjm.frame.paste  configure -state normal
        .editjm.list configure -selectmode extended
        
        set anybody_setting_mode "0"
    }
}


# Reset anybody setting mode
proc ResetAnybodySettingMode { } {
    global anybody_setting_mode
    set anybody_setting_mode "0"
    .editjm.frame.anybody configure -relief raised
    .editjm.frame.create configure -state normal
    .editjm.frame.cut    configure -state normal
    .editjm.frame.copy   configure -state normal
    .editjm.frame.paste  configure -state normal
}


# Change icon
proc ChangeIcon { w } {
    global Platform sourcedir
    if {$Platform=="windows"} {
        update
        wm iconbitmap $w $sourcedir/icon_small.ico
    }
}


# Get sourcedir & dname from arguments
set sourcedir [lindex $argv 0]
set dname     [lindex $argv 1]
set Locale    [lindex $argv 2]
cd $dname

# Set environment
source $sourcedir/set_environment.tcl
# Set default font
source $sourcedir/set_default_font.tcl
# Load other sources
source $sourcedir/load_catalog.tcl
source $sourcedir/edit_each_motion.tcl
source $sourcedir/animate_joint_motion.tcl
source $sourcedir/import_images.tcl

# Load Togl(OpenGL) library
load $sourcedir/animate_joint_motion[info sharedlibextension]

# Load Img packages
load $sourcedir/Img/jpegtcl10[info sharedlibextension]
load $sourcedir/Img/zlibtcl10[info sharedlibextension]
load $sourcedir/Img/pngtcl10[info sharedlibextension]
load $sourcedir/Img/tifftcl10[info sharedlibextension]
load $sourcedir/Img/tkimg13[info sharedlibextension]
load $sourcedir/Img/tkimgbmp13[info sharedlibextension]
load $sourcedir/Img/tkimggif13[info sharedlibextension]
load $sourcedir/Img/tkimgico13[info sharedlibextension]
load $sourcedir/Img/tkimgjpeg13[info sharedlibextension]
load $sourcedir/Img/tkimgpcx13[info sharedlibextension]
load $sourcedir/Img/tkimgpixmap13[info sharedlibextension]
load $sourcedir/Img/tkimgpng13[info sharedlibextension]
load $sourcedir/Img/tkimgppm13[info sharedlibextension]
load $sourcedir/Img/tkimgps13[info sharedlibextension]
load $sourcedir/Img/tkimgsgi13[info sharedlibextension]
load $sourcedir/Img/tkimgsun13[info sharedlibextension]
load $sourcedir/Img/tkimgtga13[info sharedlibextension]
load $sourcedir/Img/tkimgtiff13[info sharedlibextension]
load $sourcedir/Img/tkimgwindow13[info sharedlibextension]
load $sourcedir/Img/tkimgxbm13[info sharedlibextension]
load $sourcedir/Img/tkimgxpm13[info sharedlibextension]

# Load BLT package
package require BLT
catch { namespace import blt::* }

# Setup start
wm withdraw .
EditJointMotion

# Reset anybody setting mode
ResetAnybodySettingMode

