#!/bin/bash

# Author: Nathanel Titane - nathanel.titane@gmail.com - Copyright 2016

shopt -s extglob globstar nullglob

# make-list #

black= red= green= yellow= blue= magenta= cyan= white= reset=

if [[ -t 1 ]]
then
	black=$(tput setaf 0)
	red=$(tput setaf 1)
	green=$(tput setaf 2)
	yellow=$(tput setaf 3)
	blue=$(tput setaf 4)
	magenta=$(tput setaf 5)
	cyan=$(tput setaf 6)
	white=$(tput setaf 7)
	reset=$(tput sgr0)
fi

version="20-08-2016"
script=$(basename -- "$0")

while (($#))
do
	case "$1" in
		-d|--description)
			mode="description"
			;;
		-n|--number)
			mode="number"
			;;
		-h|--help)
			echo -e "Usage:"
			echo -e "./$script [OPTION]"
			echo -e "Utility options:"
			echo -e "-d, --description \t Sort list by part description."
			echo -e "-n, --number \t\t Sort list by part number."
			echo -e "-h, --help \t\t Show help options."
			echo -e "-v, --version \t\t Print version."
			exit
			;;
		-v|--version)
			echo -e "$script $version"
			exit
			;;
		*)
			echo -e "$script: Unknown option $1"
			echo -e "Try '$script --help' for options information."
			exit
			;;
		esac
	shift
done

# Test for utility dependencies and requirements

for binary_name in \
"curl" \
"wget" \
"unzip" \
"zip"
do
	binary=$(which $binary_name)

	if [[ -z "$binary" ]] # If binary is not found or unspecified
	then
		echo "${yellow}The '$binary_name' binary does not seem to be installed or present on your system.${reset}"
		echo "${yellow}Would you like to specify its location manually? [ Yes | No ]${reset}"

		read reply

		if [[ "$reply" = [yY] || "$reply" = [yY][eE][sS] ]]
		then
			# Specify binary location or exit on 'Cancel'

			binary_path=$(zenity --file-selection  --multiple --separator=$'\n' --title="Please specify binary location") 2> /dev/null || exit

			binary="$binary_path/$binary"
		else
			echo "${red}Could not specify '$binary_name' binary installed on system.${reset}"
			echo "${red}Please install '$binary_name' using your system's package manager${reset}"
			echo "${red}and restart this utility when you are done.${reset}"
			echo ""
			exit 1
		fi

	elif [[ ! -z "$binary" ]] # If binary exists
	then
		echo "${green}'$binary' binary found on system - Continuing...${reset}"
		echo ""
	fi

	sleep 1
done

# LDraw parts library directory check

if [[ "$(basename $(pwd))" == [lL][dD][rR][aA][wW] ]] && [[ -d "parts" ]]
then
	echo "${green}Operating within the LDraw parts directory. Continuing...${reset}"

	directory="parts"
elif [[ "$(basename $(pwd))" != [lL][dD][rR][aA][wW] ]]
then
	echo "${yellow}LDraw parts directory not found.${reset}"
	echo "${yellow}Please specify the LDraw parts library directory location.${reset}"

	# Specify directory location or exit on 'Cancel'

	browse=$(zenity --file-selection  --multiple --directory --separator=$'\n' --title="Select a Directory") 2> /dev/null || exit

	cd "$browse" || exit

	directory="$browse/parts"
else
    # basename matches ldraw
	echo "${yellow}LDraw parts directory not found or not setup on this system.${reset}"
	echo "${yellow}Would you like to have the latest LDraw parts library downloaded and setup on your system?${reset}"

	read reply

	if [[ "$reply" = [yY] || "$reply" = [yY][eE][sS] ]]
	then
		echo "${yellow}Please specify the LDraw parts library directory setup location.${reset}"

		# Specify directory location or exit on 'Cancel'

		setup_directory=$(zenity --file-selection  --multiple --directory --separator=$'\n' --title="Select a Directory") 2> /dev/null || exit

		cd "$setup_directory" || exit

		parts_url="http://www.ldraw.org/library/updates/complete.zip"
		parts_archive=$(basename "$parts_url")

		if [[ ! -z $(which wget) ]]
		then
			get_parts=$(wget --show-progress "$parts_url")

		elif [[ ! -z $(which curl ) ]]
		then
			get_parts=$(curl -# "$parts_url" > "$parts_archive")
		else
			echo "${red}Cannot find suitable utility to fetch the LDraw parts archive - Aborting...${reset}"
		fi

		echo "${cyan}Downloading...${reset}"
		echo ""
		"$get_parts"

		echo "${cyan}Extracting...${reset}"
		echo ""
		unzip "$parts_archive"

		cd $setup_directory/[lL][dD][rR][aA][wW]/parts || exit
	else
		echo "${red}LDraw parts directory not setup on system - Exiting...${reset}"
		echo "${cyan}Please visit http://www.ldraw.org to get started.${reset}"
		echo "${cyan}You may restart this utility to generate the parts list needed for some editors to function${reset}"
		echo "${cyan}once the LDraw parts library has been downloaded and extracted on your system.${reset}"
		exit 1
	fi
fi

# Parts list verification and backup

if [[ -e parts.lst ]]
then
	mv parts.lst parts.lst.old
fi

# Mode verification

if [[ "$mode" == "description" ]]
then
	echo "${cyan}Utility started with [d]escription sorting option flag.${reset}"

elif [[ "$mode" == "number" ]]
then
	echo "${cyan}Utility started with [n]number sorting option flag.${reset}"
else
	echo "${cyan}Would you like to sort the parts list by [d]escription or by part [n]umber?${reset}"

	read reply
fi

# Parsing

echo "${cyan}Processing...${reset}"

count=1

for part in "$directory"/*.dat
do
	filename="${part##*/}"
	header="$(head -n 1 "$part")"
	description="${header:2}"

	if [[ "$description" == *~Moved* ]]
	then
		: # pass
	else
		if [[ "$description" == *_* ]]
		then
			printf '%-30s %-s\n' "$filename" "$description" >> "._.lst"

		elif [[ "$description" == *~* ]]
		then
			printf '%-30s %-s\n' "$filename" "$description" >> ".~.lst"

		else
			printf '%-30s %-s\n' "$filename" "$description" >> parts.lst
		fi

		echo -ne "${cyan}Parts in list: ${reset}" "$((count++))"'\r'
	fi
done

echo "" # Keep counter visible after loop

# Apply sorting method according to mode/reply

for list in "._.lst" ".~.lst" parts.lst
do
	if [[ "$reply" = [dD] ]] || [[ "$mode" == "description" ]]
	then
		sort -b -d -k 2 -t ' ' -o "$list" "$list"

	elif [[ "$reply" = [nN] ]] || [[ "$mode" == "number" ]]
	then
		sort -b -n -k 1 -t ' ' -o "$list" "$list"
	fi
done

# Merge files and clean

cat "._.lst" ".~.lst" >> parts.lst
rm -rf "._.lst" ".~.lst"

echo "${cyan}Done.${reset}"
echo ""
