#!/bin/sh
#
# Copyright (c) 1998,1999  Alessandro Rubini  (rubini@linux.it)
# Copyright (c) 1998       Daniel Scharstein  (schar@panther.middlebury.edu)
#
#   This program is free software; you can redistribute it and/or modify
#   it under the terms of the GNU General Public License as published by
#   the Free Software Foundation; either version 2 of the License, or
#   (at your option) any later version.
#
#   This program is distributed in the hope that it will be useful,
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#   GNU General Public License for more details.
#
#   You should have received a copy of the GNU General Public License
#   along with this program; if not, write to the Free Software
#   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#
#

# This program uses gpac if available, wish otherwise \
if [ -f /usr/local/bin/gpac ]; then engine=gpac; else engine=wish; fi

# The following a comment for both tcl interpreters, not for the shell \
exec $engine -f $0 $*

### From now on, the shell doesn't see the code (onlt wish)

# Use the environmente for configuration (not actually used in this version)
set donorm 0;  if [info exists env(ACQUIRE_NORM)]   {set donorm 1}
set dograb 1;  if [info exists env(ACQUIRE_NOGRAB)] {set dograb 0}
set ispacco 0; if [info exist pacco_defaults]       {set ispacco 1}
              if [info exists env(ACQUIRE_PHOTO)]  {set ispacco 0}

# Commandline parsing
set devicefile /dev/pxc0pgm
if {([llength $argv] == 1) && [string match /* $argv]} {
    set devicefile $argv
} elseif [info exists env(PXCDEVICE)] {
    set devicefile $env(PXCDEVICE)
}

# Check whether the device is there
if ![file exists $devicefile] {
    puts stderr "$argv0: $devicefile: No such file or directory"
    exit 1
}

### Ok, we are up and running 
puts "$argv0: using $devicefile"

# I use to "source" this file to interactively test new versions
catch {eval destroy [winfo children .]}
if $ispacco {foreach n [pacco info boxes] {$n destroy}}

# Keep the file open, to maximize perfomance
set keepopen [open $devicefile r]

# Use an external image, as some versions of wish are not able to load from
# a device node.
set imgfile /tmp/bla.pgm
exec cp $devicefile $imgfile

### The procedures

proc LiveGrab {} {
    global LiveVideo devicefile imgfile ispacco
    if !$LiveVideo return
    if $ispacco {
	# Use the pacco way
	img.it import $devicefile
    } else {
	exec cp $devicefile $imgfile
	grabimg config -file $imgfile
    } 
    update
    after 10 LiveGrab
}

proc Run {} {
    global LiveVideo
    set LiveVideo 1
    .f configure -background cyan
    .b.run configure -state disabled
    .b.stop configure -state normal
    .b.save configure -state disabled
    after 10 LiveGrab
}
    
proc Stop {} {
    global LiveVideo devicefile imgfile ispacco
    set LiveVideo 0
    if $ispacco {
	# if we are using pacco, copy the device to an image
	exec cp $devicefile $imgfile
    }
    .f configure -background #aeb2c3
    .b.run configure -state normal
    .b.stop configure -state disabled
    .b.save configure -state normal
}

proc Save {} {
    global LiveVideo imgfile Saving
    if $LiveVideo return
    set Saving 1
    toplevel .w -class Dialog
    wm title .w "Save File"
    frame .w.f
    label .w.f.lab -text "File name:"
    entry .w.f.ent -width 30 -relief sunken -bd 2 -textvariable fname
    pack .w.f.lab .w.f.ent -in .w.f -side left
    button .w.sav -text "Save" -command  {DoSave $fname 0}
    button .w.can -text "Cancel" -command {DoSave "" 0}
    pack .w.f -side top
    pack .w.sav .w.can -side left -expand yes
    bind .w <Return> {DoSave $fname 1}
    set oldFocus [focus]
    grab set .w
    focus .w.f.ent
    tkwait window .w
    focus $oldFocus
    set Saving 0
}

proc DoSave {fname flash} {
    global imgfile
    set msecs 50
    if $flash {
	set msecs 500
    }
    if {$fname == ""} {
	.w.can configure -state active
	set msecs 500
    } else {
	.w.sav configure -state active
	exec cp $imgfile $fname
    }
    after $msecs destroy .w
}
    

proc Quit {} {
    global imgfile
    exec rm -f $imgfile
    exit 0
}


### And the initial setup

if ![file size $imgfile] {
    puts "error in grabbing file"
    Quit
}

# The image frame
pack [frame .f] -side top -expand yes


if $ispacco {
    # Retrieve the image size from the head of the device
    set H [open $devicefile]; gets $H string; close $H
    if [scan  $string "P5 %i %i" x y]==2 {
	obox  img "{Img_byte it $x $y}"
	pacco/display .f.img img.it -padx 2 -pady 2
    } elseif [scan  $string "P6 %i %i" x y]==2 {
	obox  img "{Rgb_byte it $x $y}"
	pacco/display .f.img img.it -padx 2 -pady 2
    } else {
	puts stderr "$argv0: $devicefile is neither pgm nor ppm"
	exit 1
    }    
} else {
    image create photo grabimg  -file $imgfile
    label .f.img -image grabimg -relief ridge -borderwidth 3
    pack .f.img -padx 2 -pady 2

}    

### The control scales
proc More {} {

    toplevel .more
    pack [button .more.close -text "Close" -command "destroy .more"] \
            -side bottom -expand y -fill x

    proc __makeone {varname ctrlget ctrlset text min max} {
	global $varname devicefile
	pack [frame .more.$varname -bd 2 -relief ridge] -padx 2 -pady 2 \
		-expand y -fill both -side left
	pack [label .more.$varname.l -text $text] -side top
	pack [scale .more.$varname.s -orient v -from $min -to $max \
		-command "CtrlSet $ctrlset" -variable $varname] \
		-expand y -fill both
	# Init the $varname to a sane value, by parsing pxc_control output
	puts "pxc_control $devicefile $ctrlget"
	catch "exec pxc_control $devicefile $ctrlget" result
	set value [expr int([lindex [lindex [split $result {\"}] 3] 0])]
	# fix 0..255 to appear as -128..127
	if {$min<0 && $value>127} {set value [expr $value-256]}
	set $varname $value
    }

    __makeone bright getbright setbright Brightness -128 127
    __makeone contrast getcontrast setcontrast Contrast 0 511
    __makeone hue gethue sethue Hue -128 127
    __makeone satu getsatu setsatu "Saturation-U" 0 511
    __makeone satv getsatv setsatv "Saturation-V" 0 511
}

proc CtrlSet {cmd value} {
    global devicefile

    # turn -128..-1 to 128..255
    if {$value<0} {set value [expr $value + 256]}
    exec pxc_control $devicefile $cmd $value 2> /dev/null
}

# Buttons
pack [frame .b] -fill both
button .b.run  -command "Run"  -text "Run"     -disabledforeground #808080
button .b.stop -command "Stop" -text "Stop"    -disabledforeground #808080
button .b.save -command "Save" -text "Save"    -disabledforeground #808080
button .b.more -command "More" -text "More..." -disabledforeground #808080
button .b.quit -command "Quit" -text "Quit"
pack .b.run .b.stop .b.save .b.more .b.quit -side left -expand yes -fill both



bind all <space> {if !$Saving {if $LiveVideo Stop else Run}}
bind all <s> {if !$Saving Save}
bind all <q> {if !$Saving Quit}
bind all <Control-c> {Quit}

set Saving 0
update
Run


