#!/usr/bin/wish

#####################################################
# qvplaytk:
#
# Graphical interface for qvplay build using Tcl/Tk.
#
# by T.Amano 
# (e-mail:me-ta@usa.net)
# Version 0.73c Last update 97/12/30.
#
# Tested environment is
# Linux 2.0.30 on PC/AT clone
# Tk 4.0 Tcl 7.4
# Tk 4.1 Tcl 7.5
#####################################################

##################################################
# default value settings. need change.
##################################################

set speed normal
set ttydev /dev/ttyS0
set defname qv
set format jpg
set sTime 4

##################################################
# get enviroment variable QVPLAYTTY
##################################################
 catch {set ttydev $env(QVPLAYTTY)}

##################################################
# Pre process.
##################################################

# exec setserial $ttydev spd_vhi
set tk_strictMotif 1

##################################################
# Default value setting.
##################################################

set defmode g

##################################################
# Procedure define.
##################################################

#
# Make dir.
#
proc mdir {} {
    exec sh -c "mkdir ~/.qv_thum"
}

#
# Count *.ppm files.
#

proc cdir {} {
    set after 1
    set pwdir [pwd]
    cd
    cd .qv_thum
    if {[file exists thum_001.ppm]} {
	set filenum [eval exec ls -1 [glob thum_*.ppm] | wc -l]
    	regsub -all {[^0-9]} $filenum "" after
    	cd $pwdir
    	return $after
    } else {
    	cd $pwdir
	return 0
    }
}

#
# Thumbnail get.
#

proc thumbget {startnum endnum} {
    global speed ttydev
    set pwdir [pwd]
    cd
    exec qvplay -o ".qv_thum/thum" -S $speed -s $startnum -e $endnum -F ppm -a -D $ttydev
    cd $pwdir
    reset
}

#
# Thumbnail delete.
#
proc thumbdel {} {
    exec sh -c "rm ~/.qv_thum/*.ppm"
}


#
# New commands define.
#

proc l_entry {path text length} {
    frame $path
    label $path.text  -text $text
    entry $path.entry -width $length -relief sunken
    pack  $path.text  -side left -pady 1m -padx 1m -fill x
    pack  $path.entry -side right -pady 1m -padx 1m -fill x
}

proc buildwin {window title text bcolor fcolor} {
    toplevel .$window
    wm title .$window $title
    message .$window.msg -width 8c -justify left -relief ridge -bd 2\
	    -text $text
    pack .$window.msg
    .$window.msg configure -background $bcolor -foreground $fcolor
    return 1
}

#
# Check value.
#

proc checkval {widget} {
    set number [.$widget get]
    set status [regexp {^[0-9]+$} $number]
    if {$status} {
	return 1
    } else {
	set before [.$widget get]
	regsub -all {[^0-9]} $before "" after
	.$widget delete 0 end
	.$widget insert 0 $after
	set before [.$widget get]
    }
}

#
# Overflow check.
#

proc checkover {value} {
    set allnum [setpic]
    if {$value > $allnum} {
	set value $allnum
    }
    return $value
}

#
# Reset QV.
#

proc reset {} {
    exec qvplay -r
}

#
# Get how many picture.
#

proc setpic {} {
    set picnumber [exec qvplay -n]
    set i 0
    .reset.howManyPic.button config -text "$picnumber"
    regsub -all {[^0-9]} $picnumber "" i
    return $i
}

#
# Exec xv with image in temporary DIR.
#
proc xvdisplay {i} {
    global format defname speed ttydev
    set format "jpg"
    set pwdir [pwd]
    cd
    cd .qv_thum
    if {[file exists temp_[format "%03d" $i].jpg]} {
	exec xv -4x3 temp_[format "%03d" $i].jpg &
    } else {
	exec qvplay -s $i -e $i -o temp -S $speed -F $format -a -D $ttydev
	exec xv -4x3 temp_[format "%03d" $i].jpg &
    }
    cd $pwdir
}

 
#
# Flash thumbnails.
#

