#!/bin/sh
# \
exec wish8.0 -f "$0" "$@"

#!/usr/bin/wish8.0 -f
#!/usr/local/bin/wish8.0 -f

#####################################################################
#####################################################################
#
# phototk by Payton R. White (pwhite@multigen.com) (c) 1998
#
# See the .phototk file for an explaination of possible phototk
# customizeations.
#
# This is public domain software, use the hell out of it.
#
#####################################################################
#####################################################################

#####################################################################
# globals

set prefs(device) /dev/photopc
set prefs(baud) 115200
set prefs(photopc) photopc
set prefs(dbg) 0
set prefs(tmpDir) /usr/tmp/phototk[pid]
set prefs(cur) 0
set prefs(convert) convert

set vibe(defFont) -adobe-helvetica-medium-o-normal--10-100-75-75-p-57-iso8859-1
set vibe(borderWidth) 10
set vibe(defBg) #000000
set vibe(defFg) #9999cc
set vibe(quitBg) #440000
set vibe(editBg) #220022
set vibe(liveBg) #004400
set vibe(prefsBg) #004444
set vibe(aboutBg) #000044
set vibe(quitBg) #440000
set vibe(hiliteSize) 0

#####################################################################
# source the support libraries

# appDir -> where the tk script actually lives
set app $argv0
catch { set app [file readlink $app] }
set appDir [file dirname $app]

set libDir $appDir/lib
source $libDir/tclpp.tcl
source $libDir/tabdialog.tcl
source $libDir/scrolled.tcl

#####################################################################
# source the user's .phototk file if it exists

catch { source ~/.phototk }

#####################################################################
# globals the user can't override with a .phototk file

set frames(theTab) ""
set frames(names) { edit live prefs about quit }
set frames(frames) ""
set frames(active) ""
set frames(tabs) ""

set live(pre) ""
set live(time) ""
set live(timeAmount) ""

set edit(sel) ""
set edit(thumbs) ""
set edit(count) 0

#####################################################################
# init procs

proc initMisc {} {
	global prefs
	
	file mkdir $prefs(tmpDir)
# 	exec mkdir $prefs(tmpDir)
}

proc initFrames {} {
	global frames prefs vibe
	
	set frames(theTab) [new Tabs .tabs -command "activateFrame %o"]

	# hidden frame
	set hidden [frame .hidden]
	pack $hidden -side top -expand 0 -fill x

	set title [label .hidden.title -text "\tphototk\t\t\t"]
	pack $title -side left
	
	set frames(frames) ""
	
	#'tab' frames
	foreach f $frames(names) {
		set page [$frames(theTab) add .hidden.$f -text $f -bg $vibe(${f}Bg) \
			-font $vibe(defFont) -fg $vibe(defFg)]
		lappend frames(frames) [$page getWidg]
		[$page getWidg] configure -bd $vibe(borderWidth)
	}

	pack [$frames(theTab) getWidg] -side top -fill both -expand 1
}

proc initAbout {} {
	global about appDir vibe
	
	set about(txt) [text [frameName about].txt -highlightthickness 0\
			-borderwidth 0]
	
	set txt [photopc -V]
	
	$about(txt) insert 0.0 "
	
by Payton R. White


--------------------------

version 0.9.9.0

--------------------------


a tk interface to photopc:


$txt

"

	catch { set img [image create photo -file $appDir/logo.ppm]
			set iname [$about(txt) image create 1.0 -image $img] }

	set tagName [genSym tag]
	$about(txt) tag add $tagName 0.0 end
	$about(txt) tag configure $tagName -justify center

	$about(txt) configure -state disabled

	pack $about(txt) -expand 1 -fill both
}

proc initEdit {} {
	global edit vibe
	
	set edit(buttf) [frame [frameName edit].buttf]
	pack $edit(buttf) -side top
	
	set edit(bnames) { thumbnail selectAll downloadSelected downloadAll deleteSelected deleteAll }
		
	foreach b $edit(bnames) {
		set name $edit(buttf).$b
		set edit($b) [button $name -text $b -command $b -padx 2]
		pack $name -side left
	}

	set scrollt [frameName edit].scrollt
	set edit(scroll) [new ScrolledText $scrollt -width 70]
	pack $scrollt -expand 1 -fill both
	
	set edit(txt) [$edit(scroll) getWidg]
	$edit(txt) configure -state disabled \
			-highlightthickness 0 -highlightbackground $vibe(editBg)
}

