# This code creates the user interface for the mesh editor.
#
# Copyright (c) 1997 Pacific Marketing and Consulting, Inc,
#       and ICEM Systems, GmbH.  All rights reserved.
# Author:  Wayne A. Christopher, wayne@icemcfd.com

proc ddn_tetin_to_iparta {} {
    set tf [med_file_select tetin 0 "" convert]
    if {$tf == ""} return
    set part [lindex [ddn_select_part both 0] 2]
    if {$part == ""} return
    ic_trans_tetin_ddn $tf $part
}

proc ddn_copymove_part {copy} {
    global file_name
    
    set part [ddn_select_part both 1]
    if {$part == ""} return
    set dir [lindex $part 0]
    set selected [lindex $part 1]
    set filename [lindex $part 2]
    
    set newdir ""
    if {($dir == "parts") || ($dir == "./parts")} {
	set newdir $file_name(parts_dir)
    } else {
	set newdir parts
    }
    if $copy { set word Copy } else { set word Move }
    if [tk_dialog .delete $word \
	    "$word $selected from $dir to $newdir?" \
	    "" -1 "Yes" "No" ] return
    
    set newfile $newdir/[file tail $filename ]
    if ![file exists ./parts] { ic_mkdir ./parts }
    if $copy {
	ic_cp $filename $newfile
    } else {
	ic_mv $filename $newfile
    }
    ddn_list_parts $newdir 1
    ddn_list_parts $dir 1
    mess "Done.\n"
}

proc ddn_copy_part {} {
    global copy_part_newname
    
    set part [ddn_select_part both 1]
    if {$part == ""} return
    set dir [lindex $part 0]
    set selected [lindex $part 1]
    set file [lindex $part 2]
    
    set copy_part_newname [question "Copy part $selected to:"]
    if {$copy_part_newname == ""} return
    set copy_part_newname [string toupper $copy_part_newname]
    
    # First copy the current file and then rename the original one...
    for {set i 1} 1 {incr i} {
	if ![file exists $file.$i] break
    }
    ic_cp $file $file.$i
    
    set ddndir [get_program bin ddndir]
    exec $ddndir -rename $dir $selected $copy_part_newname
    exec $ddndir -w $dir
    mess "Done.\n"
    
    #ddn_run copy_part $selected $dir
}
proc ddn_rename_part {} {
    global copy_part_newname

    set part [ddn_select_part both 1]
    if {$part == ""} return
    set dir [lindex $part 0]
    set selected [lindex $part 1]
    
    set copy_part_newname [question "Rename part $selected to:"]
    if {$copy_part_newname == ""} return
    set copy_part_newname [string toupper $copy_part_newname]
    
    set ddndir [get_program bin ddndir]
    exec $ddndir -rename $dir $selected $copy_part_newname
    exec $ddndir -w $dir
    mess "Done.\n"
    
    #ddn_run copy_part $selected $dir
    #ddn_delete_part_int $dir $selected
}

# ---------------------------------------------

proc ddn_delete_part {} {
    global ddn_part_selected_sheetnumber
    set part [ddn_select_part both 1]
    if {$part != ""} {
	if [tk_dialog .delete "Delete" \
		"Delete [lindex $part 1] \
		\($ddn_part_selected_sheetnumber\)\
		\nin directory [lindex $part 0]?" \
		"" -1 "Yes" "No" ] return
	ddn_delete_part_int [lindex $part 0] [lindex $part 1]
    }
}

proc ddn_delete_part_int {dir name} {
    set file [ddn_get_partfile $dir $name]
    if {$file == ""} { error "No part named $name exists in $dir" }
    
    ic_rm $file
    # update the part list
    ddn_list_parts $dir 1
    mess "Done.\n"
}

proc ddn_get_partfile {dir name} {
    global ddn_part_selected_sheetnumber
    set list [ddn_list_parts $dir 1]
    set filename ""
    foreach i $list {
	if {[lindex $i 0] == $name} {
	    if {[lindex $i 2] == $ddn_part_selected_sheetnumber} {
	        return [lindex $i 1]
	   }
	}
    }
    return ""
}