proc thumbflash {} {
    set allnum [setpic]
    set thumnum [cdir]
    if {$thumnum < $allnum} {
	thumbget [expr $thumnum +1] $allnum
    }
    if {$thumnum > $allnum} {
	thumbdel
	thumbget 1 $allnum
    }
    destroy .thumbnailWin
    thumbnail
}

#
# Make thumbnail window.
#

proc thumbnail {} {
    set w "thumbnailWin"
    set c "thumbnailWin.canvas"
    set thumnum [cdir]
    toplevel .$w
    wm title .$w "Thumbnails"
    frame .$w.button -relief groove -borderwidth 2
    button .$w.button.close -text "Close" -command {
	destroy .thumbnailWin
    }
    button .$w.button.flash -text "Flash" -command {
	thumbflash
    }
    button .$w.button.thumbdel -text "thumbnail delete" -command {
	thumbdel
	destroy .thumbnailWin
    }
    pack .$w.button  -side bottom -fill x
    pack .$w.button.close .$w.button.flash .$w.button.thumbdel -side left -padx 5m -pady 2m

    set yregion [expr $thumnum / 2 + 1]
    scrollbar .$w.vscroll -command ".$c yview"
    canvas .$c -relief sunken -borderwidth 2 -scrollregion\
	    "0c 0c 0c ${yregion}c" -yscrollcommand\
	    ".$w.vscroll set"
    .$c configure -background grey80
    for {set y 1; set i 1} {$i <= $thumnum} {incr y 1} {
	for {set x 1} {$x <= 9 && $i <= $thumnum} {incr x 2; incr i} {
	    image create photo ppmthum$i -file\
		    ~/.qv_thum/thum_[format "%03d" $i].ppm
	    button .$c.ppm$i -image ppmthum$i -command "
		.numOfDl.start.entry delete 0 end
		.numOfDl.start.entry insert 0 $i
	    "
	    bind .$c.ppm$i <Double-Button-1> "
	        xvdisplay $i
	    "
	    bind .$c.ppm$i <Button-2> "
		.numOfDl.end.entry delete 0 end
		.numOfDl.end.entry insert 0 $i
	    "
	    bind .$c.ppm$i <Button-3> "
		.numOfDisp.text.entry delete 0 end
		.numOfDisp.text.entry insert 0 $i
		showpic
	    "
	    .$c create window ${x}c [expr $y * 2 - 1]c -window .$c.ppm$i
	    .$c create text ${x}c [expr $y * 2]c -text "$i"
	}
    }
    pack .$w.vscroll -side right -fill y
    pack .$c -expan 1 -fill both
}

#
# Get Picture.
#

proc getpicture {} {
    global defname speed ttydev format
    checkval numOfDl.start.entry
    checkval numOfDl.end.entry
    set startnum [.numOfDl.start.entry get]
    set endnum [.numOfDl.end.entry get]
    set savename [.nameField.dl.entry get]
    if {$savename == "\0"} {
	set savename $defname
    }
    set startnum [checkover $startnum]
    set endnum [checkover $endnum]
    if {$endnum == "\0" && $startnum == "\0"} {
	exec qvplay -o $savename -S $speed -F $format -a -D $ttydev
	return 1
    }
    if {$endnum != "\0"} {
	if {$startnum != "\0"} {
	    exec qvplay -o $savename -S $speed -s $startnum -e $endnum -F $format -a -D $ttydev
	} else {
	    set startnum 1
	    exec qvplay -o $savename -S $speed -s $startnum -e $endnum -F $format -a -D $ttydev
	}
    } else {
	exec qvplay $savename -S $speed -s $startnum -e $startnum -F $format -a -D $ttydev
    }
}

#
# Show picture.
#

