#!/bin/sh
#
# TazBerry - SliTaz Raspberry Pi Config Tool
#
# Copyright (C) 2014 SliTaz ARM - BSD License
# Author: Christophe Lincoln <pankso@slitaz.org>
#
. /lib/libtaz.sh
check_root

title="{ TazBerry }"
config="/boot/config.txt"
tmpdir="/tmp/tazberry"
tmp="$tmpdir/$$"
height="20"
width="72"

# Mirror URL
rpi_mirror="http://mirror.slitaz.org/arm/rpi/"

# Use a tmp directory
mkdir -p ${tmpdir}

# Small built-in help
help() {
	cat << EOT

$(boldify "$(gettext 'Usage:')") $(basename $0) [command|rpi_function]

$(boldify "$(gettext 'Commands:')")
  oclock            $(gettext 'Configure overclocking')
  linux-up          $(gettext 'Update SliTaz R-Pi Linux kernel')
  cam-setup         $(gettext 'Configure your Pi to use the Camera')
  ls-functions      $(gettext 'List TazBerry functions')
  rpi_              $(gettext 'Execute any tazberry_function')
  testsuite         $(gettext 'Run TazBerry testsuite')

EOT
}

#
# RPi functions
#

# This could move to /usr/bin/slitaz-??? or something since it's not
# ARM specific
rpi_stats() {
	ip=$(ifconfig | fgrep -A 1 "encap:Ethernet" | fgrep "inet" | cut -d ":" -f 2)
	mem_total=$(free -m | fgrep "Mem:" | awk '{print $2}')
	mem_used=$(free -m | fgrep "Mem:" | awk '{print $3}')
	mem_used_pct=$(( ( ${mem_used} * 100) / ${mem_total} ))
	cat << EOT
$(gettext 'Kernel')       : $(uname -snrm)
$(gettext 'Uptime')       : $(uptime | awk '{print $3}' | sed s"/:/h /" | sed s"/,/min/")
$(gettext 'Network IP')   : $(echo $ip | awk '{print $1}')
$(gettext 'CPU heat')     : $(awk '{printf "%3.1f C\n", $1/1000}' /sys/class/thermal/thermal_zone0/temp)
$(gettext 'Processes')    : $(ps | wc -l)
$(gettext 'Memory usage') : ${mem_used_pct}%
EOT
}

rpi_turbo() {
	if ! fgrep -q 'force_turbo=1' ${config}; then
		gettext "Enabling Raspberry Pi force turbo..."
		echo "force_turbo=1" >> ${config}; status
	else
		gettext "Disabling Raspberry Pi force turbo..."
		sed -i '/force_turbo=1/'d ${config}; status
	fi
}

# RPi Overclocking
rpi_oclock() {
	cat << EOT
none    700MHz  ARM 250MHz core 400MHz SDRAM 0 overvolt
modest  800MHz  ARM 300MHz core 400MHz SDRAM 0 overvolt
medium  900MHz  ARM 333MHz core 450MHz SDRAM 2 overvolt
high    950MHz  ARM 450MHz core 450MHz SDRAM 6 overvolt
turbo   1000MHz ARM 500MHz core 500MHz SDRAM 6 overvolt
EOT
}

