#!/bin/sh
# \
exec wish -f "$0"

# This is the graphical front-end to plotfoil, the airfoil plotting program.
# It requires tcl-7.4 and tk-4.0 to have been installed on your system.
# Tcl/tk runs on Unix/X11 systems and MS Windows and is available free from
# a variety of sites (source code):
#     ftp://ftp.sunlabs.com/pub/tcl/
#     ftp://ftp.cs.berkeley.edu/ucb/tcl
#     ftp://ftp.x.org/contrib
#     ftp://ftp.uu.net/languages/tcl
#     ftp://harbor.ecn.purdue.edu/pub/tcl
#     ftp://ftp.ibp.fr/pub/tcl
#     ftp://syd.dit.csiro.au/pub/tk
#     ftp://ftp2.fujixerox.co.jp/pub/tcl
#
# tcl/tk is available as a pre-compiled release for MS-Windows systems; get
#     ftp://ftp.sunlabs.com/pub/tcl/win42b1.exe (a self-extracting archive)
#
# PC users: have you considered Linux? Linux is a completely free
# implementation of Unix for intel, amiga and alpha platforms. It comes with
# compilers, X11, TeX, and all sorts of goodies. And all the source code is
# included! Send me email if you want more information.
#
# This program also uses ghostview, available from ftp.cs.wisc.edu
#
# Copyright 1996 Shamim Mohamed
# spm@crl.com May 1996
#
# This file is distributed under the Gnu Public License Version 2
# A copy of the Gnu Public License (herinafter referred to as the GPL)
# is in the file COPYING that should have been in the same place you
# got this from.
#
# Briefly, the GPL says that you may freely distribute this file, and
# you can even charge money for it. However, you cannot prevent those people
# from further redistributing it. Furthermore, if you make any modifications
# to this file and redistribute the modified version, the same conditions
# apply to the modified version.
#
# INSTALLATION INSTRUCTIONS
#
# Edit the "configuration section" - just make sure that the locations of
# plotfoil, ghostview, lpr and the airfoil directory are set right. And
# that's it!

########################################################################
# Configuration Section
########################################################################

# Set this to the location of the plotfoil executables lives in
set plotfoil "/u/shamim/plotfoil"

# Where are the airfoil data?
set airfoils "/u/shamim/plotfoil/coord"

# Where's ghostview (for preview)
set ghostview "ghostview"

# How do I print?
set lpr "lpr"

########################################################################
# End of Configuration Section
########################################################################
#


if ![string match 4.* $tk_version] {
  puts "\nWarning: old tk version ($tk_version). Please update to 4.*\n"
  exit
}

# defaults
set units "m"
set papersize "letter"
set chord 200
set useSheetingAllowance 0
set sheetingAllowance ""
set sectionFileName "$airfoils/"
set sparCount 0
set thickness(0) ""
set positions(0) 0
set usexoffset 0
set useyoffset 0
set xoffset ""
set yoffset ""
set useangle 0
set angle ""
set usetemplate 0
set templateH ""
set templateT ""
set templateL ""

set modCamber 0
set modThickness 0
set camber ""
set thick ""

set useNaca 0
set naca ""

########################################################################
# Filename widgets
#

proc browserHandler {widget wName variable} {
    global browserD browserP $variable
    eval set name [selection get]
    set browserP($wName) $browserD($wName)/$name
    if [file isdirectory $browserD($wName)/$name] {
	set browserD($wName) [string trimright $browserP($wName) /]
	fillFileList $widget.files $browserP($wName)
    }
    set $variable $browserP($wName)
}

proc browser {widget variable dir} {
    set wName $widget
    global browserD browserP $variable
    set browserD($wName) $dir
    set browserP($wName) $browserD($wName)/
    
    listbox $widget.files -relief flat \
	-yscrollcommand "$widget.scroll set" -width 30
    scrollbar $widget.scroll -command "$widget.files yview"
    fillFileList $widget.files $browserD($wName)
    bind $widget.files <Double-Button-1> \
	"browserHandler $widget $wName $variable"
    button $widget.up -text up -command "
	set dir \$browserD($wName)
	set parent \[file dirname \$dir\]
	set browserD($wName) \$parent
	set browserP($wName) \$browserD($wName)/
	fillFileList $widget.files \$browserD($wName)
	set browserP($wName) \$browserD($wName)/
	set $variable \$browserP($wName)
    "

    pack $widget.up -side left -pady 2m -padx 2m -fill y
    pack $widget.scroll -side left -fill y -pady 2m
    pack $widget.files -side left -pady 2m
}