proc initLive2 {} {	
	global live
	set f [frameName live]
	
	set tmpf [frame $f.butts]
	pack $tmpf -side top
	
	set pre [button $tmpf.pre -text preview -command livePreview]
	pack $pre -side left
	
	set snap [button $tmpf.snap -text snapshot -command liveSnapshot]
	pack $snap -side left
	
	set timed [button $tmpf.time -text timed -command liveTimed]
	pack $timed -side left
	
	set live(time) [addFrame $f]
	pack forget $live(time)
	
	set live(pre) [frame $f.pre]
	
	set tf [addFrame $live(time)]
	$tf configure -borderwidth 25
	addOption $tf "mode" live(mode) "timeLapse" "webCam"
	addOption $tf "size" live(size) "thumbNail" "standardQuality" "highQuality"
	
	set tf [addFrame $live(time)]
	set live(timeAmount) [addEntry $tf "Time Interval (sec): "]
# 	set tf [addFrame $live(time)]
# 	set live(fileName) [addEntry $tf "File Name Prefix: "]
	
	set tf [addFrame $live(time)]
	$tf configure -borderwidth 50
	set live(start) [addButton $tf "start" liveStart]
	pack $live(start) -side top
	
# 	set live(stop) [addButton $tf "stop" liveEnd]
# 	$live(stop) configure -state disabled
}

proc initLive {} {	
	global live vibe
	set f [frameName live]
	
	set live(base) [addFrame $f "-side top -fill x"]
	$live(base) configure -highlightthickness 0 -bd 0 -relief raised
	set live(tabs) [new Tabs $f.frames -extend $live(base)]
	
	# preview mode
	set prePage [$live(tabs) add $live(base).pre -text preview \
		-bg $vibe(prefsBg) -font $vibe(defFont) -fg $vibe(defFg)]

	set pre [button [$prePage getWidg].pre -text preview -command livePreview]
	pack $pre -side top
	[$prePage getWidg] configure -bd 25
	set live(preFrame) [$prePage getWidg]
			
	# snap shot mode
	set snapPage [$live(tabs) add $live(base).snap -text snapshot \
		-bg $vibe(editBg) -font $vibe(defFont) -fg $vibe(defFg)]

	set snap [button [$snapPage getWidg].snap -text snapshot -command liveSnapshot]
	pack $snap -side top
	[$snapPage getWidg] configure -bd 25
	set live(snapFrame) [$snapPage getWidg]
	
	# time lapse and web cam mode
	set livePage [$live(tabs) add $live(base).time -text timed \
		-bg $vibe(aboutBg) -font $vibe(defFont) -fg $vibe(defFg)]
		
	set live(time) [$livePage getWidg]
	
	set opts "-side top -anchor n"
	
	set tf [addFrame $live(time) $opts]
	$tf configure -borderwidth 25
	set live(liveFrame) [$livePage getWidg]
	
	addOption $tf "mode" live(mode) "timeLapse" "webCam"
	addOption $tf "size" live(size) "thumbNail" "standardQuality" "highQuality"
	
	set tf [addFrame $live(time) $opts]
	set live(timeAmount) [addEntry $tf "Time Interval (sec): "]
# 	set tf [addFrame $live(time)]
# 	set live(fileName) [addEntry $tf "File Name Prefix: "]
	
	set tf [addFrame $live(time) $opts]
	$tf configure -borderwidth 50
	set live(start) [addButton $tf "start" liveStart]
	pack $live(start) -side top
	
	pack [$live(tabs) getWidg] -side top -fill both -expand 1

# 	set live(stop) [addButton $tf "stop" liveEnd]
# 	$live(stop) configure -state disabled
}

