#!/usr/bin/env bash

function get-output-filename {
        # takes fileinput, returns fileoutput name; takes optional $2 argument to tack onto end of name
        name="$(cut -d'.' -f1 <<<"$1")"
        ext="$(cut -d'.' -f2 <<<"$1")"
        echo "${name}_${2}.${ext}"
}

function timelapse() {
	framerate="$1"
	filename="$2"
	resolution_width="$3"
	resolution_height="$4"
	$(type -P ls) -1tr ./*.JPG >gopro_timelapse_list.txt
	mencoder -nosound -ovc x264 \
		-vf scale="$resolution_width":"$resolution_height" -mf type=jpeg:fps="$framerate" \
		mf://@gopro_timelapse_list.txt -o "$filename"
	rm gopro_timelapse_list.txt
}

function superview() {
	for i in *.MP4; do
		name=$(echo "$i" | cut -d'.' -f1)+S
		echo "$name"
		ffmpeg -i "$i" -q:a 1 -q:v 1 0 -vcodec mpeg4 -acodec ac3 -aspect 16:9 -strict experimental "$name".MP4
	done
}

function fisheye() {
	#echo "https://gopro.com/help/articles/Question_Answer/HERO4-Field-of-View-FOV-Information"
	echo -ne "Resolution:\n-[0] 4:3 Wide FOV\n-[1] 4:3 Medium FOV\n-[2] 4:3 Narrow FOV\nPhoto resolution: "
	read -r res
	distortion_args=""
	case $res in
	0*)
		distortion_args="0 0 -0.3"
		;;
	1*)
		distortion_args="0 0 -0.2"
		;;
	2*)
		distortion_args="0 0 -0.1"
		;;
	esac
	if [[ $1 == "" ]]; then
		for photo in *.JPG; do
			timestamp=$(stat -c %y "$photo")
			mogrify -distort barrel "$distortion_args" "$photo"
			touch -d "$timestamp" "$photo"
		done
	else
		timestamp=$(stat -c %y "$1")
		mogrify -distort barrel "$distortion_args" "$1"
		touch -d "$timestamp" "$1"
	fi
}

function fisheye_video() {
	#echo "https://gopro.com/help/articles/Question_Answer/HERO4-Field-of-View-FOV-Information"
	#https://gopro.com/help/articles/question_answer/HERO3-Black-Edition-Field-of-View-FOV-Information
	#https://gopro.com/help/articles/Question_Answer/HERO4-Field-of-View-FOV-Information
	#https://gopro.com/help/articles/Question_Answer/HERO5-Black-Field-of-View-FOV-Information
	#http://www.kolor.com/wiki-en/action/view/Autopano_Video_-_Focal_length_and_field_of_view
	#https://gopro.com/help/articles/question_answer/hero6-black-field-of-view-fov-information

	vfov=0
	hfov=0
	diag=0

	echo -ne "Camera:
			-[0] HERO3
			-[1] HERO4/5
			-[2] HERO6
			>> Camera: "
	read -r cam
	case $cam in
	0*)
		echo ">> HERO3"
		echo -ne "Resolution:
			-[0] 4:3 Wide FOV
			-[1] 4:3 Medium FOV
			-[2] 4:3 Narrow FOV
			-[3] 16:9 Wide FOV
			-[4] 16:9 Medium FOV
			-[5] 16:9 Narrow FOV
			>> Video resolution: "
		read -r res
		case $res in
		0*)
			hfov=94.4
			vfov=122.6
			diag=149.2
			;;
		1*)
			hfov=72.2
			vfov=94.4
			diag=115.7
			;;
		2*)
			hfov=49.1
			vfov=64.6
			diag=79.7
			;;
		3*)
			hfov=69.5
			vfov=118.2
			diag=133.6
			;;
		4*)
			hfov=55
			vfov=94.4
			diag=107.1
			;;
		5*)
			hfov=37.2
			vfov=64.4
			diag=73.6
			;;
		esac
		;;
	1*)
		echo ">> HERO4"
		echo -ne "Resolution:
			-[0] 4:3 Wide FOV
			-[1] 4:3 Medium FOV
			-[2] 4:3 Narrow FOV
			-[3] 16:9 Wide FOV
			-[4] 16:9 Medium FOV
			-[5] 16:9 Narrow FOV
			>> Video resolution: "
		read -r res
		case $res in
		0*)
			hfov=94.4
			vfov=122.6
			diag=149.2
			;;
		1*)
			hfov=72.2
			vfov=94.4
			diag=115.7
			;;
		2*)
			hfov=49.1
			vfov=64.6
			diag=79.7
			;;
		3*)
			hfov=69.5
			vfov=118.2
			diag=133.6
			;;
		4*)
			hfov=55
			vfov=94.4
			diag=107.1
			;;
		5*)
			hfov=37.2
			vfov=64.4
			diag=73.6
			;;
		esac
		;;
	2*)
		echo ">> HERO6"
		echo -ne "Resolution:
			-[0] 4:3 Wide FOV ZOOM 0
			-[1] 4:3 Wide FOV ZOOM 100
			-[2] 16:9 Wide FOV ZOOM 0
			-[3] 16:9 Wide FOV ZOOM 100
			>> Video resolution: "
		read -r res
		case $res in
		0*)
			hfov=94.4
			vfov=122.6
			diag=149.2
			;;
		1*)
			hfov=49.1
			vfov=64.6
			diag=79.7
			;;
		2*)
			hfov=69.5
			vfov=118.2
			diag=133.6
			;;
		3*)
			hfov=35.7
			vfov=62.2
			diag=70.8
			;;
		esac
		;;
	esac

	flength=$(echo "$vfov/$hfov*$diag" | bc -l | head -n1 | cut -d "." -f1)
	if [[ $1 == "" ]]; then
		for video in *.MP4; do
			name=$(echo "$video" | cut -d'.' -f1)_corrected
			ffmpeg -i "$video" -vf "lenscorrection=cx=0.5:cy=0.5:k1=-0.$flength:k2=-0.022" -q:a 1 -q:v 1 -vcodec libx264 "$name".mp4
		done
	else
		name=$(echo "$1" | cut -d'.' -f1)_corrected
		ffmpeg -i "$1" -vf "lenscorrection=cx=0.5:cy=0.5:k1=-0.$flength:k2=-0.022" -q:a 1 -q:v 1 -vcodec libx264 "$name".mp4
	fi
}

function convert() {
	if [[ $1 == "" ]]; then
		for i in *.MP4; do
			name=$(echo "$i" | cut -d'.' -f1)
			echo "$name"
			ffmpeg -i "$i" -q:a 1 -q:v 1 -vcodec mpeg4 "$name".mov
		done
	else
		name=$(echo "$1" | cut -d'.' -f1)
		echo "$name"
		ffmpeg -i "$1" -q:a 1 -q:v 1 -vcodec mpeg4 "$name".mov
	fi
}

function convert-h265-to-h264 {
        fileout="$(get-output-filename ${1} h264)"
        ffmpeg -i "$1" -bsf:v h264_mp4toannexb -vcodec libx264 -c:a copy "$fileout"
}

function slowmo() {
	ffmpeg -i "$1" -r 25 -vf "setpts=($3/1)*PTS" -q:a 1 -q:v 1 -vcodec libx264 "$2"
	echo "Video slowed down, use trim to trim the video"
}

function speed() {
	ffmpeg -i "$1" -r "$4" -vf "setpts=($3/1)*PTS" -q:a 1 -q:v 1 -vcodec libx264 "$2"
	echo "finished $1"
}

function trim() {
	ffmpeg -i "$1" -ss "$3" -t "$4" -q:a 1 -q:v 1 -vcodec libx264 "$2"
}

function merge() {
	LIST_FILE="$(mktemp)"
	printf "file '$PWD/%s'\n" *.MP4 > $LIST_FILE
	ffmpeg -f concat -safe 0 -i $LIST_FILE -c copy "$1"
	rm $LIST_FILE
}

function rotate90deg {
	fileout="$(get-output-filename ${1} rotated)"
        # use 'transpose=2' for counter-clockwise
        ffmpeg -i "$1" -filter:v transpose=1 -metadata:s:v rotate="" "$fileout"
}

function stabilize() {
	ffmpeg -i "$1" -vf deshake "$2"
}

function sort() {
	mkdir -p videos/{single,chaptered,thumbnails,lowresvideos}
	mkdir -p photos/{single,timelapse-burst-continuous}
	if [[ $1 == "move" ]]; then
		mv GOPR*.MP4 videos/single
		mv GP*.MP4 videos/chaptered
		mv GOPR*.JPG photos/single
		mv G*.JPG photos/timelapse-burst-continuous
		mv ./*.LRV videos/lowresvideos
		mv ./*.THM videos/thumbnails
	else
		cp -p GOPR*.MP4 videos/single
		cp -p GP*.MP4 videos/chaptered
		cp -p GOPR*.JPG photos/single
		cp -p G*.JPG photos/timelapse-burst-continuous
		cp -p ./*.LRV videos/lowresvideos
		cp -p ./*.THM videos/thumbnails
	fi
	echo "Finished!"
}

function wifiinfo() {
	echo "is $(pwd) the root of your SD card?"
	read -r
	echo -ne "Enter current (default) wifi password: "
	read -r defssid
	echo -ne "Enter Wifi SSID: "
	read -r wifissid
	echo -ne "Enter password: "
	read -r wifipassword
	{
		echo "$defssid"
		echo "EVssidprimary,$wifissid"
		echo "EVpassphrase,$wifipassword"
	} >>gpauto
	echo "Done. Insert SD card into the camera, remove battery, insert battery and power on twice."
}

function update() {
	curl https://raw.githubusercontent.com/KonradIT/gopro-linux/master/version
	curl https://raw.githubusercontent.com/KonradIT/gopro-linux/master/gopro >/usr/bin/gopro
}

function gif() {
	convert -size "$1" ./*.JPG -delay 5 -resize "$1" "$2"
}
function proxy() {
	if [[ $1 == "rename" ]]; then
		mkdir lowres highres
		mv ./*.MP4 highres/
		mv ./*.LRV lowres/
		for i in lowres/*.LRV; do
			name=$(echo "$i" | cut -d'.' -f1)
			mv "$i" "$name".MP4
		done
	fi
	if [[ $1 == "move" ]]; then
		mv highres/*.MP4 lowres/
	fi
}

function help() {
	echo 'GoPro Tool for Linux OS
Available commands:
- gopro
    >>Check for missing dependencies, e.g. ffmpeg, imagemagick and mencoder

- gopro timelapse [fps] [outfilename] [res width] [res height]
		>>Makes a timelapse with pictures in the current folder, make sure to cd to a DCIM/XXXGOPRO folder!
		>>Example: gopro timelapse 30 goproTL.mp4 1920 1080

- gopro superview
		>>Applies SuperView to all GoPro videos in the current dir

- gopro fisheye
		>>Fixes barrel distorsion to all GoPro pictures in the current folder

- gopro fisheye_video [video]
		>>Fixes barrel distorsion on GoPro videos, [video] is optional, remove to apply to all mp4 videos in current dir
		>>Also needs camera name input

- gopro convert
		>>Converts all GoPro MP4 videos to MPEG4 MOV videos for easy editing

- gopro convert-h265-to-h264 [input_video]
		>>Converts videos with h.265 codecs to h.264
		>>This is useful for backwards compatibility. Some videos recorded on HERO Black 7 devices cannot be played on older hardware until codecs are converted.

- gopro slowmo [video]
		>>Reduces the speed in a High FPS GoPro Video
		>>Example: gopro slowmo GOPRO0553.MP4

- gopro trim [input video] [output video] [HH:MM:SS start] [HH:MM:SS end]
		>>Trims a video to start and end times
		>>Example: gopro trim GOPR0553.MP4 Trimmed.mp4 00:05:04 00:07:43

- gopro merge [output_video]
		>>Merges all videos present in the current folder to [output_video]

- gopro rotate90deg [input_video]
		>>Rotates video 90 degrees clockwise (edit "translate=2" argument for counter-clockwise)

- gopro stabilize
		>>Stabilizes video
		>>Example: gopro GOPRO0005.MP4 Stabilized.MP4

- gopro sort
		>>Sorts media, please execute in DCIM/XXXGOPRO

- gopro wifiinfo
		>>Sets Wifi SSID and Password for HERO5, 6, 7 cameras

- gopro gif
		>>Makes gif from images in current dir
		>>Example: gopro gif 800x600 animation.gif

- gopro proxy [option]
		>>[rename] = renames .LRV to lowres/*.MP4
		>>[move] = when finish editing, moves highres/*.MP4 to lowres/

- gopro update
		>>Updates this script

- gopro help
		>>show this usage message'
}

echo "GoPro Tool for Linux"
echo "To see a list of commands and syntax available run: gopro help"
echo "Checking dependencies..."
hash ffmpeg 2>/dev/null || { echo >&2 "ffmpeg ..... Not installed!"; }
hash mogrify 2>/dev/null || { echo >&2 "mogrify ..... Not installed!"; }
hash mencoder 2>/dev/null || { echo >&2 "mencoder ..... Not installed!"; }
hash bc 2>/dev/null || { echo >&2 "bc ..... Not installed!"; }
"$@"