proc fileBrowse {variable mode {dir "-"} {window "-"}} {
    
    global $variable
    global browserOk
    
    if {$dir == "-"} {
	set dir [pwd]
    }
    set $variable $dir/

    if {$window != "-" } {
    
	if {$mode == "w" } {
	    entry $window.filename -textvariable $variable \
		-relief sunken -width 40
	} else {
	    label $window.filename -textvariable $variable \
		-relief sunken -width 40
	}
	pack  $window.filename -side bottom -pady 2m
	# Accept a filename into path
	browser $window $variable $dir
	return ""
    } else {
	set okCmd "global browserOk; set browserOk 1; destroy .browser"
	toplevel .browser -class Dialog
	wm title .browser "File Browse"
	wm iconname .browser "Browser"

	frame .browser.top -relief raised -bd 2
	pack .browser.top -side top
	frame .browser.bot -relief raised -bd 2
	pack .browser.bot -side bottom -fill both
	
	# Accept a filename into path
	browser .browser.top $variable $dir
	
	# setup buttons and newline handling
	set browserOk 0
	button .browser.bot.ok -text ok -fg ForestGreen  -command $okCmd \
	    -activebackground "DarkOliveGreen" -activeforeground white
	button .browser.bot.cancel -fg red -activebackground chocolate\
	    -text Cancel -command "destroy .browser"

	if {$mode == "w" } {
	    entry .browser.bot.filename -textvariable $variable\
		-relief sunken -width 40
	} else {
	    label .browser.bot.filename -textvariable $variable \
		-relief flat -width 40
	}
	bind .browser <Return> $okCmd

	pack .browser.bot.filename -side top -pady 2m 
	pack .browser.bot.cancel .browser.bot.ok -side left \
	    -ipadx 2m -ipady 2m -padx 2m

	#    bind .browser <Double-Button-1> $okCmd

	set oldfocus [focus]
	grab set .browser
	focus .browser

	tkwait window .browser

	focus $oldfocus
	if $browserOk {
	    return 1
	} else {
	    return 0
	}
    }
}

########################################################################