proc initPrefs {} {
	global prefs vibe

	set f [frameName prefs]
	
	#frame for buttons
	set f0 [frame $f.status]
	pack $f0 -side top
	
	set b1 [button $f0.status -text "download status from camera" -command readStatus]
	pack $b1 -side left

	set b1 [button $f0.status2 -text "upload status changes to camera" -command sendStatus]
	pack $b1 -side left
	
	# text status window
	set t1 [text $f.txt -width 40 \
			-highlightthickness 10 -highlightbackground $vibe(prefsBg)]
	set prefs(txt) $t1
	pack $t1 -side left -expand 1 -fill y
	$t1 insert 0.0 "press 'read status from camera' to begin"
	$t1 configure -state disabled
	
	#frame for all of the input widgets
	set f2 [addFrame $f]
	set tmp [addLabel $f2 "" top]
	$tmp configure -width 80
	
	#resolution input
	set tf [addFrame $f2]	
	addOption $tf "Resolution: " prefs(res) Lo Hi Ext
	
	#shutter mode
	set tf [addFrame $f2]
	addOption $tf "Shutter: " prefs(shut) "Auto" "Microsecond" "1/fraction"
	set prefs(shutVal) [addEntry $tf "Val: "]
	
	#color mode
	set tf [addFrame $f2]
	addOption $tf "Color: " prefs(color) "On" "Off"
	
	#flash mode
	set tf [addFrame $f2]
	addOption $tf "Flash: " prefs(flash) "Auto" "Force" "Off" "AntiRedeye"
	
	#autoshut stuff
	set tf [addFrame $f2]
	set prefs(autoHost) [addEntry $tf "Host Autoshutoff (sec): "]
		
	set tf [addFrame $f2]
	set prefs(autoField) [addEntry $tf "Field Autoshutoff (sec): "]
	
	#lcd stuff
	set tf [addFrame $f2]
	set prefs(autoLCD) [addEntry $tf "LCD Autoshutoff (sec): "]
	
	set tf [addFrame $f2]
	addOption $tf "LCD Brightness: " prefs(bright) 1 2 3 4 5 6 7
	
	# macro mode
	set tf [addFrame $f2]
	addOption $tf "Macro Mode: " prefs(macro) On Off
	
	# camera id
	set tf [addFrame $f2]
	set prefs(id) [addEntry $tf "Camera ID"]
}

proc initQuit {} {
	global appDir
	
	catch { set img [image create photo -file $appDir/tiki2.ppm]
			set lab [label [frameName quit].lab -image $img -borderwidth 40]
	pack $lab -side top }

	set bye [button [frameName quit].bye -text "really quit" -command doQuit ]
	pack $bye
}

proc doQuit {} {
	global prefs
	
	catch { file delete -force -- $prefs(tmpDir) }
	destroy . 
}

#####################################################################
# vibes

proc initVibe {} {
	global frames edit about prefs vibe live

	forWidgetTree defFont .
	forWidgetTree defColors .
	forWidgetTree defHilite .
	
	foreach f $frames(names) {
		forWidgetTree tabColor [frameName $f] $f
	}
	
	forWidgetTree tabColor $live(preFrame) prefs
	forWidgetTree tabColor $live(snapFrame) edit
	forWidgetTree tabColor $live(liveFrame) about	
}

proc defHilite { widget args } {
	global vibe
	
	set cur [$widget cget -highlightthickness]
	
	if { $cur == 1 || $cur == 2 } {
		$widget configure -highlightthickness $vibe(hiliteSize)
	}
}

proc defFont { widget args } {
	global vibe

	$widget configure -font $vibe(defFont)
}

proc defColors { widget args } {
	global vibe
	
	$widget configure -bg $vibe(defBg) 
	$widget configure -fg $vibe(defFg)
 	$widget configure -activebackground [modSat $vibe(defBg) 50]
 	$widget configure -activeforeground [modSat $vibe(defFg) 100]
#  	$widget configure -highlightbackground #666600
#  	$widget configure -highlightcolor #ffff00

}

proc tabColor { widget tab args } {
	global vibe
	
	set color $vibe(${tab}Bg)
	$widget configure -background $color
	$widget configure -activebackground [modSat $color 50]
}

#####################################################################
# prefs

set prefsNeedLoad 1
proc prefsExposed {} {
	global prefsNeedLoad

	update
	
	if { $prefsNeedLoad } {
		readStatus
		set prefsNeedLoad 0
	}
}

