#!/bin/bash -a
# Screencast Creator v1.5
# Copyright (C) 2010, 2015, 2016 - James Budiono, (C) 2016 SFR
# License: GPL vesion 3 - see http://www.gnu.org/licenses/gpl.html
# uses: gtkdialog, Xdialog, ffmpeg
# update 1.1 - make it compatible with ffmpeg 0.9.1 in Fatdog64 600
# update 1.2 - update defaults with more sensible values - tested with vlc 2.01 and ffmpeg 0.11.1
# update 1.3 - supports custom resolution with xrectsel, need gtkdialog-r514
# update 1.4 - make it work with ffmpeg 2.8.4
# update 1.5 - SFR: re-designed GUI
# update 1.6 - step/SFR: GUI update, add session settings and improve Finish dialog
# update 1.7 - step: support creating GIF automatically, using togif.sh
#
# use bash to export functions to gtkdialog

#xrandr | 
#sed -n '/Screen/ {s/.*current \(.* x .*\),.*/\1/; s/\([0-9]*\) x \([0-9]*\)/\1 \2/p}' | 
#while read HORZ VERT
#do
#	echo $HORZ
#	echo $VERT
#done

export TEXTDOMAIN=fatdog
export OUTPUT_CHARSET=UTF-8

# constant definitions - these are modifiable through Advanced Options
APPTITLE="Screencast Creator"
APPVERSION=1.7
PREPARE_TIME=5
AUDIO_DEVICE=hw:0,0
MAX_AUDIO_CHANNEL=2
AUDIO_CHANNEL=$MAX_AUDIO_CHANNEL
MIN_FRAME_RATE=10
FRAME_RATE=$MIN_FRAME_RATE
DEFAULT_OUT_FILE=/tmp/out_%F_%H%M%S # filename always gets date(1) time-format expanded, FAT fs doesn't like %T

# variable definitions
FFMPEG_PID=
FFMPEG_ARGS=

SCREEN_RES=
QUALITY=
FORMAT=
TARGET_RES=
VIDEO_CODEC=
VIDEO_BITRATE=
VIDEO_BIT_TOLERANCE=
VIDEO_OPTION=
AUDIO_CODEC=
AUDIO_BITRATE=
AUDIO_SAMPLERATE=
AUDIO_FORMAT=
CONV_FILTER=

UPTIME=0
RECENT_SETTINGS=$HOME/.screencast.set

# Some gettext strings need to be pre-processed and put into variables,
# because <comboboxtext> returns item's contents, so we have to compare string-to-string
STR_ENTIRE_DESKTOP_FULL="$(gettext "Entire desktop")"
STR_ENTIRE_DESKTOP_HALF="$(gettext "Entire desktop, half resolution")"
STR_ENTIRE_DESKTOP_QUARTER="$(gettext "Entire desktop, quarter resolution")"
STR_SELECTED_AREA="$(gettext "Selected area")"

STR_QUALITY_LOW="$(gettext "Low quality (small file size)")"
STR_QUALITY_MEDIUM="$(gettext "Medium quality (medium file size)")"
STR_QUALITY_HIGH="$(gettext "High quality (large file size)")"
STR_QUALITY_CUSTOM="$(gettext "Custom quality")"

# Preset settings
# MP4
AUDIO_BITRATE_MP4_LOW=4
AUDIO_SAMPLERATE_MP4_LOW=11025
VIDEO_BITRATE_MP4_LOW=32
VIDEO_BIT_TOLERANCE_MP4_LOW=32

AUDIO_BITRATE_MP4_MEDIUM=4
AUDIO_SAMPLERATE_MP4_MEDIUM=11025
VIDEO_BITRATE_MP4_MEDIUM=64
VIDEO_BIT_TOLERANCE_MP4_MEDIUM=64

AUDIO_BITRATE_MP4_HIGH=8
AUDIO_SAMPLERATE_MP4_HIGH=22050
VIDEO_BITRATE_MP4_HIGH=128
VIDEO_BIT_TOLERANCE_MP4_HIGH=128

# AVI
AUDIO_BITRATE_AVI_LOW=8
AUDIO_SAMPLERATE_AVI_LOW=11025
VIDEO_BITRATE_AVI_LOW=64
VIDEO_BIT_TOLERANCE_AVI_LOW=32

AUDIO_BITRATE_AVI_MEDIUM=8
AUDIO_SAMPLERATE_AVI_MEDIUM=11025
VIDEO_BITRATE_AVI_MEDIUM=128
VIDEO_BIT_TOLERANCE_AVI_MEDIUM=128

