#!/bin/bash

#
#	getDeps- The dependency handler you're using when your not using
#	a dependency handler. (Downloads dependencies for 3Depict)
#	Copyright (C) 2012, D Haley,  AV Ceguerra 
#
#	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/>.
#

function setFullDeps {
	#Dependency ID, URL and name
	DEPIDS=( 0 1 2 3 4 5)
	DEPNAMES=( libpng freetype ftgl wxwidgets mathgl qhull)
	DEPURLS=(https://sourceforge.net/projects/libpng/files/libpng15/older-releases/1.5.4/libpng-1.5.4.tar.gz \
			 https://sourceforge.net/projects/freetype/files/freetype2/2.4.6/freetype-2.4.6.tar.gz \
			 http://downloads.sourceforge.net/project/ftgl/FTGL%20Source/2.1.3%7Erc5/ftgl-2.1.3-rc5.tar.gz \
			 http://downloads.sourceforge.net/project/wxwindows/2.8.11/wxWidgets-2.8.11.tar.gz \
			 http://sourceforge.net/projects/mathgl/files/mathgl/mathgl%201.11.2/mathgl-1.11.2.tar.gz/download \
			 http://www.qhull.org/download/qhull-2011.1-src.tgz)
	DEPFILENAMES=(libpng-1.5.4.tar.gz \
				freetype-2.4.6.tar.gz \
				ftgl-2.1.3-rc5.tar.gz  \
				wxWidgets-2.8.11.tar.gz \
				mathgl-1.11.2.tar.gz \
				qhull-2011.1-src.tgz)
	DEPMDSUM=(dea4d1fd671160424923e92ff0cdda78 \
			  1dc4af24a86e2f78a49ac6b520a81ec5 \
			  fcf4d0567b7de9875d4e99a9f7423633 \
			  ce80389e1b70d6a518c80b7b715b763e\
			  acd33e68911d9506f60d769dce23f95e \
			  a65061cf2a6e6581182f4df0f3667a8e)

}

function setMacDeps {
	OS_VERSION=`sw_vers -productVersion |sed 's/\.[0-9]*$//'`
	#Dependency ID, URL and name
	DEPIDS=( 0)
	DEPNAMES=( mathgl)
	DEPURLS=( http://sourceforge.net/projects/mathgl/files/mathgl/mathgl%201.11.2/mathgl-1.11.2.tar.gz)
	DEPFILENAMES=( mathgl-1.11.2.tar.gz)
	DEPMDSUM=( acd33e68911d9506f60d769dce23f95e)
	
	
	ACTIVE_GCC_PORT=`port select --list gcc|grep \(active\)`
	if [ $? -ne 0 ] ; then
		echo "macports was not successful in finding the current gcc version"
		exit 1
	fi
	ACTIVE_GCC_PORT=${ACTIVE_GCC_PORT% \(active\)}
}

function installMacPorts {
	#check to see if it's installed
	if [ x"`which port`" == x"" ] ; then
		echo "macports will now be installed..."
		echo "OS_VERSION = $OS_VERSION"

		if [ x"$OS_VERSION" == x"10.5" ] ; then 
			curl -O https://distfiles.macports.org/MacPorts/MacPorts-2.0.3-10.5-Leopard.dmg
			hdiutil attach MacPorts-2.0.3-10.5-Leopard.dmg
		elif [ x"$OS_VERSION" == x"10.6" ] ; then 
			curl -O https://distfiles.macports.org/MacPorts/MacPorts-2.0.3-10.6-SnowLeopard.dmg
			hdiutil attach MacPorts-2.0.3-10.6-SnowLeopard.dmg
		elif [ x"$OS_VERSION" == x"10.7" ] ; then 
			curl -O https://distfiles.macports.org/MacPorts/MacPorts-2.0.3-10.7-Lion.dmg
			hdiutil attach MacPorts-2.0.3-10.7-Lion.dmg
		else
			echo "Mac OS X $OS_VERSION  not supported."
			exit 1
		fi
		if [ $? -ne 0 ] ; then
			 echo "macports dmg could not be mounted"
			 exit 1
		fi

		# use installer to install macports to /opt/local
		sudo installer -pkg /Volumes/MacPorts-2.0.3/MacPorts-2.0.3.pkg -target /opt/local/
		hdiutil detach /Volumes/MacPorts-2.0.3/

		echo "sourcing .profile after macports installation"
		. ~/.profile

		echo "updating macports ports tree to latest..."
		sudo port selfupdate
		if [ $? -ne 0 ] ; then
			echo "macports was not successful in updating ports tree"
			exit 1
		fi
	else
		echo "macports is already already installed."
	fi
}

function setSuseDeps {
	DEPIDS=( 0)
	DEPNAMES=( mathgl)
	DEPURLS=( http://sourceforge.net/projects/mathgl/files/mathgl/mathgl%201.11.2/mathgl-1.11.2.tar.gz/download)
	DEPFILENAMES=( mathgl-1.11.2.tar.gz)
	DEPMDSUM=( acd33e68911d9506f60d769dce23f95e)

}

function detectProxy()
{
	#Check the http proxy variable
	if [ x"$http_proxy" == x"" ] ; then 
		if [ x"$OS_NAME" == x"Darwin" ] ; then
			##Are we using mac? Try to get the proxy automagically

			#PROXY=`system_profiler |grep "Auto Configure URL" | sed 's/^[ ]*//' | sort | uniq | awk {'sub(/^.*:[ \t]*/, "", $0); print $0;'}`
			PROXY=`system_profiler SPNetworkDataType|grep "HTTP Proxy Server" | sed 's/^[ ]*//' |sort | uniq | awk {'sub(/^.*:[ \t]*/, "", $0); print $0;'}`
			PROXYPORT=`system_profiler SPNetworkDataType|grep "HTTP Proxy Port" | sed 's/^[ ]*//' |sort | uniq | awk {'sub(/^.*:[ \t]*/, "", $0); print $0;'}`
			if [ x"$PROXY" != x"" ] ; then
				echo "using proxy as : $PROXY:$PROXYPORT ; hope this works"
				export http_proxy=$PROXY:$PROXYPORT
			fi

			echo "using $http_proxy as the proxy server"
		else
			echo "Proxy not found... Maybe you dont need one."
			echo "	You can set one by passing it as an argument (./getdeps nameofproxy), if required"
			echo " eg: ./getdeps your_proxy_server:12345"
			echo
			echo "Or you can set it at the command line with "
			echo " export http_proxy=your_proxy_server:12345" 
			echo "(where 12345 is the proxy server \"port\"), usually 8080 or 8000"
		fi
	else
		echo "using $http_proxy as the proxy server"
	fi
}

function parseArgs()
{
	if [ $# -ne 2 ] ; then
		#User did not specify a proxy as argument - try to detect
		detectProxy
	elif [ $# -eq 1 ] ; then
		export http_proxy=$1
		echo "using $1 as the proxy server"
	else
		echo "usage : getDeps [proxyserver]"
		exit 1
	fi
}

function testCompiler()
{
	echo "int main(int argc, char *argv[]) { return 0; } ; " > gcctest.c
	gcc gcctest.c -o gcctest

	if [ ! -f gcctest ] ; then
		echo "You do not have gcc (GNU compiler frontend) installed?? Install it into your PATH, then try again."
		exit 1
	fi
	rm gcctest.c gcctest

	echo "int main(int argc, char *argv[]) { return 0; } ; " > gcctest.cpp

	g++ gcctest.cpp -o gcctest
	if [ ! -f gcctest ] ; then
		echo "You do not have g++ (C++ compiler) installed?? Install it into your PATH, then try again."
		exit 1
	fi

	rm gcctest.cpp gcctest
}

function handleMacDistro()
{
	# install deps except mathgl
	echo "installing 3Depict dependencies…"
	sudo port install wget gcc46 libpng freetype ftgl wxWidgets-devel dylibbundler qhull gsl +universal
	if [ $? -ne 0 ] ; then
		echo "macports was not successful in getting the dependencies"
		exit 1
	fi
}

function handleLinuxDistro()
{
	#Attempt to detect some popular linux distros
	echo "Trying to detect your linux system type. "
	echo "If this fails, you should just try to use your package manager to do this"

	GUESS_DISTRIB_BY_PKGMAN="no"
	if [ x`which lsb_release` == x"" ] ; then
		GUESS_DISTRIB_BY_PKGMAN="yes"
	else
		# we have an lsb_release command - use it!
		DISTRIBUTOR=`lsb_release -i  -s`
		if [ $? -eq 0 ] ; then
			if [ x$DISTRIBUTOR == x"Debian" ] ; then
				LINUXDISTRO="DebianLike"
			elif [ x$DISTRIBUTOR == x"Ubuntu" ] ; then
				LINUXDISTRO="DebianLike"
			elif [ x$DISTRIBUTOR == x"LinuxMint" ] ; then
				LINUXDISTRO="DebianLike"
			elif [ x$DISTRIBUTOR == x"SUSE LINUX" ] ; then
				LINUXDISTRO="SuseLike"
			elif [ x$DISTRIBUTOR == x"Fedora" ] ; then
				LINUXDISTRO="RedhatLike"
			elif [ x$DISTRIBUTOR == x"CentOS" ] ; then
				LINUXDISTRO="RedhatLike"
			elif [ x`echo $DISTRIBUTOR  | grep -i redhat` != x"" ] ; then
				LINUXDISTRO="RedhatLike"
			else
				GUESS_DISTRIB_BY_PKGMAN="yes"
			fi
		else
			LINUXDISTRO="Unknown"
		fi
	fi

	#Try to guess based upon package manager binary 
	if [ x"$GUESS_DISTRIB_BY_PKGMAN" != x"no" ] ; then
		if [ x`which apt-get` != x"" ] ; then
			LINUXDISTRO="DebianLike"
		elif [ x`which yum` != x"" ] ; then
			LINUXDISTRO="RedhatLike"
		elif [ x`which zypper` != x"" ] ; then
			LINUXDISTRO="SuseLike"
		else
			LINUXDISTRO="Unknown"
		fi
	fi

	case $LINUXDISTRO in
		DebianLike)
			echo "System appears to be Debian-esque (debian/ubuntu/mint...)."
			echo "Running apt-get:"

			sudo apt-get build-dep 3depict && sudo apt-get install make g++
			if [ $? -ne 0 ] ; then
				echo "Failed to install build-dependencies"
				exit 1
			else
				echo "All done."
				exit 0
			fi
		;;
		RedhatLike)
			echo "System appears to be redhat like"

			sudo yum groupinstall "Development Tools" && sudo yum install yum-utils && sudo yum-builddep 3Depict
			
			if [ $? -ne 0 ] ; then
				echo "Failed to install build dependencies"
				exit 1
			else
				echo "All done."
				exit 0
			fi

		;;
		SuseLike)
			echo "System appears to be suse-like"
			sudo zypper install -t devel_C_C++ && sudo zypper install libxml2-devel wxGTK-devel ftgl-devel libpng14-devel freetype2-devel qhull-devel
		
			echo "Installed as much as is available from repo. Still need some extra deps... Proceeding to source install"
			setSuseDeps	

		;;
		*)	
			#Call setFullDeps to set depnames for error message below
			setFullDeps
		
			echo "--------"
			echo "Are you sure you need to run this?? "
			echo "You are running some unrecognised version of linux "
			echo "you should use your package manager to install these "
			echo "libraries : ${dep_names[*]}"
			echo
			echo "Refusing to continue, otherwise script could break your system..."
			echo "--------"
			echo 
			exit 1
		;;
	esac
}

function runDownloads()
{
	echo "OK, we need to download some libraries, compile them, and try to install them."
	echo " This is a bit of a long-shot, but this script will try to do this automagically."
	echo " Ensure your net connection is good."

	echo "---------"
	echo "Let's go!"
	echo "---------"

	HAVE_ALL_DEPS=0
	if [ -d sources ] ; then
		echo "OK, found the \"sources\" folder. Cool"
	else
		echo "making the source folder"
		mkdir sources
	fi

	echo "Looking for dependencies"

	for i in ${DEPIDS[*]}
	do
		j=${DEPFILENAMES[$i]}
		k=${DEPURLS[$i]}

		if [ ! -f "sources/$j" ] ; then
			echo "Missing sources/$j. Will attempt to download"

case $OS_NAME in
	Darwin) 
		wget $k -O sources/$j
		;;
	*)

			if [ x`which curl` == x"" ] ; then
				echo "the program -curl- was not present.  Aborting"
				echo "Need the files:"
				echo ${DEPFILENAMES[*]}
				echo "supposedly at:"
				echo ${DEPURLS[*]}
				echo "try to find these online, and place in the sources folder"
			fi

			#use CURL to download the file and save it to source/$k	
			curl -L --progress-bar $k -o sources/$j
		;;