proc getElem { lines line elem } {
	return [lindex [lindex $lines $line] $elem]
}

proc parseStatus { txt } {
	set lines [split $txt "\n"]
	
	set out ""
	
	# 0 res must be mapped
	set res [getElem $lines 0 3]
	
	if { $res == "Low" } {
		lappend out Lo
	} elseif { $res == "High" } {
		lappend out Hi
	} else {
		lappend out Ext
	}
	
	# 1 shut we only use the value
	lappend out [getElem $lines 2 1]
	
	# 2 color must be mapped
	set color [getElem $lines 3 4]
	if { $color == "Color" } {
		lappend out "On"
	} else {
		lappend out "Off"
	}
	
	# 3 flash maps directoy
	lappend out [getElem $lines 4 3]
	
	# 4 5 autoshut host and field are values
	lappend out [getElem $lines 8 3]
	lappend out [getElem $lines 9 3]
	
	# 6 7 lcd autolcd and brightness
	lappend out [getElem $lines 13 2]
	lappend out [getElem $lines 12 2]
	
	# 8 macro mode
	lappend out [getElem $lines 11 4]
	
	# 9 camera id
	lappend out [lindex [lrange [lindex $lines 14] 2 end] 0]
	
# 	echo $out
	
	return $out
}

proc setEntry { entry what } {
	$entry delete 0 end
	$entry insert 0 $what
}

proc updateStatusWidgets { status } {
	global prefs
	
	set prefs(res) [lindex $status 0]
	
	if { [lindex $status 1] != 0 } {
		set prefs(shut) Microsecond
		setEntry $prefs(shutVal) [lindex $status 1]
	} else {
		set prefs(shut) Auto
		setEntry $prefs(shutVal) 0
	}
	
	set prefs(color) [lindex $status 2]
	
	set prefs(flash) [lindex $status 3]
	
	setEntry $prefs(autoHost) [lindex $status 4]
	setEntry $prefs(autoField) [lindex $status 5]

	setEntry $prefs(autoLCD) [lindex $status 6]
	set prefs(bright) [lindex $status 7]

	set prefs(macro) [lindex $status 8]
	
	# must strip off extra list nesting
	setEntry $prefs(id) [lindex $status 9]
}

proc sendStatus {} {
	global prefs
	
	progStart 2 "sending status"
	progIncr
	
	# resolution
	if { $prefs(res) != [lindex $prefs(status) 0] } {
		photopc resolution $prefs(res)
	}
	
	# shutter speed is a pain
	set shutVal [$prefs(shutVal) get]
	if { $prefs(shut) == "Auto" } {
		if { [lindex $prefs(status) 1] != 0 } {
			photopc shutter Auto
		}
	} elseif { $prefs(shut) == "Microseconds" } {
		if { $shutVal != [lindex $prefs(status) 1] } {
			photopc shutter $shutVal
		}
	} else {
		set thisVal [expr int ( 1000000 / double ( $shutVal ) )]
		echo $thisVal
		if { $thisVal != [lindex $prefs(status) 1] } {
			photopc shutter 1/$shutVal
		}
	}
	
	if { $prefs(color) != [lindex $prefs(status) 2] } {
# 		echo $prefs(color)
		photopc color $prefs(color)
	}

	if { $prefs(flash) != [lindex $prefs(status) 3] } {
		photopc flash $prefs(flash)
	}
	
	set autoHost [$prefs(autoHost) get]
	if { $autoHost != [lindex $prefs(status) 4] } {
		photopc autoshut-host $autoHost
	}
	
	set autoField [$prefs(autoField) get]
	if { $autoField != [lindex $prefs(status) 5] } {
		photopc autoshut-field $autoField
	}
	
	set autoLCD [$prefs(autoLCD) get]
	if { $autoLCD != [lindex $prefs(status) 6] } {
		photopc lcd-autoshut $autoLCD
	}
	
	if { $prefs(bright) != [lindex $prefs(status) 7] } {
		photopc lcd-brightness $prefs(bright)
	}
	
	if { $prefs(macro) != [lindex $prefs(status) 8] } {
		photopc macro $prefs(macro)
	}

	set id [$prefs(id) get]
	set test [lindex $prefs(status) 9]
	
	if { $id != $test } {
		photopc id $id
	}
	
	progEnd
	
	# reread status after
	readStatus
}