AUDIO_BITRATE_AVI_HIGH=16
AUDIO_SAMPLERATE_AVI_HIGH=22050
VIDEO_BITRATE_AVI_HIGH=256
VIDEO_BIT_TOLERANCE_AVI_HIGH=256

# function definitions
function set_value_resolution {
	case "$RESOLUTION" in
		"$STR_ENTIRE_DESKTOP_FULL")		get_screen_resolution && echo "${SCREEN_RES}+0+0"	;;
		"$STR_ENTIRE_DESKTOP_HALF")		get_screen_resolution && get_half_resolution		;;
		"$STR_ENTIRE_DESKTOP_QUARTER")	get_screen_resolution && get_quarter_resolution		;;
		"$STR_SELECTED_AREA")			choose_region										;;
	esac
}

function set_value_quality {
	case "$1" in
		video_bitrate)
			if [ "$FORMAT_MP4" = "true" ]; then
				case "$QUALITY" in
					"$STR_QUALITY_LOW")		echo "${VIDEO_BITRATE_MP4_LOW}"		;;
					"$STR_QUALITY_MEDIUM")	echo "${VIDEO_BITRATE_MP4_MEDIUM}"	;;
					"$STR_QUALITY_HIGH")	echo "${VIDEO_BITRATE_MP4_HIGH}"	;;
				esac
			else	# AVI
				case "$QUALITY" in
					"$STR_QUALITY_LOW")		echo "${VIDEO_BITRATE_AVI_LOW}"		;;
					"$STR_QUALITY_MEDIUM")	echo "${VIDEO_BITRATE_AVI_MEDIUM}"	;;
					"$STR_QUALITY_HIGH")	echo "${VIDEO_BITRATE_AVI_HIGH}"	;;
				esac
			fi
		;;
		video_bit_tolerance)
			if [ "$FORMAT_MP4" = "true" ]; then
				case "$QUALITY" in
					"$STR_QUALITY_LOW")		echo "${VIDEO_BIT_TOLERANCE_MP4_LOW}"		;;
					"$STR_QUALITY_MEDIUM")	echo "${VIDEO_BIT_TOLERANCE_MP4_MEDIUM}"	;;
					"$STR_QUALITY_HIGH")	echo "${VIDEO_BIT_TOLERANCE_MP4_HIGH}"		;;
					# special case for invisible <comboboxtext>, to keep it in sync with VIDEO_BITRATE
					"$STR_QUALITY_CUSTOM")	echo "${VIDEO_BITRATE}"						;;
				esac
			else	# AVI
				case "$QUALITY" in
					"$STR_QUALITY_LOW")		echo "${VIDEO_BIT_TOLERANCE_AVI_LOW}"		;;
					"$STR_QUALITY_MEDIUM")	echo "${VIDEO_BIT_TOLERANCE_AVI_MEDIUM}"	;;
					"$STR_QUALITY_HIGH")	echo "${VIDEO_BIT_TOLERANCE_AVI_HIGH}"		;;
					# special case for invisible <comboboxtext>, to keep it in sync with VIDEO_BITRATE
					"$STR_QUALITY_CUSTOM")	echo "${VIDEO_BITRATE}"						;;
				esac
			fi
		;;
		audio_bitrate)
			if [ "$FORMAT_MP4" = "true" ]; then
				case "$QUALITY" in
					"$STR_QUALITY_LOW")		echo "${AUDIO_BITRATE_MP4_LOW}"		;;
					"$STR_QUALITY_MEDIUM")	echo "${AUDIO_BITRATE_MP4_MEDIUM}"	;;
					"$STR_QUALITY_HIGH")	echo "${AUDIO_BITRATE_MP4_HIGH}"	;;
				esac
			else	# AVI
				case "$QUALITY" in
					"$STR_QUALITY_LOW")		echo "${AUDIO_BITRATE_AVI_LOW}"		;;
					"$STR_QUALITY_MEDIUM")	echo "${AUDIO_BITRATE_AVI_MEDIUM}"	;;
					"$STR_QUALITY_HIGH")	echo "${AUDIO_BITRATE_AVI_HIGH}"	;;
				esac
			fi
		;;
		audio_samplerate)
			if [ "$FORMAT_MP4" = "true" ]; then
				case "$QUALITY" in
					"$STR_QUALITY_LOW")		echo "${AUDIO_SAMPLERATE_MP4_LOW}"		;;
					"$STR_QUALITY_MEDIUM")	echo "${AUDIO_SAMPLERATE_MP4_MEDIUM}"	;;
					"$STR_QUALITY_HIGH")	echo "${AUDIO_SAMPLERATE_MP4_HIGH}"		;;
					# without it <comboboxtext> defaults to 1st value
					"$STR_QUALITY_CUSTOM")	echo "${AUDIO_SAMPLERATE}"				;;
				esac
			else	# AVI
				case "$QUALITY" in
					"$STR_QUALITY_LOW")		echo "${AUDIO_SAMPLERATE_AVI_LOW}"		;;
					"$STR_QUALITY_MEDIUM")	echo "${AUDIO_SAMPLERATE_AVI_MEDIUM}"	;;
					"$STR_QUALITY_HIGH")	echo "${AUDIO_SAMPLERATE_AVI_HIGH}"		;;
					# without it <comboboxtext> defaults to 1st value
					"$STR_QUALITY_CUSTOM")	echo "${AUDIO_SAMPLERATE}"				;;
				esac
			fi
		;;
	esac
}

