
#
#
#  Default bindings
#
#

global avview_bindings avview_bindings_layout avview_video_window_bindings

set avview_bindings {
	"toggle_fullscreen" "<Control-KeyPress-f>"
	"toggle_fullscreen" "<Key-Insert>"
	"next_fav_channel 1" "<Key-KP_Add>"
	"next_fav_channel -1" "<Key-KP_Subtract>"
	"next_fav_channel 1" "<Key-Next>"
	"next_fav_channel -1" "<Key-Prior>"
	"next_channel 1" "<Control-Key-KP_Add>"
	"next_channel -1" "<Control-Key-KP_Subtract>"
	"toggle_mute" "<Key-KP_Multiply>"
	"toggle_mute" "<Key-XF86AudioMute>"
	"exit_avview" "<Control-Key-q>"
	"exit_avview" "<Key-Escape>"
	"remote_power_off" "<Key-XF86PowerOff>"
	"next_encoding 1" "<Control-Key-i>"
	"switch_to_control XV_VOLUME; change_control 1" "<Key-XF86AudioRaiseVolume>"
	"switch_to_control XV_VOLUME; change_control -1" "<Key-XF86AudioLowerVolume>"
	}

set avview_video_window_bindings {
	"input_channel %s %K" <Key> 
	"next_control 1" <ButtonPress-1>
	"change_control -1" <ButtonPress-5>
	"change_control 1" <ButtonPress-4>
	"next_control 1" "<Key-Up>"
	"next_control -1" "<Key-Down>"
	"change_control 1" "<Key-Right>"
	"change_control -1" "<Key-Left>"
	}

set avview_bindings_layout {action default_sequence}

proc assign_default_bindings {} {
global avview_bindings avview_bindings_layout VIDEO_WINDOW avview_video_window_bindings

foreach $avview_bindings_layout $avview_video_window_bindings {
	bind . $default_sequence $action
	}

foreach $avview_bindings_layout $avview_bindings {
	bind all $default_sequence $action
	}
}
	
	
proc toggle_fullscreen {} {
global fullscreen_mode disable_fullscreen_switching
if { $disable_fullscreen_switching } { bell ; return }
if { $fullscreen_mode } {
	set fullscreen_mode false
	} {
	set fullscreen_mode true
	}
}

proc next_channel { dir } {
global current_channel
global current_table

if { [current_connector] != "tuner" } { return }

set CHANNEL_LIST [freq_get_channel_list $current_table]
set num_entries [llength $CHANNEL_LIST]
set current_channel_index [lsearch -exact $CHANNEL_LIST $current_channel]

set new_index [expr ($current_channel_index + $dir) % $num_entries]
set current_channel [lindex $CHANNEL_LIST $new_index]
}

proc next_fav_channel { dir } {
global current_channel

if { [current_connector] != "tuner" } { return }

set current_channel [find_first_favorite_channel $current_channel $dir]
}

proc toggle_mute {} {
global VIDEO_WINDOW
global current_port mute_index
if { $current_port == "none" } { return }
set num_attributes [xv_num_port_attributes $VIDEO_WINDOW $current_port]
if { $mute_index >= 0 } {
	set variable [find_attribute_variable $VIDEO_WINDOW $current_port $mute_index]
	global $variable
	catch {
		if { [xv_getportattribute $VIDEO_WINDOW $current_port "XV_MUTE"] } { set $variable 0 } { set $variable 1 }
		on_attribute_change XV_MUTE $variable a b
		}
	}
}

global avview_controls avview_controls_layout avview_current_control
set avview_controls {
	"XV_VOLUME"  " Volume "
	"XV_BRIGHTNESS" " Brightness "
	"XV_CONTRAST" " Contrast "
	"XV_SATURATION" " Saturation "
	}
set avview_controls_layout { attribute name }
set avview_current_control 0
global control_countdown
set control_countdown 0

proc control_counter {} {
global control_countdown VIDEO_WINDOW
incr control_countdown -1
if { $control_countdown <= 0 } { 
	destroy $VIDEO_WINDOW.control 
	} {
	after 200 control_counter
	}
}

proc display_control { name value min max } {
global VIDEO_WINDOW control_countdown
set C $VIDEO_WINDOW.control
destroy $C
canvas $C -background [$VIDEO_WINDOW cget -background] -borderwidth 0
place $C -relx 0.05 -rely 0.95 -relwidth 0.9 -relheight 0.2 -anchor sw
update
adjust_message_font
$C create text 5 5 -text $name -anchor nw -tag name \
	-fill "#BBBBFF" -font message_font
set bbox [$C bbox name]
$C create rectangle $bbox -fill black -tag name_bkg
$C lower name_bkg
set width [expr 1+[winfo height $C]/100]
set bar_x [expr [lindex $bbox 0]]
$C create rectangle [expr $bar_x+$width/2] [expr [lindex $bbox 3]+2+$width/2] [expr [winfo width $C]-1-$width/2] [expr [winfo height $C]-1-$width/2] \
	-fill "black" -width $width -outline yellow
$C create rectangle [expr $bar_x+$width+1] [expr [lindex $bbox 3]+2+$width+1] [expr ([winfo width $C]-3-$width-$bar_x)*($value-$min)/($max-$min)+$bar_x+1] [expr [winfo height $C]-2-$width] \
	-fill "blue" -width 0
if { $control_countdown <= 0 } { 
	after 300 control_counter
	}
set control_countdown 14
}
	