proc ddn_select_part {which exists} {
    global file_name parts_dir_local
    
    return [ddn_select_part_full $which $exists]
    
    switch $which {
	both {
	    if [file exists ./parts] {
		set parts_dir_local [tk_dialog .wpd Select \
					 "Select part from project directory\
					($file_name(parts_dir)) or ./parts?" \
					 "" -1 "project dir" "./parts"]
	    } else {
		set parts_dir_local 0
	    }
	}
	local {
	    set parts_dir_local 1
	}
	project {
	    set parts_dir_local 0
	}
    }   
    
    if $parts_dir_local {
	set dir ./parts
    } else {
	set dir $file_name(parts_dir)
    }
    if ![file exists $dir] { cmd_mkdir $dir }
    set partname [ddn_pick_part $dir $parts_dir_local $exists]
    if {$partname == ""} { return "" }
    set file [ddn_get_partfile $dir $partname]
    if {$file == ""} {
	if $exists {
	    error "You must select an existing part"
	} else {
	    set file $dir/$partname
	}
    }
    return [list $dir $partname $file]
}

proc ddn_run {what {partname ""} {dir ""} {extra_cmds ""} {batchddn 0} {do_after 1}} {
    global file_name env use_xwindows ddn_options parts_dir_local
    
    if [info exists env(ICEM_DDN_DIR)] {
	set env(ICEM_ACN_OLD) $env(ICEM_ACN)
	set env(ICEM_ACN) $env(ICEM_DDN_DIR)
    }	

    if {$partname == ""} {
	set stuff [ddn_select_part both 0]
	if {$stuff == ""} return
	set dir [lindex $stuff 0]
	set partname [lindex $stuff 1]
    }
    
    if {$dir == ""} {
	if $parts_dir_local {
	    set dir ./parts
	} else {
	    set dir $file_name(parts_dir)
	}
    }
    
    set restart ""
    if {$what != "ddn"} {
	set restart [ddn_app_before_$what $dir $partname]
    }
    set restart [concat $restart $extra_cmds]
    
    set tt tt
    if $use_xwindows { set tt tt=xterm }
    #if $batchddn { set tt tt=none }
    
    set cmdargs "db=$dir [ddn_options $tt]"
    set pn "pn=[ddn_partname $partname]"
    
    set rstfile ""
    if {$restart != ""} {
	set rstfile [cmd_tempfile ddncmds .tmp]
	set fp [open $rstfile w]
	foreach r $restart { puts $fp $r }
	close $fp
	append cmdargs " i=$rstfile"
    }
    
    # This is a big hack.
    if ![info exists env(LD_LIBRARY_PATH)] {
	set env(LD_LIBRARY_PATH) $env(ICEM_ACN)/ddn/shared_lib
    } else {
	set oenv $env(LD_LIBRARY_PATH)
	append env(LD_LIBRARY_PATH) :$env(ICEM_ACN)/ddn/shared_lib
    }
    #set env(ICEM_NOLOCK) y -- problems on sun
    set env(ICEM_NO_FOLDER) 1
    set env(ICEM_NO_SPACE_CHECK) 1
    set env(ICEM_CASE_SENSITIVE) 1
    
    ic_run_application_command . bin icemddn "$cmdargs \"$pn\""

    if [info exists oenv] {
	set env(LD_LIBRARY_PATH) $oenv
    } else {
	unset env(LD_LIBRARY_PATH)
    }
    if {($what != "ddn") && $do_after} {
	ddn_app_after_$what $dir $partname
    }
    if {$rstfile != ""} {
	ic_rm $rstfile
    }

    if [info exists env(ICEM_ACN_OLD)] {
	set env(ICEM_ACN) $env(ICEM_ACN_OLD)
    } 
}