function get_screen_resolution() {
	read HORZ VERT <<EOF
		$(xrandr | sed -n '/Screen/ {s/.*current \(.* x .*\),.*/\1/; s/\([0-9]*\) x \([0-9]*\)/\1 \2/p}')
EOF
	SCREEN_RES=${HORZ}x${VERT}
}

function get_half_resolution() {
	local tgt_horz
	tgt_horz=$(($HORZ/2))
	[ $(($tgt_horz % 2)) -eq 1 ] && tgt_horz=$(( tgt_horz + 1))
	TARGET_RES=$(($tgt_horz))x$(($VERT/2))
	echo ${TARGET_RES}+0+0
}

function get_quarter_resolution() {
	local tgt_horz
	tgt_horz=$(($HORZ/4))
	[ $(($tgt_horz % 2)) -eq 1 ] && tgt_horz=$(( tgt_horz + 1))	
	TARGET_RES=$(($tgt_horz))x$(($VERT/4))
	echo ${TARGET_RES}+0+0
}

function get_dialog_geometry() {
	xwininfo -root -tree |
	awk '/\x22'"$APPTITLE"'\x22.+gtkdialog/ {
		print "GEOMETRY=\""$(NF-1)"\" TOPLEFT=\""$(NF)"\""
	}'
}
export -f get_dialog_geometry

function show_about() {
	Xdialog --title "$APPTITLE" \
	--msgbox "${APPTITLE} v${APPVERSION}\n© James Budiono 2010, 2012, 2015, 2016\n© SFR 2016" 0 0
}

function choose_region() {
	# fallback if xrectsel does not exist
	if ! type xrectsel > /dev/null; then
		echo $VIDEO_RES
	else
		Xdialog --title "$(gettext "Select capture area")" --infobox "\
$(gettext "To select capture area, click left mouse button and hold,
move the mouse, then release button to confirm.
Press OK when ready.")\
" 0 0 10000
#		fi
		xrectsel
	fi
}

