#!/bin/bash

    # This program is free software: you can redistribute it and/or modify
    # it under the terms of the GNU General Public License as published by
    # the Free Software Foundation, either version 3 of the License, or
    # (at your option) any later version.

    # This program is distributed in the hope that it will be useful,
    # but WITHOUT ANY WARRANTY; without even the implied warranty of
    # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    # GNU General Public License for more details.

    # You should have received a copy of the GNU General Public License
    # along with this program.  If not, see <http://www.gnu.org/licenses/>.

# TODO review code 2019-02-16
# TODO update documentation

# A simple way to manage my task lisk.  `stmmenu` is a dmenu interface
# for adding or removing items from a plain text file.  This script is
# part of my dotfiles: https://gitlab.com/protesilaos/dotfiles 
#
# Adapted from the same tool provided by suckless.org:
# https://tools.suckless.org/dmenu/scripts/todo
#
# For a command line utility with more functions and prettier output,
# which interfaces with the exact same task list file, see my `stm`.  It
# is also part of my dotfiles (inside the bin directory).

# Define my task list file
if [ -f "$HOME/.my_task_list" ]; then
	task_list="$HOME/.my_task_list"
else
	touch -h "$HOME/.my_task_list"
	task_list="$HOME/.my_task_list"
fi

# Find the number of lines (needed for dmenu -l)
task_list_height="$(grep -c '^.*' $task_list)"

# Pass custom colours to dmenu command
source "$HOME/.local/share/my_colours/active-tempus-theme.sh"

# Get the system-wide custom font, for use in dmenu
source "$HOME/.local/share/my_custom_ui_font.sh"

# Custom dmenu command.  Accepts the line height as an argument.
my_dmenu() {
	if [ -n "$1" ]; then
		local height="$1"
	else
		local height="5"
	fi

    dmenu -i -p 'Write to add OR select to remove a task' \
	-nb "$background" -nf "$foreground" -sb "$color12" \
	-sf "$background" -fn "$my_custom_ui_font" -l "$height"
}

# Pipe the task list's contents to dmenu. Print line numbers as well.
task_interaction="grep -n '' $task_list | my_dmenu $task_list_height"

# Capture dmenu's output
task_action="$(eval $task_interaction)"

# Only store the line number. We need this to tell sed to delete the
# corresponding line.  It avoids problems with special characters.
task_interaction_line="$(echo $task_action | cut -d ':' -f 1)"

# Do not capture the line number.  That is only needed for sed and does
# not correspond to content that is present in the task list.
task_action_clean="$(echo $task_action | cut -d ':' -f 2)"

# Write to add a task, or select an existing one to remove it from the
# list.
while [ -n "$task_action" ]; do
	# If item with corresponding line number exists
	if grep -F "$task_action_clean" "$task_list"; then
		# Remove item from list based on its line number.  Also respect
		# symlinks (the actual task list might be in a git-controlled
		# repo).
		sed -i --follow-symlinks "$task_interaction_line d" "$task_list"

		# Tell us what happened
		echo "Removed «$task_action_clean» from task list"

		# Decrement the line height after removing the selected task
        task_list_height=$(($task_list_height-1))
	else
		# Append new item to the task list
		echo "$task_action_clean" >> "$task_list"

		# Tell us what happened
		echo "Appended «$task_action_clean» to task list"

		# Increment the line height after adding the typed task
        task_list_height=$(($task_list_height+1))
	fi
	
	# Renew stmmenu after receiving an action
	task_interaction="grep -n '^.*' $task_list | my_dmenu $task_list_height"
	task_action="$(eval $task_interaction)"
	task_interaction_line="$(echo $task_action | cut -d ':' -f 1)"
	task_action_clean="$(echo $task_action | cut -d ':' -f 2)"
done