proc ddn_options {{tt ""} {hd 1}} {
    global use_xwindows options ddn_options ddn_part_selected_sheetnumber
    
    array set optnames {
	ds,ANSI-82 a82
	ds,DIN d
	ds,a82 a82
	ds,din din
	pf,Ascii a
	pf,Binary b
	pf,ASCII a
	pf,BINARY b
	pf,a a
	pf,b b
	um,English e
	um,Metric m
	um,e e
	um,m m
    }
    
    set tt tt
    if $use_xwindows { set tt tt=xterm }
    
    if {$ddn_part_selected_sheetnumber == ""} {
        set ddn_part_selected_sheetnumber 1
    }    
    return "sn=$ddn_part_selected_sheetnumber dbms=no lf=yes hd=y \
	um=$optnames(um,$ddn_options(um)) \
	ds=$optnames(ds,$ddn_options(ds)) pf=$optnames(pf,$ddn_options(pf)) \
	$tt"
}

proc ddn_pick_part {dir islocal exists} {
    global part_selected
    
    set pts ""
    foreach pp [ddn_list_parts $dir 1] {
	lappend pts [lindex $pp 0]
    }
    if ![lmember $pts $part_selected] { set part_selected "" }
    
    if $islocal {
	set place ./parts
    } else {
	set place PROJECT_DIR/parts
    }
    if $exists {
	set mess "Select a part from $place."
    } else {
	set mess "Select a part from $place\nor enter a new name."
    }
    set p [choose_one $mess $pts $part_selected]
    if {$p != ""} { set part_selected $p }
    return $p
}