proc readStatus {} {
	global prefs

	progStart 2 "getting camera status"
	progIncr

	set txt [photopc query]
	set prefs(status) [parseStatus $txt]

	progEnd
	
	updateStatusWidgets $prefs(status)
	
	$prefs(txt) configure -state normal
	$prefs(txt) delete 0.0 end
	$prefs(txt) insert 0.0 $txt
	$prefs(txt) configure -state disabled
	
	update
}

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

proc livePreview {} {
	global live prefs
	
	if { $live(pre) != "" } {
		destroy $live(pre)
	}
	
	progStart 2 "taking snapshot"
	progIncr
	
	set file $prefs(tmpDir)/preview.jpp
	photopc preview $file
	set img [loadImage $file]
	
	set live(pre) [label $live(preFrame).preImg -image $img -borderwidth 15 -bg black]
	pack $live(pre) -side top
	
	progEnd
}

proc liveSnapshot {} {
	global live
	
	progStart 2 "taking snapshot"
	progIncr
	
	photopc snapshot
	
	progEnd
}

proc liveTimed {} {
	global live

	pack $live(time) -side top
	update
}

proc liveStart {} {
	global live progWidget vibe
	
	if { [askDownloadLocation "timed" ] == "" } return	
	
	readStatus

	progStart 5000 "current image"
	set stop [button $progWidget.stop -text "stop" -command liveEnd \
		-bg $vibe(quitBg) -fg $vibe(defFg) -font $vibe(defFont) \
		-activebackground [modSat $vibe(quitBg) 50] \
		-activeforeground [modSat $vibe(defFg) 100] ]
	pack $stop
	
	set live(current) 1
	
	if { $live(size) == "highQuality" } {
		photopc resolution "Hi"
	} elseif { $live(size) == "standardQuality" } {
		photopc resolution "Lo"
	} else {
		# no op for preview mode
	}
		
	liveUpdate
}

proc liveUpdate {} {
	global live prefs
		
	set time [expr 1000 * [$live(timeAmount) get]]
	set num [format "%04d" $live(current)]
	
	if { $live(mode) == "timeLapse" } {
		set name $prefs(downLoc).$num.jpg
	} else {
		set name $prefs(downLoc).jpg
	}

	progIncr $name

	if { $live(size) != "thumbNail" } {
		photopc snapshot
		set num [photopc count]
		photopc image $num $name
		photopc erase $num
	} else {
		photopc preview $name	
	}

	incr live(current)

	after $time liveUpdate
}

proc liveEnd {} {
	global live prefs
	
	after cancel liveUpdate

	update

	photopc resolution [lindex $prefs(status) 0]
	
	progEnd
}

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

proc getListing {} {
	set txt [photopc list]
	
	set txt [split $txt "\n"]
	
	return [lrange $txt 1 end]
}

proc thumbnail {} {
	global edit
	
	set edit(count) [photopc count]
	progStart $edit(count) "downloading thumbnails"
	
	set listing [getListing]
	
	foreach thumb $edit(thumbs) {
		echo $thumb
		destroy $thumb
	}

	$edit(txt) configure -state normal
	
	$edit(txt) delete 0.0 end
	set edit(thumbs) ""
	
	for { set num 1 } { $num <= $edit(count) } { incr num } {
		progIncr
		set thumb [newThumb $num [lindex $listing $num]]
		lappend edit(thumbs) [thumbName $num]
		
		$edit(txt) insert end "\t"

		# manually put in line breaks		
# 		if { ! [expr $num % 3] } {
# 			$edit(txt) insert end "\n\n"
# 		}
		
		update
	}
		
	$edit(txt) configure -state disabled
	
	progEnd
}