proc showpic {} {
    checkval numOfDisp.text.entry
    set shownum [.numOfDisp.text.entry get]
    if {$shownum != "\0"} {
	set shownum [checkover $shownum]
	exec qvplay -p $shownum
	return $shownum
    } else {
	return 0
    }
}

#
# Delete picture.
#

proc delpic {} {
    set delnum [showpic]
    if {$delnum} {
	exec qvplay -d $delnum
	reset
	showpic
	setpic
    }
}

#
# Protect & Unprotect picture.
#

proc protpic {status} {
    set protnum [showpic]
    if {$protnum} {
	if {$status} {
	    exec qvplay -P $protnum
	} else {
	    exec qvplay -U $protnum
	}
    }
}

#
# Take pictuire.
#

proc takepicture {} {
    global sTime
    checkval takePara.loop.entry
    checkval takePara.sleep.entry
    set looptime [.takePara.loop.entry get]
    set sleeptime [.takePara.sleep.entry get]
    if {$looptime == 1 || $looptime == "\0"} {
	if {$sleeptime != "\0"} {
	    exec sleep $sleeptime
	    exec qvplay -t
	} else {
	    exec qvplay -t
	}
	    reset
    } else {
	exec qvplay -t
	reset
	while {$looptime > 1} {
	    incr looptime -1
	    if {$sleeptime != "\0"} {
		exec sleep $sleeptime
	    } else {
		exec sleep $sTime
	    }
	    exec qvplay -t
	    reset
	}
    }
    setpic
    reset
}

#
# Value clear.
#

proc valclear {mode} {
    switch $mode {
	g {
	    foreach widget {nameField.dl numOfDl.start numOfDl.end} {
		.$widget.entry delete 0 end
	    }
	}
	s {
	    .numOfDisp.text.entry delete 0 end
	}
	t {
	    .takePara.loop.entry delete 0 end
	    .takePara.sleep.entry delete 0 end
	}
    }
}

#
# Create windows.
#

proc createwin {} {
    pack .title -pady 2m
    pack .reset -padx 1m -pady 1m
    pack .thumbnail -padx 1m -pady 1m
    pack .selecter -pady 1m
    pack .subframe -pady 1m
    pack .borderButton -padx 1m -pady 2m -ipadx 10m
}

proc createsubwin {mode} {
    switch $mode {
	g {
	    pack .format -in .subframe -padx 1m -pady 1m -expand 1 -fill x
	    pack .formatOfPic -in .format -expand 1 -fill x
	    pack .formatOfPicthum -in .format -expand 1 -fill x
	    pack .nameField -in .subframe -pady 1m
	    pack .numOfDl -in .subframe -padx 1m -pady 1m
	    pack .getPic -in .subframe -padx 1m -pady 2m
	}
	s {
	    pack .numOfDisp -in .subframe -padx 1m -pady 1m
	    pack .protPic -in .subframe -padx 1m -pady 1m
	    pack .delPic -in .subframe -pady 2m -padx 1m
	}
	t {
	    pack .takePara -in .subframe -padx 1m -pady 1m
	    pack .takePic -in .subframe
	}
    }
}

###################################################
# define windows.
###################################################

#
# Title.
#
  frame .title -borderwidth 4 -relief ridge
  label .title.text -text "qvplaytk : Graphical interface for qvplay. $ttydev"
  pack  .title.text

  frame .subframe -borderwidth 1 -relief ridge

#
# Common operation mode.
#

  frame  .reset
  button .reset.button -text "Reset QV."
  pack   .reset.button -padx 3m -side left

  frame  .reset.howManyPic -borderwidth 2 -relief groove
  button .reset.howManyPic.button -text "pictures = 0" -width 17
  pack   .reset.howManyPic.button -side top
  pack   .reset.howManyPic

  frame   .thumbnail -borderwidth 2 -relief groove
  button  .thumbnail.button -text "Show thumbnails"
  pack    .thumbnail.button -pady 1m -padx 1m

  frame  .selecter -borderwidth 3 -relief groove
  label  .selecter.text -text "Select operation mode"
  button .selecter.getI -text "G"
  button .selecter.disp -text "S"
  button .selecter.take -text "T"
  pack   .selecter.text -side top
  pack   .selecter.getI .selecter.disp .selecter.take -side left -padx 7m -pady 1m -ipadx 2m