proc ddn_list_parts {dir update} {
    global env
    
    set stuff [ic_list_ddn_parts $dir $update]
    
    set warns [lindex $stuff 2]
    if {$warns != ""} {
	mess "$warns\n" red
    }
    
    set parts ""
    foreach ent [lindex $stuff 1] {
	foreach line $ent {
	    set fpos [string first \" $line]
            set lpos [string last \" $line]
            set fpos [expr $fpos + 1]
            set lpos [expr $lpos - 1]
            if {$lpos > $fpos} {
                  set arg [string trimright [string range $line $fpos $lpos]]
            }
	    regsub -all {\\} $line {\\\\} line
	    regsub -all {\"} $line {\\\"} line
	    switch [lindex $line 0] {
		type  { set type [lindex $line 1] }
		name  { set name $arg }
		sheet { set sheet [lindex $line 1] }
		file  { set file $arg }
	    }
	}
	if {$type != 1} continue
	lappend parts [list $name $dir/$file $sheet]
    }
    return [lsort $parts]
}

proc ddn_partname {pn} {
    global is_win
    
    if $is_win {
	set a [regsub -all " " $pn _ pn]
	set b [regsub -all "\t" $pn _ pn]
	if {$a || $b} {
	    mess "Warning: on windows DDN part names can't have spaces.\n" red
	}
	return $pn
    } else {
	return $pn
    }
}

# ------------------------------------------------

proc ddn_select_part_full {which exists} {
    global file_name parts_dir_local part_selected
    global ddn_part_selected_local ddn_part_selected_project
    global ddn_part_selected_sheetnumber
    
    set d [form_init .select_ddn_part_$which "Select ddn part" file \
	      "accept cancel"]
    if {$d != ""} {
	set applist list
	if {(($which == "local") || ($which == "both")) && \
		[file exists ./parts]} {
	    form_listbox $d.local "Parts in\n./parts" "" \
		"ddn_select_part_full_set $d local" \
		"form_accept_hack .select_ddn_part_$which; list" \
		{20x10} {1 0 -cols 2}
	    form_label $d.locall "Part:" {2 0}
	    form_entry $d.locale ddn_part_selected_local "" {2 1}
	    $d.locale configure -width 15
	    set mgeo "0 0 -cols 2"
	}
	if {($which == "project") || ($which == "both")} {
	    form_listbox $d.project "Parts in\nPROJECT_DIR/parts" "" \
		"ddn_select_part_full_set $d project" \
		"form_accept_hack .select_ddn_part_$which; list" \
		{20x10} {1 2 -cols 2}
	    form_label $d.projectl "Part:" {2 2}
	    form_entry $d.projecte ddn_part_selected_project "" {2 3}
	    $d.projecte configure -width 15
	    set mgeo "0 2 -cols 2"
	}
	if {$which == "both"} {
	    set mgeo "0 0 -cols 4"
	    set applist "appropriate list"
	}
	form_label $d.lab "Select a part from the $applist or\nenter\
		a new part name below." $mgeo
	
	form_finish +300+300
    }
    
    set ddn_part_selected_local ""
    set ddn_part_selected_project ""
    set ddn_part_selected_sheetnumber ""
        
    if [winfo exists .select_ddn_part_$which.main.local] {
	set pts_l ""
	if [file exists ./parts] {
	    foreach pp [ddn_list_parts ./parts 1] {
		lappend pts_l "[lindex $pp 0] \([lindex $pp 2]\)"
	    }
	}
	form_listbox_set .select_ddn_part_$which.main.local $pts_l
    }
    if [winfo exists .select_ddn_part_$which.main.project] {
	set pts_p ""
	if [file exists $file_name(parts_dir)] {
	    foreach pp [ddn_list_parts $file_name(parts_dir) 1] {
		lappend pts_p "[lindex $pp 0] \([lindex $pp 2]\)"
	    }
	}
	form_listbox_set .select_ddn_part_$which.main.project $pts_p
    }
    
    if ![form_wait .select_ddn_part_$which] { return "" }
    
    if {$ddn_part_selected_local != ""} {
	set dir ./parts
	set partname $ddn_part_selected_local
	set parts_dir_local 1
    } elseif {$ddn_part_selected_project != ""} {
	set dir $file_name(parts_dir)
	set partname $ddn_part_selected_project
	set parts_dir_local 0
    } else {
	return ""
    }
    
    set part_selected $partname
    
    if ![file exists $dir] { cmd_mkdir $dir }
    set file [ddn_get_partfile $dir $partname]
    if {$file == ""} {
	if $exists {
	    error "You must select an existing part"
	} else {
	    set file $dir/$partname
	}
    }
    return [list $dir $partname $file]
}

proc ddn_select_part_full_set {d which name} {
    global ddn_part_selected_local ddn_part_selected_project
    global ddn_part_selected_sheetnumber
    
    switch $which {
	local {
	    set snum [lindex $name end]
	    regsub -all {\(} $snum "" snum
	    regsub -all {\)} $snum "" snum
	    set ddn_part_selected_sheetnumber $snum
	    regsub -all " \{\}" [lreplace $name end end ""] "" name
	    set ddn_part_selected_local $name
	    set ddn_part_selected_project ""
	    if [winfo exists $d.project] {
		form_listbox_select $d.project ""
	    }
	}
	project {
	    set snum [lindex $name end]
	    regsub -all {\(} $snum "" snum
	    regsub -all {\)} $snum "" snum
	    set ddn_part_selected_sheetnumber $snum
	    regsub -all " \{\}" [lreplace $name end end ""] "" name
	    set ddn_part_selected_project $name
	    set ddn_part_selected_local ""
	    if [winfo exists $d.local] {
		form_listbox_select $d.local ""
	    }
	}
    }
}

# ------------------------------------------------

proc ddn_app_before_mif {parts partname} {
    global file_name ddn_options env
    
    array set optnames {
	Hexa 1 Tetra 2 Global 3 hexa 1 tetra 2 global 3 1 1 2 2 3 3 
    }
    
    set rst ""
    lappend rst F.5.13.5.6
    lappend rst $env(ICEM_ACN)/common/gpl
    lappend rst F.5.13.7.tetra
    lappend rst $file_name(mesh_dir)
    lappend rst $optnames($ddn_options(mif_license))
    return $rst
}

proc ddn_app_after_mif {parts partname} {
    global file_name
    
    set ff [newest_file_in_dir $file_name(mesh_dir) *.tin]
    if {$ff != ""} {
        if {$file_name(tetin) != ""} { set home 0 } else { set home 1 }
        ic_load_tetin [list $ff]
        if $home { tdv_home .v.view }
    }
}

# ------------------------------------------------

proc ddn_run_mulcad {} {
    global file_name
    
    set pp [file split $file_name(project_dir)]
    set mulc [lindex $pp [expr [llength $pp] - 3]]
    if {$mulc != "mulcad"} {
	error "You can only run mulcad if the project directory is old-style, i.e. mulcad/configname/geoname"
    }
    ddn_run mulcad
}

proc ddn_app_before_mulcad {parts partname} {
    global file_name ddn_options env
    
    set pp [file split $file_name(project_dir)]
    set confname [lindex $pp [expr [llength $pp] - 2]]
    set geoname [lindex $pp [expr [llength $pp] - 1]]

    set rst ""
    lappend rst y
    lappend rst F.1.16.4
    lappend rst $env(ICEM_ACN)/common/tfile_mulcad]
    lappend rst 3.LOWER
    lappend rst F.5.13.5.6
    lappend rst $env(ICEM_ACN)/common/gpl
    lappend rst F
    lappend rst F.5.13.7.MULCAD
    lappend rst $confname
    lappend rst $geoname
    return $rst
}

proc ddn_app_after_mulcad {parts partname} {
    global file_name
    
    file_unload domain
    
    mess "Loading multiblock mesh in $file_name(project_dir) ...\n"
    
    file_do_load_domain $file_name(project_dir)/domains/Multiblock \
	$file_name(project_dir)/mesh/topo_mulcad_out "" \
	$file_name(project_dir)/mesh/subface_proj
}

proc mulcad_cleanup {} {
    global file_name gui_name
    if {$file_name(transfer_dir) == ""} {
	errormsg "$gui_name(Conf) or $gui_name(geo) is undefined"
	return
    }
    eval ic_rm $file_name(transfer_dir)/{tape*,I*,G*,T*}
}

# ------------------------------------------------

proc ddn_app_before_comak {parts partname} {
    global file_name ddn_options env
    
    set pp [file split $file_name(project_dir)]
    set mulc [lindex $pp [expr [llength $pp] - 3]]
    set confname [lindex $pp [expr [llength $pp] - 2]]
    set geoname [lindex $pp [expr [llength $pp] - 1]]
    if {$mulc != "mulcad"} {
	error "You can only run comak if the project directory is old-style, i.e. mulcad/configname/geoname"
    }
    
    set rst ""
    lappend rst y
    lappend rst F.1.16.4
    lappend rst $env(ICEM_ACN)/common/tfile_comak]
    lappend rst 3.LOWER
    lappend rst F.5.13.5.6
    lappend rst $env(ICEM_ACN)/common/gpl
    lappend rst F
    lappend rst F.5.13.7.COMAK
    lappend rst $confname
    lappend rst $geoname
    return $rst
}

proc ddn_app_after_comak {parts partname} {
    global file_name
    
    file_unload domain
    
    mess "Loading multiblock mesh in $file_name(project_dir) ...\n"
    file_do_load_domain $file_name(project_dir)/domains/Multiblock \
	$file_name(project_dir)/mesh/topo_mulcad_out "" \
	$file_name(project_dir)/mesh/subface_proj
}

# --------

proc ddn_app_before_frontal {parts partname} {
    global file_name ddn_options env
    
    set rst ""
    lappend rst F.5.13.5.6
    lappend rst $env(ICEM_ACN)/common/gpl
    lappend rst F.5.13.7.frontg
    return $rst
}

proc ddn_app_after_frontal {parts partname} {
}

# --------

proc ddn_app_before_input {parts partname} {
    global file_name ddn_options env
    
    set rst ""
    lappend rst F.5.13.5.6
    lappend rst $env(ICEM_ACN)/common/gpl
    lappend rst F.5.13.7.inputg
    return $rst
}

proc ddn_app_after_input {parts partname} {
}

# --------------------------

proc update_partlist {which callup} {
    global file_name
    if [file exists ./parts] {ddn_list_parts ./parts 1}
    ddn_list_parts $file_name(parts_dir) 1
}

proc nice_partname {} {
    global part_selected
    if {$part_selected == ""} {return anonymous_part}
    set pn $part_selected
    regsub -all " |\t" $pn _ pn
    regsub -all {\\} $pn {\\\\} pn
    return [string tolower $pn]
}

proc partfile_is_binary {name} {
    set fd [open $name]
    set line [read $fd 80]
    close $fd
    if {([string first "\n" $line] >= 0) && ([string first "\0" $line] == -1)} {
	return 0
    } {
	return 1
    }
}