set cimg [image create photo -data {
R0lGODlhDAAOAMYAAP///1dXV1tbQ5STOnJwH0JCQnJycp6ip52gkqysh6uoLEtLS2hoaJaW
lr3Ay5mivZCVppubm4+NGkxMTJGRkVZWVikpKSAhIn2Hp5qamlZVNkdHR5CQkENDQ1Zcb5Wc
sz8/Pzc3N3FxcYmJiTU2OHZ2eVBQUC0tLTAwMElJSTExMY+PPKyqFXJwCZublTQ0NE1NTWZm
ZpKSkpWcrpijwqKstKStn9PRYnNwAHl5eWBmemxxgmduhXR+m8TCboSBACsrK1JSUpWVlbnA
1Y+Ys5+luImYx8TGgX16ACcnJy8vL0BAQD09PicrOHiCoXV9mHSApcPGf3VyAF9fX1VVVWpq
ak5OTm9zfrrA07S0tKGhoaiwxNbXU1hWAB4eHjMzMyIiIjI1OjQ1OJyaEaajKQAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAMAA4AAAeNgACCAAECAwSDiQUGBwgJ
CokACwwNDg8QERKJExQVFhcYGRqJGxwdgh4fIIkhIiOCJCUmgh0WJygpKCoTKywtLi8wBTEb
MjM0NTY3OCEqKAUvOTo7PD0+P0ATGwxBQkNERUZHSEkqSkshTE1OT1BRUkBTVFVWV1hZWltc
XQBeL19gwoipUGEMmUgIBQUCADs=
}]

proc newThumb { index listing } {
	global edit cimg

	set f [frame [thumbName $index] -borderwidth 3 -relief raised]
	
	photopc thumbnail $index [thumbImageName $index]
	
	set img [loadImage [thumbImageName $index]]
# 	set l [label $f.l -image $img]
# 	pack $l -side top
		
	set bmenu $f.bmenu
	set tmenu $bmenu.tmenu

	menubutton $bmenu -menu $tmenu -text "info menu" -image $img
	menu $tmenu -tearoff 0

	$tmenu add command -state disabled -label "size: [lindex $listing 2]"
	$tmenu add command -state disabled -label "res: [lindex $listing 3]"
	$tmenu add command -state disabled -label "flash: [lindex $listing 4]"
	$tmenu add command -state disabled -label "shut: [lindex $listing 5]"
	$tmenu add command -state disabled -label "date: [lrange $listing 6 8], [lindex $listing 10]"
	$tmenu add command -state disabled -label "time: [lindex $listing 9]"
	
	pack $bmenu -side top

	set f2 [frame $f.cbs]
	pack $f2 -side top

	set varName [thumbVarName $index]
	set check [checkbutton [thumbCheckName $index] -text $index -variable $varName]
	global $varName
	set $varName 0
	pack $check -side left

	set lock [checkbutton [thumbCheckName $index]2 -image $cimg \
		-variable [genSym thumb_2]]
	if { [lindex $listing 1] == "P" } {
		$lock select
	}
	$lock configure -command "protect $lock $index"
	pack $lock -side left
		
# 	set info [label [thumbName $index].info -text $infoTxt]
	
	$edit(txt) window create end -window $f

	forWidgetTree defFont $f
	forWidgetTree defColors $f
}

proc thumbName { index } {
	global edit

	return $edit(txt).$index
}

proc thumbImageName { index } {
	global prefs
	
	return $prefs(tmpDir)/thumb$index.jpt
}

proc thumbVarName { index } {
	return thumbVal$index
}

proc thumbCheckName { index } {
	global edit
	
	return [thumbName $index].cbs.cb
}

proc getSelectedThumbs {} {
	global edit

	set selects ""

	for { set num 1 } { $num <= $edit(count) } { incr num } {
		global [thumbVarName $num]
		
		eval set val $[thumbVarName $num]
		
		if { $val == 1 } {
			lappend selects $num
		}
	}
	
	return $selects
}

proc selectAll {} {
	global edit
	
	set end [llength $edit(thumbs)]
	for { set num 1 } { $num <= $end } { incr num } {
		[thumbCheckName $num] select
	}
}

proc askDownloadLocation { { badSeed "image" } } {
	global prefs tcl_version
	
	if { $tcl_version < 8.0 } {
		set prefs(downLoc) [pwd]/$badSeed
	} else {
		set prefs(downLoc) [tk_getSaveFile \
				-title "select download directory and file name prefix"]
	}
		
	return $prefs(downLoc)
}