esac				
			if [ $? -ne 0 ] ; then
				echo "Couldn't download dependency : $j, from $k :"
				echo "try to find it online, and put it in the sources folder"
			fi

			if [ ! -f "sources/$j" ] ; then
				echo 
				echo "That's not right... i was told it was downloaded, but now I can't find it."
				echo "Something is wrong, you may have to download the file yourself,"
				echo " and place it in the sources folder"
				echo
				echo "Try $k"
				echo "or look online for \"$j\""
				echo 
				echo "will continue in 8 seconds..."
				sleep 8
			fi
		else
			echo "found $j; this is good"
		fi


	done

	echo
	echo
	echo " -------------------------"
	echo
	echo
}

function checkHashes()
{

	for i in ${DEPIDS[*]}
	do
		j=${DEPFILENAMES[$i]}

case $OS_NAME in
	Darwin) 
		#Mac OSX has an undocumented md5sum compat function. Use it
		HASH_SUM=`md5 sources/$j | awk {'sub(/^.*= [ \t]*/, "", $0); print $0;'}`
		;;
	*)
		HASH_SUM=`md5sum sources/$j | awk {'sub(/^.*= [ \t]*/, "", $0); print $0;'}`
		;;
esac

		if [ x"$HASH_SUM" != x"${DEPMDSUM[$i]}" ] ; then
			echo "Warning! The file contents for sources/$j appear to be wrong (hash mismatch). "
			echo "I recommend pressing ctrl+c and downloading the file manually and overwriting it"

			echo "continuing in 20 seconds. Press ctrl+c to abort (recommended)"
			sleep 20
		else
			echo " $j looks OK. Good -- moving on"
			sleep 1
		fi
	done
}

