#!/usr/bin/ksh
#
# Use VCR to record TV-programs from TV-card
#
# (c) Peter van Eerten 2006, GPL license
# 
# Tested with:
#   -PDKSH on Zenwalk 3.0
#
# October 7, 2006: Initial release - programmed on a rainy saturday in only a few hours time :-)
#-------------------------------------------------------------------------------------------------

# Create embedded GTK functions
if [[ ! -f /etc/gtk-server.cfg ]]
then
    print "No GTK-server configfile found! Please install GTK-server..."
    exit 1
elif [[ ! -f $HOME/.gtk4korn || /etc/gtk-server.cfg -nt $HOME/.gtk4korn ]]
then
    print "# Embedded GTK functions for KornShell" > $HOME/.gtk4korn
    while read LINE
    do
	if [[ $LINE == +(*FUNCTION_NAME*) ]]
	then
	    TMP=${LINE#*= }
	    print "function ${TMP%%,*}" >> $HOME/.gtk4korn
	    print "{\nprint -p ${TMP%%,*} \$@" >> $HOME/.gtk4korn
	    print "read -p GTK\n}" >> $HOME/.gtk4korn
	fi
    done < /etc/gtk-server.cfg
fi
NULL="NULL"

# Check if VCR is installed
VCR=`which vcr 2>/dev/null`
if [[ -z $VCR ]]
then
    echo "VCR not found on your system!"
    echo "Get it from http://www.stack.nl/~brama/vcr/"
    echo "Exiting..."
    exit 1
fi

# Check if the 'at' scheduler is installed
AT=`which at 2>/dev/null`
if [[ -z $AT ]]
then
    echo "The AT scheduler was not found on your system!"
    echo "Exiting..."
    exit 1
fi
ATRM=`which atrm 2>/dev/null`

# Check if a volume mixer is installed
AUMIX=`which aumix 2>/dev/null`
if [[ -z $AUMIX ]]
then
    echo "No MIXER found on your system!"
    echo "Cannot set recording volume. Please install 'aumix'."
    echo "Exiting..."
    exit 1
fi

ATFILE=/tmp/at.txt
LOG=/tmp/log.txt

# Include embedded GTK for KornShell
. $HOME/.gtk4korn

# Start GTK-server
gtk-server stdin cfg=/etc/gtk-server.cfg |&

# Define GUI
gtk_init $NULL $NULL
# Window
gtk_window_new 0
WINDOW=$GTK
gtk_window_set_title $WINDOW "'KSH TV-program Recorder'"
gtk_window_set_position $WINDOW 1
gtk_widget_set_size_request $WINDOW 350 230
gtk_window_set_resizable $WINDOW 0
gtk_table_new 50 50 1
TABLE=$GTK
gtk_container_add $WINDOW $TABLE
# date time Length
gtk_combo_box_new_text
DATE_MONTH=$GTK
gtk_table_attach_defaults $TABLE $DATE_MONTH 3 18 10 17
gtk_combo_box_append_text $DATE_MONTH "January"
gtk_combo_box_append_text $DATE_MONTH "February"
gtk_combo_box_append_text $DATE_MONTH "March"
gtk_combo_box_append_text $DATE_MONTH "April"
gtk_combo_box_append_text $DATE_MONTH "May"
gtk_combo_box_append_text $DATE_MONTH "June"
gtk_combo_box_append_text $DATE_MONTH "July"
gtk_combo_box_append_text $DATE_MONTH "August"
gtk_combo_box_append_text $DATE_MONTH "September"
gtk_combo_box_append_text $DATE_MONTH "October"
gtk_combo_box_append_text $DATE_MONTH "November"
gtk_combo_box_append_text $DATE_MONTH "December"
let MONTH=`date +%m`-1
gtk_combo_box_set_active $DATE_MONTH $MONTH
gtk_spin_button_new_with_range 1 31 1
DATE_DAY=$GTK
gtk_table_attach_defaults $TABLE $DATE_DAY 19 24 10 18
gtk_spin_button_set_value $DATE_DAY `date +%d`
gtk_spin_button_set_wrap $DATE_DAY 1
gtk_spin_button_new_with_range 0 23 1
DATE_HOUR=$GTK
gtk_table_attach_defaults $TABLE $DATE_HOUR 27 32 10 18
gtk_spin_button_set_value $DATE_HOUR `date +%H`
gtk_spin_button_set_wrap $DATE_HOUR 1
gtk_spin_button_new_with_range 0 59 1
DATE_MINUTE=$GTK
gtk_table_attach_defaults $TABLE $DATE_MINUTE 32 37 10 18
gtk_spin_button_set_value $DATE_MINUTE `date +%M`
gtk_spin_button_set_wrap $DATE_MINUTE 1
gtk_spin_button_new_with_range 1 180 1
DATE_LENGTH=$GTK
gtk_table_attach_defaults $TABLE $DATE_LENGTH 40 47 10 18
gtk_spin_button_set_value $DATE_LENGTH 30
gtk_frame_new
DATE_FRAME=$GTK
gtk_table_attach_defaults $TABLE $DATE_FRAME 1 49 1 22
gtk_frame_set_label $DATE_FRAME "'  Select date, time and length  '"
# Channels
gtk_combo_box_new_text
CHANNEL_COMBO=$GTK
gtk_table_attach_defaults $TABLE $CHANNEL_COMBO 3 19 31 37
while read LINE
do
    if [[ $LINE != "[defaults]" && $LINE = +(*\]*) ]]
    then
	g_locale_to_utf8 "'$LINE'" -1 $NULL $NULL $NULL
	gtk_combo_box_append_text $CHANNEL_COMBO "'$GTK'"
    fi