#
# Get picture mode.
#

  frame .format -borderwidth 1 -relief ridge

  frame .formatOfPic
  label .formatOfPic.text -text "Download format."
  radiobutton .jpg -text "jpg" -variable format -value jpg
  radiobutton .cam -text "cam" -variable format -value cam
  radiobutton .bMP -text "BMP" -variable format -value BMP
  radiobutton .pPM -text "PPM" -variable format -value PPM
  radiobutton .rGB -text "RGB" -variable format -value RGB
  pack  .formatOfPic.text -side top
  pack  .jpg .cam .bMP .pPM .rGB -padx 1m -pady 2m -in .formatOfPic -side left -expand 1 -fill x

  frame .formatOfPicthum
  label .formatOfPicthum.text -text "Thumbnails :"
  radiobutton .bmp -text "bmp" -variable format -value bmp
  radiobutton .ppm -text "ppm" -variable format -value ppm
  radiobutton .rgb -text "rgb" -variable format -value rgb
  pack  .formatOfPicthum.text -side left
  pack  .rgb .ppm .bmp -padx 1m -pady 2m -in .formatOfPicthum -side right -anchor e

  frame   .nameField -borderwidth 1 -relief ridge
  l_entry .nameField.dl "Name of download picture: " 12
  pack    .nameField.dl

  frame .numOfDl -borderwidth 1 -relief ridge
  l_entry .numOfDl.start "Start number of download picture: " 4
  l_entry .numOfDl.end  "End number of download picture: " 4
  pack    .numOfDl.start .numOfDl.end -side top -anchor e

  frame  .getPic
  button .getPic.button -text "Get Picture"
  pack   .getPic.button

#
# Show & Delete picture mode.
#

  frame   .numOfDisp -borderwidth 2 -relief groove
  l_entry .numOfDisp.text "Picture number on LCD:" 4
  button  .numOfDisp.button -text "Show Picture"
  pack    .numOfDisp.text .numOfDisp.button -pady 2m -padx 1m -side top


  frame   .protPic -borderwidth 2 -relief groove
  button  .protPic.pbutton -text " Protect "
  button  .protPic.ubutton -text "Unprotect"
  pack    .protPic.pbutton .protPic.ubutton -pady 1m -padx 1m -side left

  frame   .delPic
  button  .delPic.button -text "Delete Picture"
  button  .delPic.abutton -text "Delete\nAll Picture"
  pack    .delPic.button -pady 1m
  pack    .delPic.abutton -pady 2m

#
# Take picture mode.
#

  frame   .takePic
  button  .takePic.button -text "Take Picture"
  pack    .takePic.button -pady 3m

  frame   .takePara -borderwidth 2 -relief groove
  l_entry .takePara.loop  "Loop number of take picture: " 8
  l_entry .takePara.sleep "Interval sec of take picture: " 8
  pack    .takePara.loop .takePara.sleep -pady 1m -padx 1m -side top -anchor e

#
# Quit.
#

  frame  .borderButton
  button .borderButton.info -text "Info"
  button .borderButton.clear -text "Clear"
  button .borderButton.quit -text "Quit"
  pack    .borderButton.info .borderButton.clear .borderButton.quit -padx 4m -pady 2m -expand 1 -side left


####################################################
# Object configuration.
####################################################

#
# color setting
#