function prepBuildDir()
{
	echo "------------------------------"
	echo "          Extraction"
	echo


	if [ -d decompress ] ; then
	echo "deleting existing decompress folder"
	rm -rf ./decompress
	fi


	echo " Decompressing archives; this can be slow..."



	mkdir -p decompress

	if [ $? -ne 0 ] ; then
	echo "Oh dear, I couldn't make a folder called \"decompress\". Thats odd. Giving up"
	exit 1
	fi

	cd decompress
	for i in ${DEPIDS[*]}
	do
	j=${DEPFILENAMES[$i]}

	echo "Extracting $j"
	if [ x"`echo $j | grep \.tar\.gz`" != x"" ] ; then
		tar -zxf ../sources/$j 
	elif [ x"`echo $j | grep \.tar\.bz2`" != x"" ] ; then
		tar -jxf ../sources/$j 
	elif [  x"`echo $j | grep \.tgz`" != x"" ] ; then
		tar -zxf ../sources/$j 
	elif [ x"`echo $j | grep \.zip`" != x"" ] ; then
		unzip ../sources/$j 
	else
		echo "$j apparently not a tar-gz or zip file! Aborting!"
		exit 1
	fi

	if [ $? -ne 0 ] ; then
		echo "There was a problem extracting $j, aborting"
		exit 1
	fi
	done

	sleep 2

	echo "Re-arranging build directory"
	#FTGL has a tilde in the filename, but not the download, move it.
	mv "ftgl-2.1.3~rc5" "ftgl-2.1.3-rc5"

}