done < $HOME/.vcrrc
gtk_combo_box_set_active $CHANNEL_COMBO 0
gtk_frame_new
CHANNEL_FRAME=$GTK
gtk_table_attach_defaults $TABLE $CHANNEL_FRAME 1 21 24 40
gtk_frame_set_label $CHANNEL_FRAME "'  Select channel  '"
# Entry for filename
gtk_entry_new
NAME_ENTRY=$GTK
gtk_table_attach_defaults $TABLE $NAME_ENTRY 24 47 31 37
gtk_entry_set_text $NAME_ENTRY "$HOME/out.avi"
gtk_frame_new
NAME_FRAME=$GTK
gtk_table_attach_defaults $TABLE $NAME_FRAME 22 49 24 40
gtk_frame_set_label $NAME_FRAME "'  Output filename  '"
# Buttons
gtk_button_new_with_label "Exit"
EXIT_BUTTON=$GTK
gtk_table_attach_defaults $TABLE $EXIT_BUTTON 41 49 42 49
gtk_button_new_with_label "Schedule"
RECORD_BUTTON=$GTK
gtk_table_attach_defaults $TABLE $RECORD_BUTTON 1 11 42 49
gtk_button_new_with_label "About"
ABOUT_BUTTON=$GTK
gtk_table_attach_defaults $TABLE $ABOUT_BUTTON 32 40 42 49
gtk_button_new_with_label "'List all'"
SCHEDULE_BUTTON=$GTK
gtk_table_attach_defaults $TABLE $SCHEDULE_BUTTON 12 20 42 49
gtk_widget_show_all $WINDOW
# Create ABOUT box
gtk_server_version
TMP="\t***  KSH Video Recorder ***\r\rRunning ${KSH_VERSION#*)} with GTK-server $GTK.\r\r Visit http://www.gtk-server.org/ for more info!"
gtk_message_dialog_new $WINDOW 0 0 2 "'$TMP'" "''"
DIALOG=$GTK
# Create warning
gtk_message_dialog_new $WINDOW 0 3 2 "'Output file already exists!\r\rEnter a different filename.'" "''"
WARNING=$GTK
# Create message
gtk_message_dialog_new $WINDOW 0 0 2 "'Your recording was scheduled.'" "''"
READY=$GTK
# Window for schedule overview
gtk_window_new 0
SCHED_WIN=$GTK
gtk_window_set_title $SCHED_WIN "'Scheduled recordings'"
gtk_widget_set_size_request $SCHED_WIN 300 200
gtk_window_set_resizable $SCHED_WIN 1
gtk_window_set_transient_for $SCHED_WIN $WINDOW
gtk_window_set_position $SCHED_WIN 4
# Presets
gtk_frame_new
SCHED_ITER=$GTK
gtk_list_store_new 1 64
SCHED_LST=$GTK
gtk_tree_view_new_with_model $SCHED_LST
SCHED_CHOICE=$GTK
gtk_server_connect $SCHED_CHOICE "button-press-event" $SCHED_CHOICE 1
gtk_tree_view_set_headers_visible $SCHED_CHOICE 0
gtk_tree_view_get_selection $SCHED_CHOICE
SCHED_SEL=$GTK
gtk_cell_renderer_text_new
SCHED_CELL=$GTK
gtk_tree_view_column_new_with_attributes "Instance" $SCHED_CELL "text" 0 $NULL
SCHED_COLUMN=$GTK
gtk_tree_view_append_column $SCHED_CHOICE $SCHED_COLUMN
gtk_tree_view_column_set_resizable $SCHED_COLUMN 1
gtk_tree_view_column_set_clickable $SCHED_COLUMN 1
gtk_scrolled_window_new $NULL $NULL
SCHED_SW=$GTK
gtk_scrolled_window_set_policy $SCHED_SW 1 1
gtk_scrolled_window_set_shadow_type $SCHED_SW 1
gtk_container_add $SCHED_SW $SCHED_CHOICE
gtk_button_new_with_label "Delete"
SCHED_DEL=$GTK
gtk_widget_set_size_request $SCHED_DEL 60 30
gtk_button_new_with_label "Exit"
SCHED_EXIT=$GTK
gtk_widget_set_size_request $SCHED_EXIT 60 30
gtk_hseparator_new
SCHED_SEP=$GTK
gtk_hbox_new 0 0
SCHED_HBOX=$GTK
gtk_box_pack_start $SCHED_HBOX $SCHED_DEL 0 0 1
gtk_box_pack_end $SCHED_HBOX $SCHED_EXIT 0 0 1
gtk_vbox_new 0 0
SCHED_VBOX=$GTK
gtk_box_pack_start $SCHED_VBOX $SCHED_SW 1 1 1
gtk_box_pack_start $SCHED_VBOX $SCHED_SEP 0 0 1
gtk_box_pack_start $SCHED_VBOX $SCHED_HBOX 0 0 1
gtk_container_add $SCHED_WIN $SCHED_VBOX

