#!/bin/bash

function usage() {
	echo "USAGE: $0 [options] numbers"
	echo "  -q   quiet: don't print the header"
	echo "  -h   help: print this message"
	echo "  -B   suppress binary"
	echo "Start octal numbers with a 0 and hex numbers with a 0x."
	echo "End binary numbers with a b."
	exit 1
}

function toupper() {
	echo $* | tr 'abcdef' 'ABCDEF'
}

function tolower() {
	echo $* | tr 'ABCDEF' 'abcdef'
}

function do_binary() {
	OUT=`echo "ibase=2; $1; obase=10000; $1; obase=1000; $1; obase=10; $1" | bc`
	tolower $1 $OUT
}

function do_hex() {
	i=`toupper $1`
	if [ -n "$PRINT_BINARY" ]; then
		OUT=`echo "ibase=16; $i; obase=10; $i; obase=8; $i; obase=2; $i" | bc`
	else
		OUT=`echo "ibase=16; $i; obase=10; $i; obase=8; $i" | bc`
	fi
	tolower $1 $OUT
}

function do_octal() {
	if [ -n "$PRINT_BINARY" ]; then
		OUT=`echo "ibase=8; $1; obase=20; $1; obase=10; $1; obase=2; $1" | bc`
	else
		OUT=`echo "ibase=8; $1; obase=20; $1; obase=10; $1" | bc`
	fi
	tolower $1 $OUT
}

function do_decimal() {
	if [ -n "$PRINT_BINARY" ]; then
		OUT=`echo "$1; obase=16; $1; obase=8; $1; obase=2; $1" | bc`
	else
		OUT=`echo "$1; obase=16; $1; obase=8; $1" | bc`
	fi
	tolower $1 $OUT
}

function convert_args() {
	if [ -n "$PRINT_HEADER" ]; then
		if [ -n "$PRINT_BINARY" ]; then
			echo "orig dec hex oct bin";
		else
			echo "orig dec hex oct";
		fi
	fi

	while [ -n "$1" ]; do
		if [ ${1:0:2} == '0x' ]; then
			do_hex ${1:2}
		elif [ ${1: -1:1} == 'b' ]; then
			do_binary ${1/b/}
		elif [ ${1:0:1} == '0' ]; then
			do_octal ${1:1}
		else
			do_decimal $1
		fi
		shift;
	done;
}

PRINT_HEADER=1
PRINT_BINARY=1
BAD_OPTIONS=''

# process options:
while getopts "qBh" o; do
	case $o in
		q)
		PRINT_HEADER=''
		;;
		B)
		PRINT_BINARY=''
		;;
		h)
		usage
		;;
		'?')
		BAD_OPTIONS=1
		;;
	esac
done
shift $(($OPTIND - 1))

if [[ -n "$BAD_OPTIONS" || -z "$1" ]]; then
	usage;
fi

convert_args $* | column -t