proc getDownloadName {} {
	global prefs
	
	set num [format "%04d" $prefs(cur)]
	
	return $prefs(downLoc).$num.jpg
}

proc downloadSelected {} {
	global prefs

	set thumbs [getSelectedThumbs]
	if { $thumbs == "" } return

	if { [askDownloadLocation] == "" } return
	
	progStart [llength $thumbs] "downloading files"

	# temporary place to put files until we put up a dialog
	foreach num $thumbs {
		set name [getDownloadName]
		progIncr $name
		photopc image $num $name
		incr prefs(cur)
	}
	
	progEnd
}

proc downloadAll {} {
	global prefs

	if { [askDownloadLocation] == "" } return
	
	set count [photopc count]
	progStart $count "downloading all pictures"
	
	for { set num 0 } { $num <= $count } { incr num } {
		set name [getDownloadName]
		progIncr $name
		photopc image $num $name
		incr prefs(cur)
	}
	
	progEnd
}

proc deleteSelected {} {
	global prefs

	set thumbs [lsort -decreasing -integer [getSelectedThumbs]]
	progStart [llength $thumbs] "deleting files"
	
	foreach thumb $thumbs {
		progIncr
		photopc erase $thumb
	}
	
	progEnd
	
	thumbnail
}

proc deleteAll {} {
	global prefs
	
	progStart 2 "deleting files"
	progIncr
	
	photopc eraseall
	
	progEnd
	
	thumbnail
}

proc protect { widget index } {

	set varName [$widget cget -variable]
	global $varName
	eval set val $$varName
		
	if { $val == 1 } {
		photopc protect $index on
	} else {
		photopc protect $index off
	}
}

#####################################################################
# util funcs

proc rgbColor { xcolor } {
	set txt [string range $xcolor 1 end]
		
	set num [expr 0x$txt + 0]
	
	set rr [expr ( $num & 0xff0000 ) >> 16 ]
	set gg [expr ( $num & 0xff00 ) >> 8 ]
	set bb [expr $num & 0xff]
	
	return "$rr $gg $bb"
}

proc xColor { rr gg bb } {
	return [format "#%02x%02x%02x" $rr $gg $bb]
}

proc min { a b } {
	if { $a < $b } {
		return $a
	} else {
		return $b
	}
}

proc max { a b } { 
	if { $a > $b } {
		return $a
	} else {
		return $b
	}
}

proc clampColor { what } {
	set what [min 255 $what]
	set what [max 0 $what]
	return $what
}

proc modSat { xcolor { howMuch 25 } } {
# 	echo in $xcolor
	set rgb [rgbColor $xcolor]
	
	set rr [clampColor [expr [lindex $rgb 0] + $howMuch]]
	set gg [clampColor [expr [lindex $rgb 1] + $howMuch]]
	set bb [clampColor [expr [lindex $rgb 2] + $howMuch]]
	
	set xcolor [xColor $rr $gg $bb]
	
# 	echo out $xcolor
	return $xcolor
}

##

set symnum -1
proc genSym { { pre sym } } {
	global symnum
	
	incr symnum
	
	return $pre$symnum
}

proc forWidgetTree { procName root args } {
	catch { eval $procName $root $args }

	set kids [winfo children $root]
	foreach kid $kids {	
		forWidgetTree $procName $kid $args
	}
}

proc echo { args } {
	global prefs
	
	if { $prefs(dbg) } { puts "$args" }
}

proc tabButtonName { bname } {
	global frames
	
	return $frames(tabs).$bname
}

proc frameName { frameIn } {
	global frames

	set ind -1
	switch -- $frameIn {
		edit {
			set ind 0
		}
		live {
			set ind 1
		}
		prefs {
			set ind 2
		}
		about {
			set ind 3
		}
		quit {
			set ind 4
		}
		default {
			set ind -1
			puts "bogus frameName call for $frameIn"
		}
	}
	
	return [lindex $frames(frames) $ind]
	
# 	return .hidden.$frameIn
# 	return .$frameIn
}

