#!/bin/bash

# ------------------------------------------------------------------------------
# Defaults:
# ------------------------------------------------------------------------------

target="linux"
project="project"
test=0

ldflags=" -lGL -lGLU `sdl-config --libs`"
ccflags=" -Wall -Wstrict-prototypes -Wstrict-overflow -ggdb `sdl-config --cflags`"

binary="binary"
runconfiguration=""

# ------------------------------------------------------------------------------
# text format definitions:
# ------------------------------------------------------------------------------
txtblk='\e[0;30m' # Black - Regular
txtred='\e[0;31m' # Red
txtgrn='\e[0;32m' # Green
txtylw='\e[0;33m' # Yellow
txtblu='\e[0;34m' # Blue
txtpur='\e[0;35m' # Purple
txtcyn='\e[0;36m' # Cyan
txtwht='\e[0;37m' # White
bldblk='\e[1;30m' # Black - Bold
bldred='\e[1;31m' # Red
bldgrn='\e[1;32m' # Green
bldylw='\e[1;33m' # Yellow
bldblu='\e[1;34m' # Blue
bldpur='\e[1;35m' # Purple
bldcyn='\e[1;36m' # Cyan
bldwht='\e[1;37m' # White
unkblk='\e[4;30m' # Black - Underline
undred='\e[4;31m' # Red
undgrn='\e[4;32m' # Green
undylw='\e[4;33m' # Yellow
undblu='\e[4;34m' # Blue
undpur='\e[4;35m' # Purple
undcyn='\e[4;36m' # Cyan
undwht='\e[4;37m' # White
bakblk='\e[40m'   # Black - Background
bakred='\e[41m'   # Red
badgrn='\e[42m'   # Green
bakylw='\e[43m'   # Yellow
bakblu='\e[44m'   # Blue
bakpur='\e[45m'   # Purple
bakcyn='\e[46m'   # Cyan
bakwht='\e[47m'   # White
txtrst='\e[0m'    # Text Reset

# ------------------------------------------------------------------------------
# puts out the help text
# ------------------------------------------------------------------------------

function howToUse() {
	echo "Usage: $0 [OPTION]"
	echo 
	echo "Options:"
	echo "  -help    - prints this text"
	echo "  -target  - specifies compilation target:"
	echo "     linux - compiles for Linux [default]"
	echo "  -test    - launches binary after successful compilation"
	echo
	echo "If you provide the test parameter, build will try to execute"
	echo "the binary after successfully compiled it."
	echo 
	exit 1
}

# ------------------------------------------------------------------------------
# Parsing command line parameters
# ------------------------------------------------------------------------------

while (( "$#" ))
do
	
	case "$1" in
		"-help")
			howToUse
			exit 0
			;;
		"-target")
			target=$2
			shift 2
			;;
		"-test")
			test=1
			shift 1
			;;
		*)
			echo "$0: Unknown command line parameter: $1"
			exit 1
			shift 1;
			;;
	esac
	
done

# ------------------------------------------------------------------------------
# Configuring:
# ------------------------------------------------------------------------------

case "$target" in
	"linux")
		cc="/usr/bin/gcc"
		ld="/usr/bin/gcc"
		dp="/usr/bin/gcc"
		;;
	*)
		echo "$0: Target not supported (yet): $target"
		exit 1
		;;
esac

# ------------------------------------------------------------------------------
# Preparing:
# ------------------------------------------------------------------------------

echo -e "${bldgrn}Building ${project}...${txtrst}"
echo -e " ${bldwht}Target:${txtrst} $target"
echo -e " ${txtwht}cc:    ${txtrst} $cc"
echo -e " ${txtwht}ld:    ${txtrst} $ld"

echo ""

echo -e "[${bldgrn}  0 %${txtrst}] [${bldwht}sh${txtrst}] Gathering source files..."
source=()
i=0

for file in $(find -xtype f -name "*.c")
do
	source[i]=$file
	i=$(expr $i + 1)
done

sourcefilecount=${#source[@]}
i=0

for file in $(find -xtype f -name "*.c" | sed 's/.\///')
do
	percentage=$(expr \( ${i} + 1 \) \* 100 / \( ${sourcefilecount} + 2 \))
	
	case "${#percentage}" in
		1)
			percentage="  ${percentage}"
			;;
		2)
			percentage=" ${percentage}"
			;;
	esac
	
	targetfile=$(echo $file | sed 's/.c/.o/')
	objects[i]=$targetfile
	i=$(expr $i + 1)
	
	if [ -f $targetfile ]
	then
		
		basename=$(basename $file)
		objname=$(basename $targetfile)
		depends=$(${dp} -MM ${file} 2> /dev/null | sed "s/$objname: //" | sed 's/\\//')
		fileschanged=0
		
		for filecheck in ${depends}
		do
			srcts=$(stat -c %Y $filecheck)
			objts=$(stat -c %Y $targetfile)
			
			if [ $srcts -gt $objts ]
			then
				fileschanged=$(expr $fileschanged + 1)
			fi
		done
		
		if [ $fileschanged == 0 ]
		then
			echo -e "[${bldgrn}${percentage} %${txtrst}] [${bldwht}sh${txtrst}] skipping ${file}"
			continue;
		fi
		
		
	fi
	
	echo -e "[${bldgrn}${percentage} %${txtrst}] [${bldwht}cc${txtrst}] compiling ${file}"
	ccoutput=$(${cc} -o ${targetfile} -c ${ccflags} ${file} 2>&1)
	
	if [ $? != 0 ]
	then
		echo -e "[${bldred}ERROR${txtrst}] [${bldwht}cc${txtrst}] Error on compile process; aborting"
		echo ""
		echo "$ccoutput"
		echo ""
		exit 1
	fi
done

echo -e "[${bldgrn}100 %${txtrst}] [${bldwht}ld${txtrst}] linking ${binary}"
ldoutput=$(${ld} -o ${binary} ${ldflags} ${objects[@]} 2>&1)

if [ $? != 0 ]
then
	echo -e "[${bldred}ERROR${txtrst}] [${bldwht}ld${txtrst}] Error on link process; aborting"
	echo ""
	echo "$ldoutput"
	echo ""
	exit 1
fi

if [ $test -eq 1 ]
then
	echo -e "[${bldgrn}100 %${txtrst}] [${bldwht}sh${txtrst}] executing binary"
	echo ""
	
	${binary} ${runconfiguration}
	
fi
echo ""