function round_to_16() {
	local x y
	x=${1%x*}
	y=${1#*x}
	# round to 16
	#x=$(( (((x+16)/16)*16) ))
	#y=$(( (((y+16)/16)*16) ))
	# round to 2 - SFR
	x=$(( ((x/2)*2) ))
	y=$(( ((y/2)*2) ))
	[ $x -lt 16 ] && x=16
	[ $y -lt 16 ] && y=16
	
	echo ${x}x${y}
	#echo ${x}x${y} > /dev/stderr
}

# show recording options
function show_options_gui() {
	GUI=$([ -e "$RECENT_SETTINGS" ] && . "$RECENT_SETTINGS"
[ "$RESOLUTION" = "$STR_SELECTED_AREA" ] && x=true || x=false
sensitize_VIDEO_RES=$x
default_VIDEO_BITRATE=${VIDEO_BITRATE:-$VIDEO_BITRATE_MP4_MEDIUM}
default_VIDEO_BIT_TOLERANCE=${VIDEO_BIT_TOLERANCE:-$VIDEO_BIT_TOLERANCE_MP4_MEDIUM} # is not visible
default_AUDIO_BITRATE=${AUDIO_BITRATE:-$AUDIO_BITRATE_MP4_MEDIUM}
default_AUDIO_SAMPLERATE=${AUDIO_SAMPLERATE:-$AUDIO_SAMPLERATE_MP4_MEDIUM}
[ "$QUALITY" = "$STR_QUALITY_CUSTOM" ] && x=true || x=false
sensitize_VIDEO_BITRATE=$x
sensitize_VIDEO_BIT_TOLERANCE=$x # is not visible
sensitize_AUDIO_BITRATE=$x
sensitize_AUDIO_SAMPLERATE=$x
cat <<EOV|sed "s/#.*//" # enable interpolation and comments
	<window title="${APPTITLE}" resizable="false" image-name="/usr/share/pixmaps/midi-icons/camera48.png">
		<vbox>
			<frame $(gettext "Output filename")>
				<hbox>
					<button tooltip-text="$(gettext "Start Recording")" stock-icon-size="1">
						<input file stock="gtk-media-record"></input>
						<action>get_dialog_geometry</action>
						<action>exit:record</action>
					</button>
          <entry accept="savefilename" is-focus="true" tooltip-text="$(gettext "Tip: file name expands date(1) formats.")">
						<variable>FILE_SAVEFILENAME</variable>
						<default>${FILE_SAVEFILENAME:-$DEFAULT_OUT_FILE}</default>
					</entry>
					<button>
						<input file stock="gtk-open"></input>
						<variable>FILE_BROWSE_SAVEFILENAME</variable>
						<action type="fileselect">FILE_SAVEFILENAME</action>
					</button>
				</hbox>
				<checkbox>
					<label>$(gettext "Record sound")</label>
					<variable>RECORD_AUDIO</variable>
					<default>${RECORD_AUDIO:-true}</default>
				</checkbox>
			</frame>

			<frame $(gettext "Choose capture area and resolution")>
				<comboboxtext>
					<variable>RESOLUTION</variable>
					<default>${RESOLUTION:-$STR_ENTIRE_DESKTOP_HALF}</default>
					<item>$STR_ENTIRE_DESKTOP_FULL</item>
					<item>$STR_ENTIRE_DESKTOP_HALF</item>
					<item>$STR_ENTIRE_DESKTOP_QUARTER</item>
					<item>$STR_SELECTED_AREA</item>
					<action condition="command_is_true( [ \"\$RESOLUTION\" = \"\$STR_SELECTED_AREA\" ] && echo true )">enable:VIDEO_RES</action>
					<action condition="command_is_true( [ \"\$RESOLUTION\" != \"\$STR_SELECTED_AREA\" ] && echo true )">disable:VIDEO_RES</action>
					<action>refresh:VIDEO_RES</action>
				</comboboxtext>
				<hbox>
				    <text xalign="0"><label>$(gettext "Capture area:") </label></text>
				    <text space-fill="true" space-expand="true"><label>""</label></text>
					<entry accept="customres" sensitive="$sensitize_VIDEO_RES">
						<variable>VIDEO_RES</variable>
						<default>${VIDEO_RES:-$DEFAULT_RESOLUTION}</default>
						<input>set_value_resolution</input>
					</entry>
				</hbox>
			</frame>
			
			<frame $(gettext "Choose quality")>
				<comboboxtext>
					<variable>QUALITY</variable>
					<default>${QUALITY:-$STR_QUALITY_MEDIUM}</default>
					<item>$STR_QUALITY_LOW</item>
					<item>$STR_QUALITY_MEDIUM</item>
					<item>$STR_QUALITY_HIGH</item>
					<item>$STR_QUALITY_CUSTOM</item>

					<action condition="command_is_true( [ \"\$QUALITY\" = \"\$STR_QUALITY_CUSTOM\" ] && echo true )">enable:VIDEO_BITRATE</action>
					<action condition="command_is_true( [ \"\$QUALITY\" = \"\$STR_QUALITY_CUSTOM\" ] && echo true )">enable:AUDIO_BITRATE</action>
					<action condition="command_is_true( [ \"\$QUALITY\" = \"\$STR_QUALITY_CUSTOM\" ] && echo true )">enable:AUDIO_SAMPLERATE</action>

					<action condition="command_is_true( [ \"\$QUALITY\" != \"\$STR_QUALITY_CUSTOM\" ] && echo true )">disable:VIDEO_BITRATE</action>
					<action condition="command_is_true( [ \"\$QUALITY\" != \"\$STR_QUALITY_CUSTOM\" ] && echo true )">disable:AUDIO_BITRATE</action>
					<action condition="command_is_true( [ \"\$QUALITY\" != \"\$STR_QUALITY_CUSTOM\" ] && echo true )">disable:AUDIO_SAMPLERATE</action>

					<action>refresh:VIDEO_BITRATE</action>
					<action>refresh:VIDEO_BIT_TOLERANCE</action>
					<action>refresh:AUDIO_BITRATE</action>
					<action>refresh:AUDIO_SAMPLERATE</action>
				</comboboxtext>
				<hbox>
					<text xalign="0"><label>$(gettext "Video/Audio bitrate (kb/s):") </label></text>
					<text space-fill="true" space-expand="true"><label>""</label></text>
					<spinbutton range-min="1" range-max="4096" range-step="1">
						<variable>VIDEO_BITRATE</variable>
						<sensitive>$sensitize_VIDEO_BITRATE</sensitive>
						<default>${default_VIDEO_BITRATE//k/}</default>
						<input>set_value_quality video_bitrate</input>
						<action>refresh:VIDEO_BIT_TOLERANCE</action>	# sync with VIDEO_BIT_TOLERANCE
					</spinbutton>
					<text><label>/</label></text>
					<spinbutton range-min="1" range-max="320" range-step="1">
						<variable>AUDIO_BITRATE</variable>
						<sensitive>$sensitize_AUDIO_BITRATE</sensitive>
						<default>${default_AUDIO_BITRATE//k/}</default>
						<input>set_value_quality audio_bitrate</input>
					</spinbutton>
				</hbox>
				<hbox>
					<text xalign="0"><label>$(gettext "Audio samplerate (Hz):") </label></text>
					<text space-fill="true" space-expand="true"><label>""</label></text>
					<comboboxtext>
						<variable>AUDIO_SAMPLERATE</variable>
						<sensitive>$sensitize_AUDIO_SAMPLERATE</sensitive>
						<default>${default_AUDIO_SAMPLERATE//k/}</default>
						<item>11025</item>
						<item>22050</item>
						<item>44100</item>
						<item>48000</item>
						<input>set_value_quality audio_samplerate</input>
					</comboboxtext>
				</hbox>
				<hbox visible="false">
					<text xalign="0"><label>$(gettext "Video bit tolerance (kb/s):") </label></text>
					<text space-fill="true" space-expand="true"><label>""</label></text>
					<spinbutton range-min="1" range-max="4096" range-step="1">
						<variable>VIDEO_BIT_TOLERANCE</variable>
						<sensitive>$sensitize_VIDEO_BIT_TOLERANCE</sensitive>
						<default>${default_VIDEO_BIT_TOLERANCE//k/}</default>
						<input>set_value_quality video_bit_tolerance</input>
					</spinbutton>
				</hbox>
			</frame>

			<frame $(gettext "Choose format")>
					<radiobutton>
						<variable>FORMAT_MP4</variable>
						<label>$(gettext "Linux (MP4) - smaller file size")</label>
						<default>${FORMAT_MP4:-true}</default>
						<action>refresh:VIDEO_BITRATE</action>
						<action>refresh:VIDEO_BIT_TOLERANCE</action>
						<action>refresh:AUDIO_BITRATE</action>
						<action>refresh:AUDIO_SAMPLERATE</action>
					</radiobutton>
					<radiobutton>
						<variable>FORMAT_AVI</variable>
						<label>$(gettext "Windows compatible (AVI) best for Avidemux")</label>
						<default>${FORMAT_AVI:-false}</default>
						<action>refresh:VIDEO_BITRATE</action>
						<action>refresh:VIDEO_BIT_TOLERANCE</action>
						<action>refresh:AUDIO_BITRATE</action>
						<action>refresh:AUDIO_SAMPLERATE</action>
					</radiobutton>
					<checkbox>
						<label>$(gettext "Also create animated image (GIF)")</label>
						<variable>TO_GIF</variable>
						<default>${TO_GIF:-false}</default>
					</checkbox>
			</frame>
			
			<expander expanded="false" label-fill="true">
				<frame $(gettext "Miscellaneous options")>
					<vbox>		
						<hbox>
							<text xalign="0"><label>$(gettext "FPS:")</label></text>
							<text space-fill="true" space-expand="true"><label>""</label></text>
							<spinbutton range-min="$MIN_FRAME_RATE" range-max="60" range-step="1">
								<variable>FRAME_RATE</variable>
								<input>echo ${FRAME_RATE:-$MIN_FRAME_RATE}</input>
							</spinbutton>
					
							<vseparator></vseparator>
	
							<text xalign="0"><label>$(gettext "Audio channels:")</label></text>
							<text space-fill="true" space-expand="true"><label>""</label></text>
							<spinbutton range-min="1" range-max="$MAX_AUDIO_CHANNEL" range-step="1">
								<variable>AUDIO_CHANNEL</variable>
								<input>echo ${AUDIO_CHANNEL:-$MAX_AUDIO_CHANNEL}</input>
							</spinbutton>	
						</hbox>
						<hseparator></hseparator>
						<hbox>
							<text xalign="0"><label>$(gettext "X display to capture from:")</label></text>
							<text space-fill="true" space-expand="true"><label>""</label></text>
							<entry width-request="50">
								<variable>XDISPLAY_NUMBER</variable>
								<input>echo $DISPLAY</input>
							</entry>	
						</hbox>
						<hbox>
							<text xalign="0"><label>$(gettext "Audio device for recording:")</label></text>
							<text space-fill="true" space-expand="true"><label>""</label></text>
							<entry width-request="50">
								<variable>AUDIO_DEVICE</variable>
								<input>echo $AUDIO_DEVICE</input>
							</entry>				
						</hbox>
						<hseparator></hseparator>
						<hbox>
							<text xalign="0"><label>$(gettext "Recording dialog:")</label></text>
							<text space-fill="true" space-expand="true"><label>""</label></text>
							<radiobutton>
							  <variable>RECORD_WINDOW</variable>
							  <default>${RECORD_WINDOW:-true}</default>
							  <label>$(gettext "Window")</label>
							</radiobutton>
							<radiobutton>
							  <label>$(gettext "Tray icon")</label>
							  <variable>RECORD_ICON</variable>
							  <default>${RECORD_ICON:-false}</default>
							</radiobutton>
						</hbox>
					</vbox>
				</frame>
				<label>$(gettext "Show/hide more options")</label>
			</expander>

			<hseparator></hseparator>
				
			<hbox space-fill="true" space-expand="true">	
				<text xalign="0"><label>$(gettext "Wait")</label></text>
				<spinbutton range-min="0" range-max="600" range-step="1" range-value="${PREPARE_TIME:-$PREPARE_TIME}">
					<variable>PREPARE_TIME</variable>
				</spinbutton>
				<text><label>$(gettext "seconds before starting to record")</label></text>
			</hbox>	

			<hseparator></hseparator>

			<hbox>
				<button>
					<variable>ABOUT_BUTTON</variable>
					<input file stock="gtk-about"></input>
					<label>$(gettext "About")</label>
					<action>show_about</action>				
				</button>			
				<button cancel></button>
				<button>
					<variable>RECORD_BUTTON</variable>
					<input file stock="gtk-media-record"></input>
					<label>$(gettext "Start Recording")</label>
					<action>get_dialog_geometry</action>				
					<action type="exit">record</action>				
				</button>
			</hbox>
		</vbox>
	</window>

EOV
	);
	
	OUT="$(gtkdialog --program=GUI)"
	#echo "$OUT" >&2
	case $OUT in
		*EXIT=?record*)
			echo "$OUT" > "$RECENT_SETTINGS"
	esac
	eval "$OUT"
	FILE_SAVEFILENAME="${FILE_SAVEFILENAME%/*}/$(date "+${FILE_SAVEFILENAME##*/}")"
}

function show_record_gui() {
	TIME_START=$(date -u +%s)
	GUI='
	<window title="'$(gettext "Capturing")'" resizable="false" image-name="/usr/share/pixmaps/midi-icons/camera48.png">
		<vbox>
			<frame '$(gettext "Recording in progress")'>
				<hbox homogeneous="false">
					<button stock-icon-size="1" tooltip-text="'$(gettext "Finish")'">
						<input file stock="gtk-media-stop"></input>
						<action>exit:Finish</action>
					</button>
					<entry editable="false" xalign="0.5" width-chars="10">
						<variable>UPTIME_MSG</variable>
						<input>date -u -d @$(( $(date -u +%s) - $TIME_START )) +%H:%M:%S</input>
					</entry>
					<entry editable="false" xalign="0.5" width-chars="10" tooltip-text="'"$FILE_SAVEFILENAME"'">
						<variable>FILESIZE</variable>
						<input>echo -n "$( [ $RECORD_AUDIO = "true" ] && du -h -c "'"$FILE_SAVEFILENAME"'.video" "'"$FILE_SAVEFILENAME"'.audio" | tail -n 1 | cut -f1 || du -h -c "'"$FILE_SAVEFILENAME"'" | tail -n 1 | cut -f1 )"</input>
					</entry>
				</hbox>
				<timer interval="1" visible="false">
					<action>refresh:UPTIME_MSG</action>
				</timer>
				<timer interval="3" visible="false">
					<action>refresh:FILESIZE</action>
				</timer>
			</frame>
		</vbox>
	</window>
'
	gtkdialog --program=GUI -G $TOPLEFT
}

function show_record_icon() {
	TOOLTIP="/tmp/screencast_tooltip_${USER}"
	FINISH_MARK="/tmp/screencast_finish_${USER}"
	: > "${TOOLTIP}"
	rm -f "${FINISH_MARK}"
	
	sit /usr/share/pixmaps/mini-icons/mini-record.xpm "${TOOLTIP}" "touch ${FINISH_MARK}" "touch ${FINISH_MARK}" &
	SIT_PID=$!

	TIME_START=$(date -u +%s)
	
  local one=0
	while [ ! -f "${FINISH_MARK}" ]; do
	  echo -e "$(gettext "Recording in progress, click to finish.")\n" > "${TOOLTIP}"
	  echo "$(gettext "Uptime"): $(date -u -d @$(( $(date -u +%s) - $TIME_START )) +%H:%M:%S)" >> "${TOOLTIP}"
	  echo "$(gettext "Output size"): $( [ $RECORD_AUDIO = "true" ] && du -h -c "$FILE_SAVEFILENAME.video" "$FILE_SAVEFILENAME.audio" | tail -n 1 | cut -f1 || du -h -c "$FILE_SAVEFILENAME" | tail -n 1 | cut -f1 )" >> "${TOOLTIP}"
    echo -n "$FILE_SAVEFILENAME" >> "${TOOLTIP}"
    sleep 1
	done
	
	kill $SIT_PID
	rm -f "${TOOLTIP}" "${FINISH_MARK}"
}

function checkfile_exist() {
	local user home
	# expand tilde
	if [[ "$FILE_SAVEFILENAME" == \~* ]]; then # note: bashisms
		user=${FILE_SAVEFILENAME%%/*}; user=${user:1}/
		eval home=$(printf "~%q" "$user")
		FILE_SAVEFILENAME="$home${FILE_SAVEFILENAME#*/}"
	fi

	# append the correct extension
	FILE_SAVEFILENAME="${FILE_SAVEFILENAME%.*}.${FORMAT}"
	
	if [ -f "$FILE_SAVEFILENAME" ]; then
		if ! Xdialog --title WARNING --yesno "$FILE_SAVEFILENAME $(gettext "already exist.")\n$(gettext "Are you sure you want to overwrite?")" 0 0; then
			exit
		fi
	fi
}

function parse_options() {
	# 1. get the source and target resolution
	get_screen_resolution
	SOURCE_RES=$SCREEN_RES
	TARGET_RES=$(round_to_16 ${VIDEO_RES%%+*})	
	SOURCE_ORG=${VIDEO_RES#*+}
	SOURCE_ORG=${SOURCE_ORG/+/,}

	if [ "$RESOLUTION" = "$STR_SELECTED_AREA" ]; then
		SOURCE_RES=$TARGET_RES
	fi
	[ $FRAME_RATE -le $MIN_FRAME_RATE ] && FRAME_RATE=$MIN_FRAME_RATE

	# 2. format
	if [ $FORMAT_AVI = "true" ]; then 	
		FORMAT=avi
	elif [ $FORMAT_MP4 = "true" ]; then 
		FORMAT=mp4
	fi 

	# 3. quality
	AUDIO_BITRATE=${AUDIO_BITRATE}k
	AUDIO_SAMPLERATE=${AUDIO_SAMPLERATE}   # no k, is this right? # SFR: yes, samplerate must be a "pure" number
	VIDEO_BITRATE=${VIDEO_BITRATE}k
	VIDEO_BIT_TOLERANCE=${VIDEO_BIT_TOLERANCE}k
	
	# 4. combination of quality and format
	case $FORMAT in
		mp4)
			VIDEO_CODEC=libx264
			VIDEO_OPTION="-preset slow -force_fps -pix_fmt yuv420p "
			AUDIO_CODEC=libfaac
			AUDIO_FORMAT=dts
			CONV_FILTER='-bsf:a aac_adtstoasc '
		;;
		avi)
			VIDEO_CODEC=wmv1
			VIDEO_OPTION=
			AUDIO_CODEC=libmp3lame
			AUDIO_FORMAT=mp3
			CONV_FILTER=
		;;
	esac

	# 5. build the ffmpeg args 
	FFMPEG_VIDEO_ARGS="-y -f x11grab -s $SOURCE_RES -r $FRAME_RATE -i ${XDISPLAY_NUMBER}+${SOURCE_ORG} \
					   -r $FRAME_RATE -vcodec $VIDEO_CODEC -s $TARGET_RES -b:v $VIDEO_BITRATE -bt $VIDEO_BIT_TOLERANCE $VIDEO_OPTION -f $FORMAT "
	FFMPEG_AUDIO_ARGS="-y -f alsa -ac $AUDIO_CHANNEL -i $AUDIO_DEVICE -r $FRAME_RATE \
					   -acodec $AUDIO_CODEC -ar $AUDIO_SAMPLERATE -ab $AUDIO_BITRATE -f $AUDIO_FORMAT"
	
	#echo "$FFMPEG_ARGS"
}

function start_recording() {
	parse_options
	checkfile_exist
	sleep $PREPARE_TIME  # wait a while to let user prepare
	
	# all set, now go !
	if [ $RECORD_AUDIO = "true" ]; then	
		ffmpeg $FFMPEG_VIDEO_ARGS "$FILE_SAVEFILENAME".video &
		FFMPEG_VIDEO_PID=$!	
		ffmpeg $FFMPEG_AUDIO_ARGS "$FILE_SAVEFILENAME".audio &
		FFMPEG_AUDIO_PID=$!
	else
		ffmpeg $FFMPEG_VIDEO_ARGS "$FILE_SAVEFILENAME" &
		FFMPEG_VIDEO_PID=$!
	fi
	
	# wait for 1 seconds, see if it is successful
	sleep 1
	if ! [ -e /proc/$FFMPEG_VIDEO_PID ]; then
		[ $RECORD_AUDIO = "true" ] && pkill -INT -P $FFMPEG_AUDIO_PID
		Xdialog --title "$(gettext "ERROR")" --msgbox "$(gettext "Screen capture failed.\nTo see error messages run again in a terminal:\n")$0 -d" 0 0
		exit
	fi
}

function finish_recording() {
	local ret
	pkill -INT -P $FFMPEG_VIDEO_PID
	if [ $RECORD_AUDIO = "true" ]; then	
		pkill -INT -P $FFMPEG_AUDIO_PID
		# join video and audio
		Xdialog --title "$APPTITLE" --no-buttons --infobox "$(gettext "Joining video and audio, please wait ...")" 0 0 1000000 &
		XPID=$!
 		# wait for ffmpegs to stop
		sleep 3
		ffmpeg -y -i "$FILE_SAVEFILENAME".video -i "$FILE_SAVEFILENAME".audio \
			-acodec copy -vcodec copy $CONV_FILTER -f $FORMAT "$FILE_SAVEFILENAME"
		ret=$?
		[ 0 = $ret ] && rm -f "$FILE_SAVEFILENAME".video "$FILE_SAVEFILENAME".audio
		kill $XPID
	fi	
	return $ret
}

function postprocessing() {
	local ret gif
	! [ -f "$FILE_SAVEFILENAME" ] && return
	sleep 1
	gif="${FILE_SAVEFILENAME%.*}.gif"
	if [ "$TO_GIF" = true ]; then
    # IN OUT SCALE(300) QUALITY(low,lowers,high,high2)
		togif.sh "$FILE_SAVEFILENAME" "$gif"
		ret=$?
	fi
	[ 0 = "$ret" ] &&
    echo "\n\n$(gettext "GIF animation saved in:\n")$gif\n\n$(gettext "For higher quality run:")\ntogif.sh"
	return $ret
}

# ==== main ====
if [ "$1" = "-d" ]; then
	echo "Debug mode - ffmpeg output to terminal."
else
	exec < /dev/null > /dev/null 2>&1 # enable it to run in the background
fi
DEFAULT_RESOLUTION="$(get_screen_resolution && get_half_resolution)" # default
show_options_gui;
if [ $EXIT = "record" ]; then
	start_recording
	if [ "$RECORD_WINDOW" = "true" ]; then
	  show_record_gui
	else
	  show_record_icon
	fi
	finish_recording &&
		msg="$(gettext "Done! Screencast is saved in:")\n$FILE_SAVEFILENAME" ||
		msg="$(gettext "Done with errors. Partial tracks are salvaged as:")\n$FILE_SAVEFILENAME.{video,audio}"
	msg="${msg}$(postprocessing)"
	Xdialog --title "$APPTITLE" --infobox "$msg" 0 0 10000
fi