proc next_control { dir } {
global VIDEO_WINDOW
global current_port
global avview_current_control avview_controls avview_controls_layout
if { $current_port == "none" } { return }
if { [winfo exists $VIDEO_WINDOW.control ] } {
	incr avview_current_control $dir
	}
set N [llength $avview_controls_layout]
set last_control [expr [llength $avview_controls]/$N-1]
if { $avview_current_control < 0 } {
	set avview_current_control $last_control
	}
if { $avview_current_control > $last_control } {
	set avview_current_control 0
	}
set control [lrange $avview_controls [expr $avview_current_control*$N] [expr $avview_current_control*$N+$N-1]]
foreach var $avview_controls_layout value $control {
	set $var $value
	}
set num_attributes [xv_num_port_attributes $VIDEO_WINDOW $current_port]
for {set i 0 } { $i < $num_attributes} { incr i } {
	set attr_name [xv_port_attribute_name $VIDEO_WINDOW $current_port $i]
	if { $attribute == $attr_name } {
		set range [xv_port_attribute_range $VIDEO_WINDOW $current_port $i]
		display_control $name [xv_getportattribute $VIDEO_WINDOW $current_port $attribute] [lindex $range 0] [lindex $range 1]
		update
		return
		}
	}
display_control " $name is unsupported " 0 0 1
}

global change_control_in_progress
set change_control_in_progress false

proc change_control { dir } {
global VIDEO_WINDOW
global current_port
global avview_current_control avview_controls avview_controls_layout
global change_control_in_progress
if { $current_port == "none" } { return }
if { $change_control_in_progress } { return }
set change_control_in_progress true
set N [llength $avview_controls_layout]
set last_control [expr [llength $avview_controls]/$N-1]
set control [lrange $avview_controls [expr $avview_current_control*$N] [expr $avview_current_control*$N+$N-1]]
foreach var $avview_controls_layout value $control {
	set $var $value
	}
set num_attributes [xv_num_port_attributes $VIDEO_WINDOW $current_port]
for {set i 0 } { $i < $num_attributes} { incr i } {
	set attr_name [xv_port_attribute_name $VIDEO_WINDOW $current_port $i]
	if { $attribute == $attr_name } {
		set range [xv_port_attribute_range $VIDEO_WINDOW $current_port $i]
		set value [xv_getportattribute $VIDEO_WINDOW $current_port $attribute]
		set increment [expr round(([lindex $range 1]-[lindex $range 0])*0.025)]
		if { $increment < 1 } { set increment 1 }
		set value [expr $value+$increment*$dir]
		if { $value > [lindex $range 1] } { set value [lindex $range 1] }
		if { $value < [lindex $range 0] } { set value [lindex $range 0] }
		display_control $name  $value [lindex $range 0] [lindex $range 1]
		update
		catch {
			set variable [find_attribute_variable $VIDEO_WINDOW $current_port $i]
			global $variable
			set $variable $value
			on_attribute_change $attribute $variable a b
			}
		set change_control_in_progress false
		return
		}
	}
display_control " unsupported " 0 0 1
set change_control_in_progress false
}

proc switch_to_control {attr} {
global avview_current_control avview_controls avview_controls_layout
set i 0
foreach $avview_controls_layout $avview_controls {
	if { $attribute==$attr } {
		set avview_current_control $i
		change_control 0
		break
		}
	incr i
	}
}

proc switch_to_channel { new_channel } {
global current_channel current_table
foreach channel [freq_get_channel_list $current_table] {
	if { [string equal -nocase $new_channel $channel] } {
		set current_channel $channel
		return
		}
	}
flash_message " No channel $new_channel "
bell
}

global current_ch_input
set current_ch_input ""
global current_ch_number_input
set current_ch_number_input ""