# Update custom Raspberry Pi Kernel
linux_update() {
	cache="/var/cache/tazpkg"
	current="/var/lib/tazpkg/installed/linux"
	{
		echo "XXX" && echo 20
		echo -e "\n$(gettext 'Raspberry Pi kernel update')"
		echo "XXX" && sleep 1
		mkdir -p ${cache}
		rm -f ${cache}/linux-version.txt
		
		# Last version
		echo "XXX" && echo 40
		echo -e "\n$(gettext 'Fetching latest Kernel version string...')"
		echo "XXX" && sleep 1
		if busybox wget -q -s ${rpi_mirror}/packages/last-linux.txt; then
			wget -q ${rpi_mirror}/packages/last-linux.txt \
				-O ${cache}/linux-version.txt || exit 1
		else
			echo "XXX" && echo 100
			echo -e "\n$(gettext 'Mirror is unreachable')"
			echo "XXX" && sleep 1
			exit 1
		fi
		kvers=$(cat $cache/linux-version.txt)
		pkg="linux-${kvers}-arm.tazpkg"
		
		echo "XXX" && echo 50
		echo -e "\n$(gettext 'Last Kernel version:') $kvers"
		echo "XXX" && sleep 2
		rm -rf ${cache}/linux-${kvers}*
		
		# Download
		echo "XXX" && echo 60
		echo -e "\n$(gettext 'Fetching latest Linux package...')"
		echo "XXX"
		wget -q ${rpi_mirror}/packages/${pkg} -O ${cache}/${pkg} || exit 1
		
		# Install
		echo "XXX" && echo 80
		echo -e "\n$(gettext 'Installing:') ${pkg}"
		echo "XXX"
		cd ${cache}
		spk-add ${pkg} --forced >/dev/null 2>&1 || exit 1
		
		echo "XXX" && echo 100
		echo -e "\n$(gettext 'Cleaning installing files...')"
		echo "XXX" && sleep 2
		rm -f ${cache}/linux-version.txt
		
	} | dialog --title "{ Kernel Update }" \
		--gauge "" 8 ${width} 0
	# Reboot ?
	reboot_box \
		"$(gettext 'You must reboot to use your new Linux Kernel.')"
}

# Unset overclocking
unset_oclock() {
	debug "unset_oclock"
	sed -i \
		-e '/# Overclocking.*/'d \
		-e '/arm_freq=/'d \
		-e '/core_freq=/'d \
		-e '/sdram_freq=/'d \
		-e '/over_voltage=/'d ${config}
	# Remove if 3 empty lines follows
	sed -i '1N;N;/^\n\n$/d;P;D' ${config}
}

# Set overclocking: set_oclock [mode]
set_oclock() {
	debug "set_oclock $1"
	case "$1" in
		none)
			arm_freq=700
			core_freq=250
			sdram_freq=400
			over_voltage=0 ;;
		modest)
			arm_freq=800
			core_freq=300
			sdram_freq=400
			over_voltage=0 ;;
		medium)
			arm_freq=900
			core_freq=333
			sdram_freq=450
			over_voltage=2 ;;
		high)
			arm_freq=950
			core_freq=450
			sdram_freq=450
			over_voltage=6 ;;
		turbo)
			arm_freq=1000
			core_freq=500
			sdram_freq=500
			over_voltage=6 ;;
	esac
	unset_oclock
	cat >> ${config} << EOT
# Overclocking Settings
arm_freq=$arm_freq
core_freq=$core_freq
sdram_freq=$sdram_freq
over_voltage=$over_voltage

EOT
}

tazberry_back() {
	gettext "Press ENTER to go back to TazBerry"; read
}

#
# GUI Functions
#

# Usage: msg_box "title" "message"
msg_box() {
	dialog --title "{ $1 }" --cr-wrap \
		--ok-label "TazBerry" --msgbox "\n$2" ${height} ${width}
}

# Usage: text_box "file"
text_box() {
	local file="$1"
	if [ -f "$file" ]; then
		dialog --cr-wrap \
			--title "{ $(gettext 'Viewing file:') $file }" \
			--extra-button \
			--extra-label "Edit file" \
			--ok-label "TazBerry" \
			--textbox ${file} ${height} ${width}
	else
		dialog --title "$title" \
			--msgbox "\nERROR: $file does not exist" 10 ${width}
	fi
	# Handle options
	case "$?" in
		3) editor ${file} ;;
	esac
}

# Usage: tail_box "file"
tail_box() {
	dialog --title "{ $(gettext 'Watching file:') $2 }" \
		--tailbox "$1" ${height} ${width}
}

# Usage: reboot_box "Message..."
reboot_box() {
	dialog --title "$title" --yesno "\n${2}\n\n
Do You wish to reboot now ?" \
	${height} ${width}
	[ "$?" == 0 ] && reboot
}

# Packages info and spk-up button
pkgs_box() {
	out="$tmpdir/spk-info.txt"
	spk info --output=raw > ${out}
	dialog --cr-wrap \
		--title "{ $(gettext 'Packages') }" \
		--extra-button \
		--extra-label "$(gettext 'Upgrade')" \
		--ok-label "TazBerry" \
		--textbox "$out" ${height} ${width}
	# Handle options
	case "$?" in
		3) spk-up && tazberry_back ;;
	esac
}