proc activateFrame { pageObj } {
	global frames
	
	set frameName [[$pageObj getObj] getText]

	set procName ${frameName}Exposed
	if { [info procs $procName] != {} } {
		$procName
	}
}

proc getProgGeom { widget } {
	set geom [winfo geometry $widget]
	
	scan $geom "%dx%d+%d+%d" ww hh xx yy
	
	set xc [expr int($xx + $ww / 2.0)]
	set yc [expr int($yy + $hh / 2.0)]
	
	set wide 250
	set high 75
	
	incr xc [expr $wide / -2 ]
	incr yc [expr $high / -2 ]
	
	return "${wide}x${high}+$xc+$yc"
}

proc progStart { max { txt "progress:" } } {
	global progWidget progScale progMax progCur
	
	set progWidget [toplevel .prog]
	wm geometry $progWidget [getProgGeom .]
	wm title $progWidget $txt
	
	update
	
	grab set $progWidget
	
	set progMax $max
	set progCur 0
	
	set progScale [scale $progWidget.scl -from 0 -to $progMax -variable progCur \
		 -orient horizontal]
#		-label $txt
	pack $progScale -fill both -expand 1
	
	forWidgetTree defFont $progWidget
	forWidgetTree defColors $progWidget
	
	update
}

proc progIncr { { txt "" } } {
	global progWidget progMax progCur progScale
	
	# first set of scale
	incr progCur			
	# redundant set of scale
	$progScale set $progCur 
	$progScale config -label $txt
	update
}

proc progEnd {} {
	global progWidget progCur
	
	grab release $progWidget
	destroy $progWidget
	update
}

proc addLabel { name txt { side left } } {
	set lab [label $name.[genSym label] -text $txt]
	pack $lab -side $side
	return $lab
}

proc addFrame { parent { packInfo "-side top -expand 1 -fill x -anchor w" } } {
	set fr [frame $parent.[genSym frame] -borderwidth 5]
	eval pack $fr $packInfo
	return $fr
}

proc addOption { parent lab variable args } {
	addLabel $parent $lab

	set name $parent.[genSym option]
	
# 	eval echo $variable
	eval tk_optionMenu $name $variable $args
	pack $name -side left
	
	return $name
}

proc addEntry { parent lab } {
	addLabel $parent $lab
	set name $parent.[genSym entry]
	
	entry $name
	pack $name -side left
	
	return $name
}

proc addButton { parent lab command } {
	set name [button $parent.[genSym button] -text $lab -command $command]
	pack $name -side left
	
	return $name
}

#####################################################################
# image procs

proc convert { from to } {
	if { [catch { exec djpeg -fast -pnm -outfile $to $from } ] != 0 } {
		bgerror "Could not execute 'convert' application.\n\
See '.phototk' preference file for more info on \
setting a preferred convert application."
	}
}

proc loadImage { name } {
	global prefs
	
# 	set fullName $prefs(tmpDir)/$name
	set fullName $name
	
	if { ! [file exists $fullName] } {
		echo "could not find file $fullName"
		bgerror "could not find file $fullName"
	}
	
	set root [file rootname $fullName]
	set dst $root.ppm
	
# 	if { ! [file exists $dst] } {
		$prefs(convert) $fullName $dst
# 	}
	
	set imgName [image create photo -file $dst]
	
	return $imgName
}

#####################################################################
# camera procs

proc photopc { args } {
	global prefs

	if { $prefs(dbg) } { 
		set verbose "-v"
	} else {
		set verbose ""
	}

 	catch { 
		eval echo $prefs(photopc) -q -l $prefs(device) -s $prefs(baud) $args
		set good [eval exec $prefs(photopc) -q -l $prefs(device) -s $prefs(baud) $args]
	} bad
	
# 	echo $good
	echo $bad
	
	return $bad
}

#####################################################################
# main

proc usage { argv } {
	global device
	
}

proc main { argv } {
	usage $argv

	wm geometry . 476x435
	wm minsize . 476 435

	initFrames
	initAbout
	initEdit
	initLive
	initPrefs
	initQuit

	initVibe

	initMisc
	
	update
	
# 	activateFrame edit
}

main $argv