. configure -background #999399
.subframe configure -background #a0a6a0
.title.text configure -background grey60 -foreground black
.selecter configure -background grey45
.selecter.text configure -background grey45 -foreground white
.reset configure -background grey60
.reset.button configure -background grey80 -foreground black
.reset.howManyPic.button configure -background grey20 -foreground white
.thumbnail.button configure -background #99aabb -foreground black
.getPic.button configure -background #337733 -foreground white
.delPic.button configure -background #773333 -foreground white
.delPic.abutton configure -background #AA3333 -foreground white
.takePic.button configure -background #333377 -foreground white
.borderButton  configure -background grey60

#
# Top button procedure.
#

.reset.button configure -command reset
.reset.howManyPic.button configure -command setpic
.thumbnail.button configure -command {
    if {[file exists ~/.qv_thum] && [file isdirectory ~/.qv_thum]} {
	if {![winfo exists .thumbnailWin]} {
	    if {[cdir] >= 1} {
		thumbnail
	    } else {
		thumbget 1 [setpic]
		thumbnail
	    }
	} else {
	    raise .thumbnailWin
	}
    } elseif {![winfo exists .makedir]} {
	buildwin "makedir" "Make dir" "Warning!\n\n\
		This procedure make working directory\
		for thumbnail on your home directory.\n\n\
		\"~/.qv_thum\"\n\n  OK?" "#773333" "white"
	button .makedir.button -text "OK" -command {
	    destroy .makedir
	    mdir
	}
	button .makedir.cbutton -text "Cancel" -command {
	    destroy .makedir
	}
	pack .makedir.button .makedir.cbutton -side left -padx 3m -pady 3m
    } else {
	raise .makedir
    }
}

#
# Selecter procedure.
#

.selecter.getI configure -command {
    pack forget .numOfDisp .protPic .delPic .takePic .takePara
    set defmode g
    createwin
    createsubwin $defmode
}
.selecter.disp configure -command {
    pack forget .format .nameField .numOfDl .getPic .takePic .takePara
    set defmode s
    createwin
    createsubwin $defmode
}
.selecter.take configure -command {
    pack forget  .numOfDisp .protPic .delPic .format .nameField .numOfDl .getPic
    set defmode t
    createwin
    createsubwin $defmode
}

#
# Get picture procedure.
#

.getPic.button configure -command {
    setpic
    getpicture
}

#
# Show & Delete picture procedure.
#

.numOfDisp.button configure -command {
    showpic
    setpic
}
.protPic.pbutton configure -command {protpic 1}
.protPic.ubutton configure -command {protpic 0}
.delPic.button configure -command delpic
.delPic.abutton configure -command {
    if {![winfo exists .warning]} {
	buildwin "warning" "All delete!" "Warning!\n\n\
		This program delete all pictures\
		in your QV include protected pictures!"\
		"#AA3333" "white"
	button .warning.button -text "OK" -command {
	    destroy .warning
	    exec qvalldel -f -D $ttydev
	    reset
	}
	button .warning.cbutton -text "Cancel" -command {
	    destroy .warning
	}
	pack .warning.button .warning.cbutton -side left -padx 3m -pady 3m
    } else {
	raise .warning
    }
}

#
# Take picture procedure.
#

.takePic.button configure -command takepicture

#
# Common procedure
#

.borderButton.clear configure -comman {valclear $defmode}
.borderButton.info configure -command {
    if {![winfo exists .info]} {
	buildwin "info" "Information of qvplaytk"\
		"qvplaytk:\nGraphical interface for qvplay\
		build using Tcl/Tk.\n\nBy T.Amano\n\
		(me-ta@usa.net)\n\
		Version 0.73c 1997/12/30." "grey80" "black"
	button .info.button -text "Close" -command {
	    destroy .info
	}
	pack .info.button -pady 3m
    } else {
	destroy .info
    }
}
.borderButton.quit configure -command {exit}

##################################################
# Binding Entry.
##################################################

##################################################
# Startup process.
##################################################

createwin
createsubwin $defmode