# Overclocking info TODO: button to setup
oclock_box() {
	mode=$(fgrep arm_freq ${config} | cut -d '=' -f 2)
	case "$mode" in
		700) mode="none" ;;
		800) mode="modest" ;;
		900) mode="medium" ;;
		950) mode="high" ;;
		1000) mode="turbo" ;;
	esac
	dialog \
		--clear --colors \
		--extra-button \
		--title "{ Overclocking }" \
		--ok-label "TazBerry" \
		--extra-label "Set Overclock" \
		--cancel-label "Unset Oclock" \
		--menu "\nSet Raspberry Pi overclocking, current setting: \Zb\Z2$mode" \
		${height} ${width} 14 \
"none"    "700MHz  ARM 250MHz core 400MHz SDRAM 0 overvolt" \
"modest"  "800MHz  ARM 300MHz core 400MHz SDRAM 0 overvolt" \
"medium"  "900MHz  ARM 333MHz core 450MHz SDRAM 2 overvolt" \
"high"    "950MHz  ARM 450MHz core 450MHz SDRAM 6 overvolt" \
"turbo"   "1000MHz ARM 500MHz core 500MHz SDRAM 6 overvolt"  2>${tmp}
	retval="$?"
	mode=$(cat $tmp)
	case "$retval" in
		0) continue ;;
		1) unset_oclock ;;
		3) set_oclock "$mode" ;;
		255) rm -rf ${tmpdir} && exit 0 ;;
	esac
}

gpu_mem_box() {
	dialog \
		--clear \
		--title "$title" \
		--ok-label "Set mem" \
		--cancel-label "TazBerry" \
		--menu "\nSet the memory allocated to the GPU (in MB)" \
		${height} ${width} 14 \
"16"   "For server, NAS, base system without X" \
"32"   "For very small TFT and TV display" \
"64"   "Default value, fine for low latency desktop" \
"128"  "For a faster desktop, using a video player" \
"256"  "For media center, GL/3D applications" 2>${tmp}
	mem=$(cat $tmp)
	sed -i \
		-e s"/#gpu_mem=.*/gpu_mem=$mem/" \
		-e s"/gpu_mem=.*/gpu_mem=$mem/" /boot/config.txt
}

picam_setup() {
	db="/var/lib/tazpkg/installed"
	gpu_mem=128
	pct="0"
	{
		# Needed packages
		for pkg in raspberrypi-vc raspberrypi-boot-x
		do
			echo "XXX" && echo $((${pct} + 20))
			echo -e "\nInstalling: $pkg"
			echo "XXX"
			[ -d "$db/$pkg" ] || spk-add ${pkg} >/dev/null 2>&1
			sleep 1
		done
		
		echo "XXX" && echo 60
		echo -e "\nSetting up: ${config}"
		echo "XXX" && sleep 1
		# 0 to disable camera, 1 to enable it
		if ! grep -q "start_x=1" ${config}; then
			cat >> ${config} << EOT
		
# Camera settings
start_x=1

EOT
		fi
		# In case it was commented ot disabled
		sed -i s'/#start_x=.*/start_x=1/' ${config}
		sed -i s'/start_x=.*/start_x=1/' ${config}
		
		# PiCam needs 128 MB of GPU memory
		echo "XXX" && echo 80
		echo -e "\nSetting GPU memory to: ${gpu_mem}"
		echo "XXX" && sleep 1
		
		sed  -i "s/#gpu_mem=.*/gpu_mem=${gpu_mem}/" ${config}
		sed  -i "s/gpu_mem=.*/gpu_mem=${gpu_mem}/" ${config}
		
		echo "XXX" && echo 100
		echo -e "\nPiCam config done..."
		echo "XXX" && sleep 1

	} | dialog --title "{ PiCam Setup }" \
		--gauge "" 8 ${width} 0
	
	# Reboot ?
	reboot_box \
		"$(gettext 'SliTaz is configured for the PiCam but you need a reboot to use it.')"
}