proc fillFileList {widget dirname} {
    $widget delete 0 [$widget size]
    foreach i [lsort [glob $dirname/*]] {
	set name [file tail $i]
	if {[file isdirectory $i]} {
	    set name "$name/"
	}
	$widget insert end $name
    }
}



########################################################################
########################################################################

# Portions of this code are Copyright Regents of the University of California
# Portions of this code are Copyright Sun Microsystems Inc.
# Portions of this code are Copyright 1993 by Sanjay Ghemawat
# Portions of this code are Copyright 1996 Shamim Mohamed

#	spar_set <leader> <label> <resultvar> <initial spar list>
#
#	Interact with user to determine set of spar times.
#	The result is a list of elements ranging over 0..100 and is
#	stored in resultvar.  Returns true iff dialog is not cancelled.

# Hidden global variables
#
#	as_done			Is as interaction finished
#	as_ruler		Ruler window name
#	as_helping		True iff help is being displayed

set as_done 0
set as_ruler ""
set as_helping 0

proc spar_set {w label init} {
    global as_ruler
    
    frame $w.top
    message $w.label -text "$label" -width 50 -anchor w
    pack $w.label -in $w.top -side left
    frame $w.mid -width 130 -height 10 
    button $w.help -text "Spar help..." -command sparHelp
    pack $w.help -in $w.top -side right
    pack $w.top -side top -fill x
    as_make $w
    ruler_settabs $as_ruler $init

}

proc sparHelp {} {
    set f .helpDialog

    toplevel .$f -class Dialog
    wm title $f "Help on Spars"

    message $f.text -aspect 400 -text [join {
	{Create a spar by dragging a marker out of the well at the}
	{right of the scale.}
	{You can also drag existing spars to change locations.}
	{If you drag a spar far enough up or down so that it turns}
	{dim, it will be deleted when you release the mouse button.}
	{Type in the thickness of the spar in the text entry field that}
	{tracks the spar marker.}
    }]
    button $f.dismiss -text Dismiss -command "destroy $f" -bd 1m

    pack $f.text $f.dismiss -ipady 2m -pady 2m -ipadx 2m -side top

    tkwait window $f
}

proc as_make {f} {

    global as_ruler
    set as_ruler $f.ruler
    ruler $as_ruler {} 0 100 10 2 1 1m
    pack $as_ruler -side top -expand 1 -fill both -padx 5m -pady 2m
}

proc as_interact {leader label init} {
    global as_ruler as_done
    set f .

    # Initialize dialog

}

set txtFocus {}

# Usage: ruler <w> <label> <min> <max> <major> <minor> <unit>
#
# Create a ruler from <min> to <max> with major and minor hash marks.
# The new window is called <w>.  Minor hash marks are <unit> apart.
#
# Example: The following command creates a scale from 0 to 60 with
# major hash marks on every multiple of 5, and minor hash marks on
# every multiple of 1.  Minor hash marks are separated by 2mm.
#
#	ruler .c {Select positions} 0 60 5 1 2m

proc ruler {c label min max major submajor minor unit} {
    upvar #0 ruler_$c v
    catch {destroy $c}

    canvas $c

    # Get layout info
    set v(min)    $min
    set v(max)    $max
    set v(minor)  $minor
    set v(major)  $major
    set v(submaj) $submajor
    set v(unit)   [winfo pixels . $unit]

    set v(left)   [winfo pixels $c 5m]
    set v(right)  [expr $v(left) + (($max - $min) * $v(unit))/$minor]
    set v(top)    [winfo pixels $c 1c]
    set v(bottom) [winfo pixels $c 2c]
    set v(size)   [winfo pixels $c 2m]

    $c configure -width [expr $v(right) + [winfo pixels $c 1c]] -height 1.8c

    # Get normal/active colors
    set nfg [option get $c apptLineColor Foreground]
    if ![string compare $nfg ""] {set nfg black}

    set afg $nfg
    if [string match *color* [winfo screenvisual .]] {set afg red}

    set v(normalStyle) "-fill $nfg"
    set v(activeStyle) "-fill $afg -stipple {}"
    set v(deleteStyle) "-stipple gray50 -fill $afg"

    # Find font
    set textoptions [list -fill $nfg]
    set o [option get $c itemFont Font]
    if [string compare $o ""] {
	lappend textoptions -font $o
    }

    # Create label
    eval $c create text $v(left) 5m -tags {label} -anchor sw
    $c itemconfigure label -text $label
    eval $c itemconfigure label $textoptions

    # Create horizontal line
    $c create line $v(left) 1c $v(right) 1c -fill $nfg

    set x $v(left)
    set off 0
    for {set i $min} {$i <= $max} {incr i $minor} {
	if {($off % $major) == 0} {
	    # Major hash mark
	    $c create line $x 1c $x 5m -fill $nfg
	    eval $c create text $x 5m -text $i -anchor s $textoptions
	} elseif {($off % $submajor) == 0} {
	    $c create line $x 1c $x 7m -fill $nfg
	} else {
	    # Minor hash mark
	    $c create line $x 1c $x 9m -fill grey50
	}

	incr off $minor
	incr x $v(unit)
    }

    set wl [expr $v(right) + [winfo pixels $c .2c]]
    set wc [expr $v(right) + [winfo pixels $c .6c]]
    set wr [expr $v(right) + [winfo pixels $c 1c]]

    $c addtag well withtag [$c create rect $wl 1c $wr 5m\
			    -outline $nfg -fill [lindex [$c config -bg] 4]]
    $c addtag well withtag [ruler_tab $c $wc [winfo pixels $c 6.5m]]

    foreach d {1 2 3} {
	$c bind well <$d>		[list ruler_newtab $c %x %y]
	$c bind tab <$d>		[list ruler_select $c %x %y]
	bind $c <B$d-Motion>		[list ruler_move $c %x %y]
	bind $c <ButtonRelease-$d>	[list ruler_release $c]
    }
    $c bind text <1> "textB1Press $c %x %y"
    $c bind text <B1-Motion> "textB1Move $c %x %y"
    $c bind text <Shift-1> "$c select adjust current @%x,%y"
    $c bind text <Shift-B1-Motion> "textB1Move $c %x %y"
    $c bind text <KeyPress> "textInsert $c %A"
#    $c bind text <Return> "textInsert $c \\n"
    $c bind text <Control-h> "textBs $c"
    $c bind text <BackSpace> "textBs $c"
    $c bind text <Delete> "textDel $c"
    $c bind text <2> "textPaste $c @%x,%y" 
}
set textConfigFill {}

proc textEnter {w} {
    global textConfigFill
    set textConfigFill [lindex [$w itemconfig current -fill] 4]
    $w itemconfig current -fill black
}

proc textInsert {w string} {
    global txtFocus
    if {$string == ""} {
	return
    }
    catch {$w dchars text sel.first sel.last}
    $w insert $txtFocus insert $string
}

proc textPaste {w pos} {
    global txtFocus
    catch {
	$w insert $txtFocus $pos [selection get]
    }
}

proc textB1Press {w x y} {
    foreach id [$w find withtag current] {
	if [string match thickness* $id] {
	    set txtFocus $id
	    break
	}
    }
    $w icursor current @$x,$y
    $w focus current
    focus $w
    $w select from current @$x,$y
}

proc textB1Move {w x y} {
    $w select to current @$x,$y
}

proc textBs {w} {
    global txtFocus
    if ![catch {$w dchars $txtFocus sel.first sel.last}] {
	return
    }
    set char [expr {[$w index $txtFocus insert] - 1}]
    if {$char >= 0} {$w dchar $txtFocus $char}
}

proc textDel {w} {
    global txtFocus
    if ![catch {$w dchars $txtFocus sel.first sel.last}] {
	return
    }
    $w dchars $txtFocus insert
}

# effects  Modify the label for the ruler
proc ruler_setlabel {c label} {
    $c itemconfigure label -text $label
}

# effects  Remove all existing tabs and create tabs at specified positions.
proc ruler_settabs {c pos} {
    upvar #0 ruler_$c v

    $c delete tab

    set y [expr $v(top)+2]
    foreach p $pos {
	set x [ruler_canvas_coord $c $p]
	$c addtag tab withtag [ruler_tab $c $x $y]
    }
}

# effects  Return list of positions of current tabs.
proc ruler_tabs {c} {
    upvar #0 ruler_$c v

    set result {}
    foreach i [$c find withtag tab] {
	set t [$c itemcget [$c find withtag thickness$i] -text]
	set coords [$c coords $i]
	if {[llength $coords] < 6} continue
	set x [lindex $coords 0]
	lappend result [list [ruler_user_coord $c $x] $t]
    }
    return $result
#    return [lsort -integer $result]
}

# effects  Return user-coordinate value for specified canvas position
proc ruler_user_coord {c x} {
    upvar #0 ruler_$c v
    return [expr round((($x-$v(left))*$v(minor))/$v(unit)+$v(min))]
}

# effects  Return canvas-coordinate value for specified user position
proc ruler_canvas_coord {c x} {
    upvar #0 ruler_$c v
    return [expr ((($x*1.0 - $v(min)) * $v(unit)) / $v(minor)) + $v(left)]
}

# effects  Create a tab at "x,y"
proc ruler_tab {c x y} {
    global sparNum
    upvar #0 ruler_$c v
    return [eval $c create polygon $x $y [expr $x+$v(size)] [expr $y+$v(size)]\
	    [expr $x-$v(size)] [expr $y+$v(size)] $v(normalStyle)]
}

proc ruler_newtab {c x y} {
    global txtFocus
    upvar #0 ruler_$c v
    set tabId [ruler_tab $c $x $y]
    $c addtag active withtag $tabId
    $c addtag thickness$tabId withtag \
	[$c create text $x [expr $y+2*$v(size)] -anchor center -text "0" -tags thickness]
    $c addtag text withtag thickness
    $c addtag tab withtag active
    
    $c icursor thickness$tabId 0
    $c focus thickness$tabId
    focus $c
    $c select from thickness$tabId 0
    set txtFocus thickness$tabId
    ruler_move $c $x $y
}

proc ruler_move {c x y} {
    upvar #0 ruler_$c v
    set tabId [$c find withtag active]
    if {$tabId == ""} {return}

    set cx [$c canvasx $x $v(unit)]
    set cy [$c canvasy $y]
    if {$cx < $v(left)} {set cx $v(left)}
    if {$cx > $v(right)} {set cx $v(right)}

    # Is tab in active region?
    if {($cy >= $v(top)) && ($cy <= $v(bottom))} {
	set cy [expr $v(top)+2]
	eval "$c itemconf thickness$tabId $v(activeStyle)"
	eval "$c itemconf active $v(activeStyle)"
    } else {
	set cy [expr $cy-$v(size)-2]
	eval "$c itemconf thickness$tabId $v(deleteStyle)"
	eval "$c itemconf active $v(deleteStyle)"
    }

    # Translate X coordinate to grid
    set cx [ruler_canvas_coord $c [ruler_user_coord $c $cx]]

    # Move the item
    set coords [$c coords active]
    if {[llength $coords] < 6} return
    set v_x [lindex $coords 0]
    set v_y [lindex $coords 1]
    $c move active [expr $cx-$v_x] [expr $cy-$v_y]
    $c move [$c find withtag thickness$tabId] [expr $cx-$v_x] [expr $cy-$v_y]
}

proc ruler_select {c x y} {
    upvar #0 ruler_$c v

    $c addtag active withtag current
    eval "$c itemconf active $v(activeStyle)"
    $c raise active
}

proc ruler_release c {
    upvar #0 ruler_$c v
    set t [$c find withtag active]
    if {$t == {}} {
	return
    }

    set coords [$c coords active]
    if {[llength $coords] < 6} return
    set v_y [lindex $coords 1]

    if {$v_y != [expr $v(top)+2]} {
	$c delete active
	$c delete thickness$t
    } else {
	eval "$c itemconf thickness$t $v(normalStyle)"
	eval "$c itemconf active $v(normalStyle)"
	$c dtag active
    }
}

########################################################################
########################################################################

frame .banner
label .banner.image -bitmap @plotfoil.xbm -fg red
label .banner.name -text "Plotfoil 3.3"
pack .banner .banner.image .banner.name -side left

# The file selection widget
frame .sectionSelect 
fileBrowse sectionFileName r $airfoils .sectionSelect

frame .naca
entry .naca.number -textvariable naca -width 10 -relief sunken -bd 2 
checkbutton .naca.check -variable useNaca -text "Compute NACA section" \
    -command {
	toggleColour .naca.number $useNaca
	toggleColour .sectionSelect.filename [expr !$useNaca]
    }  -anchor w -relief flat
pack .naca.check .naca.number -side left

# Chord selection
frame .chord
label .chord.name -text "Chord:"
entry .chord.value -width 10 -relief sunken -bd 2 -textvariable chord
pack .chord .chord.name .chord.value -side left

frame .modify
frame .modify.left
label .modify.label -text "Modify: " -anchor w
frame .modify.c
checkbutton .modify.camberLabel -text camber \
    -command {toggleColour .modify.camber $modCamber} \
    -variable modCamber -anchor w -relief flat
entry .modify.camber -width 3 -relief sunken -bd 2 -textvariable camber
pack .modify.camberLabel .modify.camber -in .modify.c -side left -anchor w
frame .modify.t
checkbutton .modify.thicknessLabel -text thickness \
    -command {toggleColour .modify.thickns $modThickness} \
    -variable modThickness -anchor w -relief flat
entry .modify.thickns -width 3 -relief sunken -bd 2 -textvariable thick
pack .modify.thicknessLabel .modify.thickns -in .modify.t -side left -anchor w
pack .modify.label -side top -in .modify.left -anchor w
button .modify.save -text Save -command {
    set cmd [getmodcmd]
    if {$cmd != ""} {
	if [fileBrowse filename w] {
	    eval "runit $cmd >$filename"
	}
    }
}
frame .modify.pad -width 10 -height 10
pack .modify.c .modify.pad .modify.t \
    -in .modify.left -side left -anchor w
pack .modify.save .modify.left -padx 2m -pady 2m -side right

# Units selection
frame .units -relief ridge -width 4c -bd 3
label .units.label -text Units: -anchor w
radiobutton .units.mm -text mm -variable units -value m -anchor w -relief flat
radiobutton .units.cm -text cm -variable units -value c -anchor w -relief flat
radiobutton .units.in -text inches -variable units -value i -anchor w \
    -relief flat
pack .units .units.label .units.mm .units.cm .units.in -side top -anchor w

# Use sheeting allowance?
frame .sheeting
checkbutton .sheeting.use -text "Sheeting" \
    -command {toggleColour .sheeting.value $useSheetingAllowance} \
    -variable useSheetingAllowance -anchor w -relief flat -anchor w
entry .sheeting.value -width 5 -relief sunken -bd 2 \
    -textvariable sheetingAllowance
pack .sheeting .sheeting.use .sheeting.value -side left -anchor w

# Spars
frame .spars 
spar_set .spars {Spars} {}

# templates
frame .template
checkbutton .template.label -text "Plot template" -command {
    toggleColour .template.height $usetemplate
    toggleColour .template.le $usetemplate
    toggleColour .template.te $usetemplate
} -variable usetemplate -anchor w -relief flat
frame .template.h
entry .template.height -width 5 -textvariable templateH  -relief sunken
label .template.hlabel -text Height
pack  .template.height .template.hlabel -in .template.h -side left
frame .template.l
entry .template.le -width 5 -textvariable templateL -relief sunken
label .template.llabel -text LE
pack  .template.le .template.llabel -in .template.l -side left
frame .template.t
entry .template.te  -width 5 -textvariable templateT -relief sunken
label .template.tlabel -text TE
pack .template.te .template.tlabel -in .template.t -side left
pack .template .template.label .template.h .template.t .template.l -side top \
    -anchor w

frame .papersize
label .papersize.value -textvariable papersize
label .papersize.label -text "Paper size" -anchor w
menubutton .papersize.button -bitmap @down.xbm \
    -relief raise -bd 2 -menu .papersize.button.menu
pack .papersize.label -side top -padx 2m -pady 1m -anchor w
pack .papersize.button -side left -anchor n -padx 2m
pack .papersize.value -side left -anchor n
set m [menu .papersize.button.menu -tearoff 0]
$m add command -label letter -command { set papersize letter }
for {set i 0} {$i <= 5} {incr i} {
    $m add command -label "A$i" -command [list set papersize "A$i"]
    $m add command -label "B$i" -command [list set papersize "A$i"]
}

# x/y offsets
frame .offsets
label .offsets.label -text "Offsets: " -anchor nw
frame .offsets.h
checkbutton .offsets.x -text horizontal \
    -command {toggleColour .offsets.xval $usexoffset} \
    -variable usexoffset -anchor w -relief flat
entry .offsets.xval -width 3 -relief sunken -bd 2 -textvariable xoffset
pack .offsets.x -in .offsets.h -side left -anchor w
pack .offsets.xval -in .offsets.h -side right

frame .offsets.v
checkbutton .offsets.y -text vertical \
    -command {toggleColour .offsets.yval $useyoffset} \
    -variable useyoffset -anchor w -relief flat
frame .offsets.pad -width 1c
entry .offsets.yval -width 3 -relief sunken -bd 2 -textvariable yoffset
pack .offsets.y -in .offsets.v -side left -anchor w
pack .offsets.yval -in .offsets.v -side right
pack .offsets .offsets.label .offsets.h .offsets.v -side top -anchor w -fill x

# angle, for washout
frame .washout
checkbutton .washout.label -text "Rotate: " \
    -command {toggleColour .washout.angle $useangle} \
    -variable useangle -anchor w -relief flat -anchor w
entry .washout.angle -textvariable angle -width 4 -relief sunken -bd 2 
pack .washout .washout.label .washout.angle -side left -anchor w

# Quit/Plot buttons
frame .buttons -relief sunken -bd 2
frame .buttons.top
frame .buttons.bot
frame .buttons.plot -width 2.5c -height 1.5c
frame .buttons.quit -width 2.5c -height 1.5c
frame .buttons.view -width 2.5c -height 1.5c
frame .buttons.save -width 2.5c -height 1.5c
button .buttons.plot.b -text Print -command print
button .buttons.quit.b -text Quit -fg red -command exit \
    -activebackground chocolate
button .buttons.save.b -text Save -command save
button .buttons.view.b -text Preview -command preview
#
pack .buttons.quit.b -fill both -expand true -padx 1m -pady 1m
pack .buttons.plot.b -fill both -expand true -padx 1m -pady 1m
pack .buttons.save.b -fill both -expand true -padx 1m -pady 1m
pack .buttons.view.b -fill both -expand true -padx 1m -pady 1m
#
pack propagate .buttons.quit false
pack propagate .buttons.save false
pack propagate .buttons.view false
pack propagate .buttons.plot false
pack .buttons.plot .buttons.save -in .buttons.top -side left
pack .buttons.top -side top
pack .buttons.view .buttons.quit -side left -in .buttons.bot
pack .buttons.bot -side bottom

#
# the final pack
#

frame .left -relief groove -bd 1
frame .ne -relief groove -bd 1
frame .se
frame .seL
frame .seR

pack .spars -side bottom -in .ne
pack .units -side right -in .ne -pady 5m -padx 5m
pack .template -side right -in .ne -padx 1c -pady 5m
pack .chord -side top -in .ne -anchor w -pady 5m -padx 5m
pack .sheeting -side top -in .ne -anchor w -padx 5m
lower .ne

pack .buttons -side right -in .seR -fill y -padx 5m
pack .papersize -side left -in .seL -anchor n
pack .washout -side top -in .seL -anchor w -padx 5m -pady 2m
pack .offsets -side bottom -in .seL -anchor w -padx 5m -pady 2m
pack .seL -side left -fill y -in .se
pack .seR -side right -in .se -anchor s
lower .se
lower .seR
lower .seL

pack .modify .naca .sectionSelect -side bottom -in .left
pack .banner -side top -in .left -pady 5m
lower .left

pack .left -side left -fill y 
pack .ne -side top
pack .se -side top -fill both

#######################################################################
#
# Helper procs
#
proc toggleColour {widget value} {

    if {$value == 1} {
	$widget configure -fg black
    } else {
	$widget configure -fg grey
    }
}
# Run it once to set the colour at startup
toggleColour .sheeting.value $useSheetingAllowance
toggleColour .offsets.xval $usexoffset
toggleColour .offsets.yval $useyoffset
toggleColour .washout.angle $useangle
toggleColour .template.height $useangle
toggleColour .template.le $usetemplate
toggleColour .template.te $usetemplate
#######################################################################
#
# add/del spars
#
proc addSpar args {
    global sparCount thickness positions

    incr sparCount

    set thickness($sparCount) ""
    set positions($sparCount) 0

    set width$sparCount 0

    frame .spars.spar$sparCount -width 50m
    label .spars.spar$sparCount.thick -text Thickness
    entry .spars.spar$sparCount.thickness -relief sunken -width 3 \
	-textvariable thickness($sparCount)
    label .spars.spar$sparCount.at -text at 
    scale .spars.spar$sparCount.pos -from 0 -to 100 -length 5c \
	-orient horizontal -command [list sliderHandler $sparCount ]
    pack .spars.spar$sparCount \
	.spars.spar$sparCount.thick .spars.spar$sparCount.thickness \
	.spars.spar$sparCount.at .spars.spar$sparCount.pos \
	-side left
    pack .spars .spars.spar$sparCount -side top -padx 2m

    .spars.del configure -fg black
}

proc sliderHandler {sparNum otherarg} {
    global thickness positions

    set t [.spars.spar$sparNum.thickness get]
    set p [.spars.spar$sparNum.pos get]

    set thickness($sparNum) $t
    set positions($sparNum) $p
}

proc delSpar args {
    global thickness positions
    global sparCount

    if {$sparCount > 0} {
	destroy .spars.spar$sparCount
	incr sparCount -1
	
	if {$sparCount <= 0} {
	    .spars.del configure -fg grey
	}
    }
}

#######################################################################
#
# tcl procs
#

proc getmodcmd {} {    
    global  modCamber modThickness camber thick sectionFileName
    global useNaca naca plotfoil

    if {!$useNaca && [string match */ $sectionFileName]} {
	# show error
	error Error "Please select the section you wish to plot/modify first."
	return ""
    }
    set cmd ""
    if {$useNaca} {
	set cmd "$plotfoil/naca $naca | "
    }
    set options ""
    if {$modCamber} {
	set options "$options -c $camber"
    }
    if {$modThickness} {
	set options "$options -t $thick"
    }
    set cmd "$cmd $plotfoil/editfoil -q $options"
    if {!$useNaca} {
	set cmd "$cmd $sectionFileName"
    }

    return $cmd
}