#-----------Entry point------------
OS_NAME=`uname`
parseArgs

#Each platform needs to be initialised in a different way
case $OS_NAME in
	Darwin) 
		#Mac OSX has an undocumented md5sum compat function. Use it
		setMacDeps
		installMacPorts
		handleMacDistro
		sleep 1;
		;;
	MINGW*)
		#This doesn't work under windows.
		echo "This is not functional under windows, due to the difficulty of providing a robust tool chain."
		
		echo "---------------"
		echo " If you want to fix this, please do, and send me the fix!"
		echo "---------------"
		exit 1
		;;
	Linux)
		handleLinuxDistro
	
	;;
	*)
		echo "Your platform was not recognised. Program will proceed, but may fail"
		sleep 1
		setFullDeps
	;;
esac

testCompiler

runDownloads


echo "So it looks like we have downloaded all the files."
echo "I'm just going to check the integrity of these files first."
echo 

checkHashes

prepBuildDir


echo "------------------------------"
echo "          Compilation"

########
for i in ${DEPIDS[*]}
do
	j=${DEPFILENAMES[$i]}

	#Strip the extension from the filename
	if [ x"`echo $j | grep \.tar\.gz`" != x"" ] ; then
		foldername=${j%.tar.gz}
	elif [ x"`echo $j | grep \.tar\.bz2`" != x"" ] ; then
		foldername=${j%.tar.bz2}
	elif [  x"`echo $j | grep \.tgz`" != x"" ] ; then
		foldername=${j%.tgz}
	elif [ x"`echo $j | grep \.zip`" != x"" ] ; then
		foldername=${j%.zip}
	else
		echo "$j apparently not a tar-gz or zip file! Aborting!"
		exit 1
	fi
		
	pushd $foldername

	echo "Attempting to compile ${DEPNAMES[$i]}"
	case "${DEPNAMES[$i]}" in
		libpng)
			# Compile libpng
			case "$OS_NAME" in
				Linux)
					make -f scripts/makefile.linux
					;;
				*)
					echo "Unable to build libpng, unknown platform"
					exit 1
					;;
			esac

			if [ $? -ne 0 ] ; then
				echo "Damn. Unable to build. Aborting"
				exit 1
			fi

			echo "I want to install ${DEPNAMES[$i]} to the system:"
			#install
			sudo make install  -f scripts/makefile.linux
			if [ $? -ne 0 ] ; then
				echo "Damn. Unable to install. Aborting"
				exit 1
			fi

			;;
		wxwidgets)
			# Configure wxwidgets; to let it find this bits its wants
			./configure --enable-unicode --with-opengl

			if [ $? -ne 0 ] ; then
				echo "Damn. Unable to configure. Aborting"
				exit 1
			fi

			echo "OK, configure was good. Building, this will take a while"
			sleep 2

			make

			if [ $? -ne 0 ] ; then
				echo "Damn. Unable to build. Aborting"
				exit 1
			fi

			echo "I want to install ${DEPNAMES[$i]} to the system:"
			#install
			sudo make install
			if [ $? -ne 0 ] ; then
				echo "Damn. Unable to install. Aborting"
				exit 1
			fi
			;;
		
		freetype)
			# Configure freetype
			./configure 

			if [ $? -ne 0 ] ; then
				echo "Damn. unable to configure. aborting"
				exit 1
			fi

			echo "OK, configure was good. Building, this will take a while"
			sleep 2

			make

			if [ $? -ne 0 ] ; then
				echo "Damn. unable to build. aborting"
				exit 1
			fi

			echo "I want to install ${DEPNAMES[$i]} to the system:"
			#install
			sudo make install
			if [ $? -ne 0 ] ; then
				echo "Damn. unable to install. aborting"
				exit 1
			fi
			;;

		ftgl)
			# Configure ftgl
			./configure CXXFLAGS="-fpermissive"

			if [ $? -ne 0 ] ; then
				echo "Damn. unable to configure. aborting"
				exit 1
			fi

			echo "OK, configure was good. Building, this will take a while"
			sleep 2

			make

			if [ $? -ne 0 ] ; then
				echo "Damn. unable to build. aborting"
				exit 1
			fi

			echo "I want to install ${DEPNAMES[$i]} to the system:"
			#install
			sudo make install
			if [ $? -ne 0 ] ; then
				echo "Damn. unable to install. aborting"
				exit 1
			fi
			;;

		mathgl)
			# Configure mathgl. Disable GNU scientific library to remove that dependency
			if [ x"$OS_NAME" == x"Darwin" ] ; then
				PNGDIR=/opt/local
				PNGLIBS=" CXXFLAGS=-I$PNGDIR/include LDFLAGS=-L$PNGDIR/lib "
				echo $PNGLIBS
			fi
			./configure --disable-gsl $PNGLIBS

			if [ $? -ne 0 ] ; then
				echo "Damn. unable to configure. aborting"
				exit 1
			fi

			echo "OK, configure was good. Building, this will take a while"
			sleep 2

			make

			if [ $? -ne 0 ] ; then
				echo "Damn. unable to build. aborting"
				exit 1
			fi

			echo "I want to install ${DEPNAMES[$i]} to the system:"
			#install
			sudo make install
			if [ $? -ne 0 ] ; then
				echo "Mathgl said it failed, but is known to misreport. Continuing in 10 seconds"
				sleep 10
			fi
			;;

		qhull)
			if [ x`which cmake` == "" ] ; then
				echo "Cmake not found on your system. This is needed to build qhull (sigh.). You can install it from http://www.cmake.org/cmake/resources/software.html"
			else
				#build
				cmake .
				make

				#OK, lets install!
				echo "I want to install ${DEPNAMES[$i]} to the system:"
				sudo make install
				if [ $? -ne 0 ] ; then
					echo "Damn. unable to install. aborting"
					exit 1
				fi
			fi
			
			;;
		*)
			echo "There is a bug in the script. I do not know the dependency ${DEPNAMES[$i]}. Aborting"
			exit 1
			;;
	esac
	

 
	popd
done

	
########

echo "------------------------------"
echo "          All done!"

echo 

echo " You should hopefully be able to build and run 3Depict now!"
echo 
echo