# Breakout bords!
boards_box() {
	dialog \
		--clear \
		--title "$title" \
		--ok-label "Exec" \
		--cancel-label "TazBerry" \
		--menu "\nSetup or use a breakout board" ${height} ${width} 14 \
"camera"         "$(gettext 'Configure your Pi to use a Camera')" \
"piglow"         "$(gettext 'Setup your Pi to use PiGlow')" \
"raspicomm"      "$(gettext 'Initialize RaspiComm board')" \
"pitft"          "$(gettext 'Setup PiTFT touchscreen')" 2>${tmp}
	
	# Handle options
	case "$?" in
		1|255) continue ;;
	esac
	
	# Handle actions
	action=$(cat $tmp)
	case "$action" in
		camera)
			 picam_setup ;;
		piglow)
			for pkg in python-rpi-pyglow wiringpi-piglow; do
				spk-add ${pkg}
			done
			newline
			echo -n "Do you wish to try the leds [y/N] ? " ; read anser
			if [ "$anser" == "y" ]; then 
				echo "Enter a value between: 5-255" && pyglow test
			fi ;;
		raspicomm)
			raspicomm init; read -t 4 ;;
		pitft)
			pitft-setup
			echo -n "Press ENTER to continue..."; read ;;	
	esac
}

# Main Dialog menu
main_box() {
	dialog \
		--clear \
		--title "$title" \
		--ok-label "Exec" \
		--cancel-label "Quit" \
		--menu "" ${height} ${width} 14 \
"rpi-stats"      "$(gettext 'Show some RPi system stats')" \
"gpu-mem"        "$(gettext 'Set memory split between ARM and GPU')" \
"boards"         "$(gettext 'Boards settings and tools (Camera, PyGlow)')" \
"act-led"        "$(gettext 'Turn on/off RPi onboard ACT green led')" \
"oclock"         "$(gettext 'Overclocking configuration')" \
"rpi-turbo"      "$(gettext 'Enable or disable RPi turbo on next boot')" \
"boot-cmdline"   "$(gettext 'View boot args /boot/cmdline.txt')" \
"boot-config"    "$(gettext 'View config file /boot/config.txt')" \
"linux-up"       "$(gettext 'Update SliTaz Raspberry Pi Linux Kernel')" \
"packages"       "$(gettext 'SliTaz packages manager') (spk)" \
"config"         "$(gettext 'System config (lang, keyboard, wifi)')" \
"reboot"         "$(gettext 'Reboot SliTaz system')" \
"halt"           "$(gettext 'Halt the Raspberry Pi')" \
"quit"           "$(gettext 'Exit TazBerry tool')" 2>${tmp}
	
	# Handle options
	case "$?" in
		1|255) rm -rf ${tmpdir} && exit 0 ;;
	esac
	
	# Handle actions
	action=$(cat $tmp)
	case "$action" in
		rpi-stats)
			msg_box "RPi Stats" "$(rpi_stats)" ;;
		gpu-mem)
			gpu_mem_box ;;
		boards)
			boards_box ;;
		act-led) 
			pileds act ;;
		oclock)
			oclock_box ;;
		rpi-turbo)
			rpi_turbo && newline 
			tazberry_back ;;
		boot-cmdline)
			text_box /boot/cmdline.txt ;;
		boot-config)
			text_box ${config} ;;
		linux-up)
			linux_update
			tazberry_back ;;
		packages)
			spk-dialog ;;
		config)
			slitaz-config ;;
		reboot)
			reboot ;;
		halt)
			poweroff ;;
		quit)
			rm -rf ${tmpdir} && exit 0 ;;
	esac
}

# Progress bar testsuite
gauge_box() {
    { for i in $(seq 1 100); do
		echo $i
		sleep 0.01
	done
    echo 100; } | dialog --title "{ TazBerry }" \
		--gauge "Work in progress..." 6 ${width} 0
}

#
# Handle commands
#

case "$1" in
	oclock)
		oclock_box ;;
	
	linux-up)
		linux_update ;;
	
	cam-setup)
		picam_setup ;;
	
	ls-functions)
		newline
		boldify "$(gettext 'TazBerry functions list')"
		separator
		grep "^rpi_*" $0 | awk '{print "  ", $1}' 
		newline ;;
	
	testsuite)
		gauge_box 
		msg_box "Testsuite" "Test message"
		rpi_stats 
		newline ;;
	 
	rpi_*) 
		# Execute functions 
		$@ ;;
	
	"")
		# No args: display Ncurses dialog
		while true; do
			main_box
		done ;;
	
	*|*help|-h)
		# Display help
		help ;;
esac

# Clean exit
rm -rf ${tmpdir}
exit 0