proc getcmd args {
    global chord units sectionFileName useSheetingAllowance sheetingAllowance
    global plotfoil usexoffset useyoffset sparCount useangle usetemplate
    global templateL templateT templateH thickness positions useNaca
    global angle xoffset yoffset as_ruler modCamber modThickness

    set cmd ""
    
    if {!$useNaca && [string match */ $sectionFileName]} {
	# show error
	error Error "Please select the section you wish to plot first."
	return ""
    }
    
    set cmd "$cmd $plotfoil/plotfoil -q -c $chord$units"
    if {$useSheetingAllowance > 0} {
	set cmd $cmd\ -i\ $sheetingAllowance
    }
    if {$usexoffset > 0} {
	set cmd $cmd\ -x\ $xoffset
    }
    if {$useyoffset > 0} {
	set cmd $cmd\ -y\ $yoffset
    }

    foreach i [ruler_tabs $as_ruler] {
	set cmd "$cmd -sp $i"
    }

    for {set i 1} {$i <= $sparCount} {incr i} {
	set t  $thickness($i)
	set p  $positions($i)
	set cmd $cmd\ -sp\ $p\ $t
    }
    if {$useangle > 0 } {
	set cmd $cmd\ -a\ $angle
    }
    if {$usetemplate > 0 } {
	set cmd "$cmd -tl $templateL -tt $templateT -th $templateH"
    }
    if {$useNaca || $modCamber || $modThickness} {
	set cmd "[getmodcmd] | $cmd"
    } else {
	set cmd "$cmd $sectionFileName"
    }
    return $cmd
}