proc input_channel { state keysym} {
global current_ch_input current_ch_number_input

if { ($state & (1<<2)) != 0 } { return }
# translate keypad keysyms
foreach {keysym2 translation} {
	KP_End  1
	KP_Down 2
	KP_Next 3
	KP_Left 4
	KP_Begin 5
	KP_Right 6
	KP_Home 7
	KP_Up 8
	KP_Prior 9
	KP_Insert 0
	} {
	if { $keysym == $keysym2 } {
		set keysym $translation
		break
		}
	}

if { $current_ch_input != "" || ![string is integer -strict $keysym] ||
     $keysym == "apostrophe" } {
	set current_ch_number_input ""
	input_channel_name $keysym
	} else {
	input_channel_number $keysym
	}
}

proc input_channel_name { keysym } {
global current_ch_input current_table
if { $keysym == "Return" || $keysym == "KP_Enter" } {
	if { $current_ch_input == "" } { return }
	switch_to_channel $current_ch_input
	set current_ch_input ""
	return
	}
if { $keysym == "Delete" || $keysym == "KP_Delete" } {
	global current_channel
	flash_message " [get_station_name $current_channel true] "
	set current_ch_input ""
	return
	}
if { $keysym == "BackSpace" } {
	if { $current_ch_input == "" } { 
		return 
		}
	set current_ch_input [string range $current_ch_input 0 end-1]
	flash_message " $current_ch_input "
	return
	}
if { $keysym == "apostrophe" } {
	# Apostrophe is used to indicate start of all-digit channel
	# name. Set current_ch_input to non-empty so that next key is
	# handled by input_channel_name even if it was a digit.
	set current_ch_input " "
	return
	}
# we are only interested in single letters 
if { [string length $keysym] > 1 } { return }
set new_input [string trim "${current_ch_input}$keysym"]
set valid 0
foreach channel [freq_get_channel_list $current_table] {
	if { [regexp -nocase "^$new_input" $channel] } {
		incr valid
		}
	}
if { $valid > 1 } {
	set current_ch_input $new_input
	flash_message " $new_input "
	} \
elseif { $valid == 1 } {
	switch_to_channel $new_input
	set current_ch_input ""	
	} {
	bell
	}
}

proc input_channel_number { keysym } {
global current_ch_number_input current_channel

if { ![string is integer -strict $keysym] || 
     ($current_ch_number_input == "" && $keysym == 0) } {
	return
	}

set new_input "${current_ch_number_input}$keysym"
set new_channel [get_favorite_channel_by_number [expr $new_input-1]]
if { $new_channel == "" } {
	flash_message " No channel $new_input "
	set current_ch_number_input ""
	} else {
	set current_channel $new_channel
	set next_digit "${new_input}0"
	if { [get_favorite_channel_by_number [expr $next_digit-1]] != "" } {
		flash_message " ${new_input}_ "
		set current_ch_number_input $new_input
		after 2000 expire_channel_number_selection
		} else {
		set current_ch_number_input ""
		}
	}
}

proc expire_channel_number_selection {} {
global current_ch_number_input current_channel

set current_ch_number_input ""
flash_message " [get_station_name $current_channel true] "
}

proc toggle_screensaver {} {
global screen_off ts_old_state
if { $screen_off } {
	display_video
	xmisc_setscreensaver . [lindex $ts_old_state 0] \
		[lindex $ts_old_state 1] \
		[lindex $ts_old_state 2] \
		[lindex $ts_old_state 3] \
		[lindex $ts_old_state 4] \
		[lindex $ts_old_state 5] \
		[lindex $ts_old_state 6] \
		0 \
		off
	set screen_off false
	} {
	set ss [xmisc_getscreensaver .]
	set ts_old_state $ss
	after 100
	xmisc_setscreensaver . [lindex $ss 0] \
		[lindex $ss 1] \
		[lindex $ss 2] \
		[lindex $ss 3] \
		1 \
		1 \
		1 \
		3 \
		on
	stop_video
	set screen_off true
	}
}

proc remote_power_off {} {
global fullscreen_mode dpms_off_on_fullscreen_power_off
if { $fullscreen_mode && $dpms_off_on_fullscreen_power_off } {
	toggle_screensaver
	} {
	exit_avview
	}
}

proc change_connector { new_connector } {
global current_encoding_name VIDEO_WINDOW current_port current_connector
if { $current_port == "none" } { return -1 }
switch -glob -- $current_encoding_name {
	"*tuner*"   { set old_part "tuner" }
	"*composite*"   { set old_part "composite" }
	"*svideo*"   { set old_part "svideo" }
	default {
		return -1
		}
	}
set new_enc_name [string map [list $old_part $new_connector] $current_encoding_name]

set ENCODINGS [xv_port_encodings $VIDEO_WINDOW $current_port]
set current_encoding [lsearch $ENCODINGS $new_enc_name]
if { $current_encoding >= 0 } {
	set current_encoding_name $new_enc_name
	set_encoding a b c
	return $current_encoding
	}
return -1
}


#
#  Attempt to load AVview modmap
#
catch {
	exec xmodmap $avview_directory/avview.modmap
	}