# Mainloop
while [[ $EVENT -ne $WINDOW && $EVENT -ne $EXIT_BUTTON ]]
do

    gtk_server_callback "wait"
    EVENT=$GTK

    case $GTK in

	# Record button is pressed
	$RECORD_BUTTON)
	    gtk_combo_box_get_active $DATE_MONTH
	    case $GTK in
		0) REC_MONTH="JAN";;
		1) REC_MONTH="FEB";;
		2) REC_MONTH="MAR";;
		3) REC_MONTH="APR";;
		4) REC_MONTH="MAY";;
		5) REC_MONTH="JUN";;
		6) REC_MONTH="JUL";;
		7) REC_MONTH="AUG";;
		8) REC_MONTH="SEP";;
		9) REC_MONTH="OCT";;
		10) REC_MONTH="NOV";;
		11) REC_MONTH="DEC";;
	    esac
	    gtk_spin_button_get_value_as_int $DATE_DAY
	    REC_DAY=$GTK
	    gtk_spin_button_get_value_as_int $DATE_HOUR
	    REC_HOUR=$GTK
	    if [[ $REC_HOUR -lt 10 ]]
	    then
		REC_HOUR=0$REC_HOUR
	    fi
	    gtk_spin_button_get_value_as_int $DATE_MINUTE
	    REC_MINUTE=$GTK
	    if [[ $REC_MINUTE -lt 10 ]]
	    then
		REC_MINUTE=0$REC_MINUTE
	    fi
	    gtk_spin_button_get_value_as_int $DATE_LENGTH
	    REC_LEN=$GTK
	    gtk_entry_get_text $NAME_ENTRY
	    REC_FILE=$GTK
	    gtk_combo_box_get_active_text $CHANNEL_COMBO
	    REC_CHANNEL=${GTK#\[}
	    if [[ -f $REC_FILE ]]
	    then
		gtk_widget_show $WARNING
	    else
		$AUMIX -l 100
		$AUMIX -l R
		echo "$VCR -t ${REC_LEN}m -p ${REC_CHANNEL%\]} ${REC_FILE} 1>>/tmp/log.txt 2>/dev/null" | at ${REC_HOUR}:${REC_MINUTE} ${REC_MONTH} ${REC_DAY} > $LOG 2>&1
		if [[ `cat $LOG` != +(*error*) && `cat $LOG` != +(*refusing*) ]]
		then
		    gtk_widget_show $READY
		fi
	    fi;;

	# Check the ABOUT button
	$ABOUT_BUTTON)
	    gtk_widget_show $DIALOG;;

	# Check if the dialog was closed
	$DIALOG)
	    gtk_widget_hide $DIALOG;;

	# Check if warning was closed
	$WARNING)
	    gtk_widget_hide $WARNING;;

	# Check if the message was closed
	$READY)
	    gtk_widget_hide $READY;;

	# Check if the ScheduleWindow must be shown
	$SCHEDULE_BUTTON)
	    gtk_list_store_clear $SCHED_LST
	    $AT -l > $ATFILE
	    while read LINE
	    do
		gtk_list_store_append $SCHED_LST $SCHED_ITER
		gtk_list_store_set $SCHED_LST $SCHED_ITER 0 "'$LINE'" -1
	    done < $ATFILE
	    gtk_widget_show_all $SCHED_WIN;;

	# Check if a schedule should be removed
	$SCHED_DEL)
	    NR=0
	    while read LINE
	    do
		gtk_tree_path_new_from_string $NR
		PTH=$GTK
		gtk_tree_selection_path_is_selected $SCHED_SEL $PTH
		ROW=$GTK
		gtk_tree_path_free $PTH
		if [[ $ROW = "1" ]]
		then
		    break
		else
		    ((NR+=1))
		fi
	    done < $ATFILE

	    # Remove the schedule
	    $ATRM ${LINE%%[A-Z]*}

	    # Build the list again
	    gtk_list_store_clear $SCHED_LST
	    $AT -l > $ATFILE
	    while read LINE
	    do
		gtk_list_store_append $SCHED_LST $SCHED_ITER
		gtk_list_store_set $SCHED_LST $SCHED_ITER 0 "'$LINE'" -1
	    done < $ATFILE ;;

	# Check if the message was closed
	$SCHED_EXIT)
	    gtk_widget_hide $SCHED_WIN;;

    esac
done

# Delete temporary files
rm -f $ATFILE
rm -f $LOG

gtk_server_exit