proc print args {
    global lpr

    set cmd [getcmd]
    if {[string length $cmd] <= 0} {
	return
    }

    toplevel .print
    label .print.name -text "Command to print:"
    entry .print.cmd -textvariable lpr -width 15 -relief sunken -bd 2
    button .print.ok -text ok \
	-command "destroy .print ; runit $cmd | \$lpr"
    bind .print <KeyPress-Return> "destroy .print ; runit $cmd | \$lpr"
    button .print.cancel -text cancel -command {
	destroy .print
    }
    pack .print.name -side top -anchor w -pady 2m -padx 2m
    pack .print.cmd -side top -anchor w -padx 2m
    pack .print.cancel .print.ok -side left -padx 4m -pady 4m \
	-ipadx 2m -ipady 2m 
}

proc preview args {
    global ghostview

    set cmd [getcmd]
    if {[string length $cmd] <= 0} {
	return
    }

    # Pipe plotfoil output to ghostview
    runit $cmd\ |\ $ghostview\ -
}

proc save args {
    global filename
    set cmd [getcmd]
    if {[string length $cmd] <= 0} {
	return
    }

    # Put up browser
    if [fileBrowse filename w] {
	eval "runit $cmd >$filename"
    }
}

proc quit args {
   exit
}

proc dialog {w title text bitmap default args} {
    global button

    toplevel $w -class Dialog
    wm title $w $title
    wm iconname $w Dialog
    frame $w.top -relief raised -bd 2
    pack $w.top -side top -fill both
    frame $w.bot -relief raised -bd 2
    pack $w.bot -side bottom -fill both

    message $w.top.msg -width 301 -text $text \
	-font *-Times-Medium-R-Normal-*-180-*
    pack $w.top.msg -side right -expand 1 -fill both -padx 3m -pady 3m
    if {$bitmap != ""} {
	label $w.top.bitmap -bitmap $bitmap
	pack $w.top.bitmap -side left -padx 3m -pady 3m
    }
	
    set i 0
    foreach but $args {
	button $w.bot.button$i -text $but -command "set button $i"
	if {$i == $default} {
	    frame $w.bot.default -relief sunken -bd 1
	    raise $w.bot.button$i
	    pack $w.bot.default -side left -expand 1 -padx 2m -pady 2m
	    pack $w.bot.button$i -in $w.bot.default -side left \
		-padx 2m -pady 2m -ipadx 2m -ipady 2m
	} else {
	    pack $w.bot.button$i -side left -expand 1 \
		-padx 2m -pady 2m -ipadx 2m -ipady 2m
	}
	incr i
    }

    if {$default >= 0} {
	bind $w <Return> "$w.bot.button$default flash; set button $default"
    }
    set oldfocus [focus]
    grab set $w
    focus $w

    tkwait variable button
    destroy $w
    focus $oldfocus
    return $button
}

proc error {title msg} {
    dialog .d $title $msg warning 0 Dismiss
}

proc dismiss args {
    destroy .msg
}

proc runit args {
    set cmd ""
    foreach i $args {
	set cmd "$cmd $i"
    }
    puts $cmd
    eval exec $cmd
}

