#! /bin/bash

# Compiles software necessary for MoviX

echo "

This script will compile software necessary for MoviX. 
It needs the unpacked sources in /home/movix/work/source, you can get
them with 'download-sources; unpack-sources'.
This can take a couple of hours even on a fast computer!

Press CTRL+C now if you don't want to start now.
"

# Constants and setup
targetname=movix
workdir=/home/movix/work
configdir=$workdir/config
sourcedir=$workdir/source
targetdir=$workdir/target/$targetname

# ------------- No need to change anything below ------------
# Work begins here

compileKernel=y
compileAlsa=y
compileBusybox=y
compileLirc=y
compileDevfsd=n
compileEm8300=y
compileAalib=y
compileMplayer=y
compilePerl=n
compileSdl=y
compileTvout=y
compileOnly=0
optimizeSize=n
disableWin=n
withDvd=n
remoteType=hauppauge	# default lirc remote type
while getopts ":hkKaAbBcClLdDeEmMpPsStTr:Xv:Wz" opt; do
	case $opt in

		# help
		h )	echo "Usage:
  -h      this help

  -k -K   compile/don't compile the kernel (default: compile)
  -a -A   compile/don't compile ALSA + mixer utils (default: compile)
  -b -B   compile/don't compile busybox (default: compile)
  -c -C   compile/don't compile aalib (default: compile)
  -l -L   compile/don't compile LIRC (default: compile)
  -d -D   compile/don't compile devfsd (default: don't compile)
  -e -E   compile/don't compile EM8300/DXR (default: compile)
  -m -M   compile/don't compile MPlayer (default: compile)
  -p -P   compile/don't compile perl (default: don't compile)
  -s -S   compile/don't compile SDL (default: compile)
  -t -T   compile/don't compile TV out utilities (default: compile)

  -r type LIRC remote type (e.g. hauppauge, any, none etc.)

  -X      use the bundled DVD library of MPlayer (if legal in your country)
  -v foo  leave out MPlayer feature(s), e.g. 
                    -v aa,sdl,freetype,cdparanoia,lirc,vorbis
  -W      disable Windows/Real/QT DLL support
  -z      optimize MPlayer for size instead of speed
   		"
		exit

		;;
		# compile the kernel
		k ) 	compileKernel=y
			compileOnly=k
		;;
		# don't compile the kernel
		K )	compileKernel=n
		;;

		# compile ALSA
		a )	compileAlsa=y
			compileOnly=a
		;;
		# don't compile ALSA
		A )	compileAlsa=n
		;;

		# compile busybox
		b )	compileBusybox=y
			compileOnly=b
		;;
		# don't compile busybox
		B )	compileBusybox=n
		;;

		# compile aalib
		c )	compileAalib=y
			compileOnly=c
		;;
		# don't compile aalib
		C )	compileAalib=n
		;;

		# compile LIRC
		l )	compileLirc=y
			compileOnly=l
		;;
		# don't compile LIRC
		L )	compileLirc=n
		;;

		# compile devfsd
		d )	compileDevfsd=y
			compileOnly=d
		;;
		# don't compile devfsd
		D )	compileDevfsd=n
		;;

		# compile EM8300
		e )	compileEm8300=y
			compileOnly=e
		;;
		# don't compile EM8300
		E )	compileEm8300=n
		;;

		# compile MPlayer
		m )	compileMplayer=y
			compileOnly=m
		;;
		# don't compile MPlayer
		M )	compileMplayer=n
		;;

		# compile perl
		p )	compilePerl=y
			compileOnly=p
		;;
		# don't compile perl
		P )	compilePerl=n
		;;

		# compile SDL
		s )	compileSdl=y
			compileOnly=s
		;;
		# don't compile SDL
		S )	compileSdl=n
		;;

		# compile TV-out stuff
		t )	compileTvout=y
			compileOnly=t
		;;
		# don't compile TV-out stuff
		T )	compileTvout=n
		;;

		# leave out modules
		v )	withoutModules="$OPTARG"
		;;

		# disable Win32/Real/QT DLL support
		W )	disableWin=y
		;;

		# use MPlayer's bundled DVD library
		X )	withDvd=y
		;;

		# optimize MPlayer for size instead of speed
		z )	optimizeSize=y
		;;

		# Remote type for the LIRC module compilation
		r )	remoteType="$OPTARG"
		;;
	esac
	#shift
done

# If one program is selected for compilation, unset the others
test "$compileOnly" != "0" && test "$compileOnly" != "k" && compileKernel=n
test "$compileOnly" != "0" && test "$compileOnly" != "a" && compileAlsa=n
test "$compileOnly" != "0" && test "$compileOnly" != "b" && compileBusybox=n
test "$compileOnly" != "0" && test "$compileOnly" != "c" && compileAalib=n
test "$compileOnly" != "0" && test "$compileOnly" != "l" && compileLirc=n
test "$compileOnly" != "0" && test "$compileOnly" != "d" && compileDevfsd=n
test "$compileOnly" != "0" && test "$compileOnly" != "e" && compileEm8300=n
test "$compileOnly" != "0" && test "$compileOnly" != "m" && compileMplayer=n
test "$compileOnly" != "0" && test "$compileOnly" != "p" && compilePerl=n
test "$compileOnly" != "0" && test "$compileOnly" != "s" && compileSdl=n
test "$compileOnly" != "0" && test "$compileOnly" != "t" && compileTvout=n

for line in "k-Kernel-the kernel" \
		a-Alsa-ALSA \
		b-Busybox-busybox \
		c-Aalib-aalib \
		"l-Lirc-LIRC (remote type: $remoteType)" \
		d-Devfsd-devfsd \
		"e-Em8300-EM8300/DXR" \
		m-Mplayer-MPlayer \
		s-Sdl-SDL \
		"t-Tvout-TV out utilities"; do
	
	# get the code
	code=`echo "$line" | perl -pwe 's/^(.)-(.+)-(.+)$/$1/'`
	ucode=`echo $code | tr a-z A-Z`

	# get the name of the variable
	varname=`echo "$line" | perl -pwe 's/^(.)-(.+)-(.+)$/$2/'`
	text=`echo "$line" | perl -pwe 's/^(.)-(.+)-(.+)$/$3/'`

	# get the value of this variable
	varvalue=`set | grep "^compile$varname=" | sed 's/^.*=//'`

	if [ "$varvalue" == "y" ]; then
		echo "Will compile $text, use -$ucode to disable"
	else
		echo "Won't compile $text, use -$code to enable"
	fi
	
done

# Give the user some time 
sleep 4

pushd $sourcedir

mkdir -p $targetdir/lib/modules $targetdir/usr/bin $targetdir/usr/sbin

if [ "$compileKernel" = "y" ]; then
	# -------------- Patch the kernel ------------------------
	echo "Applying kernel patches..."
	for patch in kernel-patches/*; do
		if [ -e "$patch" ]; then
		# this is a real file (and not the * from an empty dir)
			if [ -e "$patch.did" ]; then
			# Patch already applied
				echo "$patch was already applied"
			else
				touch "$patch.did"
				patch -p0 < "$patch" || exit 1

				# This is dumb but it works
				rm -f kernel-patches/*.did.did
			fi
		fi
	done

	# -------------- Compile the kernel ------------------------
	pushd linux
	cp $configdir/kernelConfig.$targetname .config
	# We use the supplied kernelConfig.movix file. If the unpacked kernel is newer,
	# make oldconfig will just ask for the new options.
	make oldconfig || exit 1

	# Add the name of this software to the kernel name
	perl -pw -i.bak -e "s/^EXTRAVERSION.+$/EXTRAVERSION = $targetname/" Makefile
	
	make dep || exit 1
	make bzImage || exit 1
	make modules || exit 1
	make modules_install INSTALL_MOD_PATH=$targetdir || exit 1
	cp arch/i386/boot/bzImage $targetdir/vmlinuz
	
	# Let's hope that this will give us the correct module dir... (probably the highest version number)
	kernelver=`ls $targetdir/lib/modules/ | egrep "^[0-9.]+$targetname$" | sort | tail -1`
	moddir="$targetdir/lib/modules/$kernelver"

	cp drivers/video/fbcon-*.o $moddir/kernel/drivers/video
	
	popd
fi

# Let's hope that this will give us the correct module dir... (probably the highest version number)
kernelver=`ls $targetdir/lib/modules/ | egrep "^[0-9.]+$targetname$" | sort | tail -1`
moddir="$targetdir/lib/modules/$kernelver"

# --------------- ALSA -----------------------------------
if [ "$compileAlsa" = "y" ]; then
	# ------ drivers -----------
	pushd alsa
	cp $configdir/alsaConfig.$targetname .
	sh alsaConfig.$targetname

	make || exit 1
	make prefix=$targetdir/alsa moddir=$moddir/misc install-modules || exit 1
	popd

	# ------ lib -----------
	pushd alsa-lib
	CFLAGS="-Os" ./configure 

	make || exit 1
	make prefix=$targetdir/alsa exec_prefix=$targetdir/alsa install || exit 1
	strip $targetdir/alsa/lib/libasound.so
	popd

	# ------ utils -----------
	pushd alsa-utils
	CFLAGS="-Os" ./configure

	# Optimize for size, not speed
	perl -pw -i.ori -e 's/^ -O[0-9] / -Os /' Makefile

	make || exit 1
	make prefix=$targetdir/alsa install || exit 1
	strip $targetdir/alsa/bin/* $targetdir/alsa/sbin/*
	popd

	# ------ other mixers -----------------
	pushd nmixer
	./configure --without-x
	make CFLAGS=-Os
	strip nmixer
	make prefix=$targetdir/nmixer install
	popd

	pushd rexima
	make CFLAGS="-Os -Wall"
	strip rexima
	make PREFIX=$targetdir/rexima install
	popd
fi

# --------------- LIRC -----------------------------------
if [ "$compileLirc" = "y" ]; then
	pushd lirc
	./configure --with-kerneldir=$sourcedir/linux --with-moduledir=$moddir/misc --sysconfdir=$targetdir/lirc/etc --with-driver=$remoteType --without-x
	# Alter makefiles so they don't try to create the device node
	find . -name Makefile | xargs perl -pw -i.ori -e 's!/bin/mknod!/bin/echo!'      
	# Alter makefiles for compilation with -Os and without debugging symbols
	find . -name Makefile | xargs perl -pw -i.ori -e 's!CFLAGS *= *-O2 -g!CFLAGS = -Os!'      
	make || exit 1
	make prefix=$targetdir/lirc install || exit 1
	strip $targetdir/lirc/bin/* $targetdir/lirc/sbin/* $targetdir/lirc/lib/liblirc_client*
	popd
fi

# --------------- DXR -----------------------------------
if [ "$compileEm8300" = "y" ]; then
	pushd em8300
	./configure --with-kerneldir=$sourcedir/linux --with-moduledir=$moddir/misc --without-x --without-gtk --disable-gtk --with-gtk-config=no --disable-gtktest
	# Alter makefiles so they don't try to uninstall headers from the wrong place
	find . -name Makefile | xargs perl -pw -i.ori -e 's!( |\t)/usr/include!\$\{prefix\}/include!'      
	# Alter makefiles for compilation without -g but with -Os
	find . -name Makefile | xargs perl -pw -i.ori -e 's! -g *-O2 ! -Os !'
	make || exit 1
	echo "make ready"
	make prefix=$targetdir/em8300 install || exit 1
	echo "make install ready"
	strip $targetdir/em8300/bin/* $targetdir/em8300/lib/*.so

	# Separate building of kernel modules
	pushd modules
	# Write the kernel location into the makefile
	perl -pw -i.ori -e \
		"s!^KERNEL_LOCATION.+\$!KERNEL_LOCATION=$sourcedir/linux!" \
		Makefile
	make
	cp -v em8300.o adv717x.o bt865.o $moddir/kernel/drivers/video

	popd # modules

	popd
fi

# --------------- Busybox -----------------------------------
if [ "$compileBusybox" = "y" ]; then
	pushd busybox
	cp $configdir/busyboxConfig.$targetname .config
	make dep || exit 1
	make || exit 1
	make PREFIX=$targetdir/busybox install || exit 1
	popd
fi

# --------------- AAlib -----------------------------------
if [ "$compileAalib" = "y" ]; then
	pushd aalib
	CFLAGS="-Os" ./configure --with-x11-driver=no --with-slang-driver=no \
		--without-gpm || exit 1
	make || exit 1
	make prefix=$targetdir/aalib install || exit 1
	strip $targetdir/aalib/lib/libaa*
	popd
fi

# --------------- SDL -----------------------------------
if [ "$compileSdl" = "y" ]; then
	pushd sdl
	cp $configdir/sdlConfig.$targetname .
	CFLAGS=-Os sh sdlConfig.$targetname

	#Need to apply patches?
	if [ -e $configdir/sdlPatch1 ]; then
		cp $configdir/sdlPatch? .
		for patch in sdlPatch? ; do
			if [ -e $patch.did ]; then
				echo "Patch $patch already applied."
			else
				echo "Applying patch $patch..."
				patch -p1 < $patch || exit 1
				touch $patch.did
			fi
		done
	fi

	make || exit 1
	make prefix=$targetdir/sdl install || exit 1
	strip $targetdir/sdl/lib/*.so

	# Insert the real directory into the sdl-config script
	perl -pw -i.ori \
		-e "s#^prefix=/usr/local#prefix=$targetdir/sdl#" \
		$targetdir/sdl/bin/sdl-config

	popd
fi

# --------------- perl -----------------------------------
if [ "$compilePerl" = "y" ]; then
	pushd perl
	cp $configdir/perlConfig.$targetname config.sh
	sh Configure -des || exit 1
	make || exit 1
	make install || exit 1
	popd
fi

if [ "$compileTvout" = "y" ]; then
	# --------------- Matroxset -----------------------------------
	pushd matroxset
	make CFLAGS="-Os -W -Wall" || exit 1
	strip matroxset
	cp matroxset $targetdir/usr/bin
	popd

	# --------------- ATItvout -----------------------------------
	pushd atitvout
	perl -pw -i.ori -e 's/ -O2 / -Os /' Makefile
	make || exit 1
	make strip || exit 1
	cp atitvout $targetdir/usr/bin
	popd

	# --------------- s3switch -----------------------------------
	pushd s3switch
	make CC="gcc -Os" || exit 1
	strip s3switch
	cp s3switch $targetdir/usr/bin
	popd

	# --------------- nvtv -----------------------------------
	pushd nvtv
	./configure --with-x=no --with-gtk=no --with-wx=no
	make CFLAGS=-Os || exit 1
	make prefix=$targetdir/nvtv install || exit 1
	strip $targetdir/nvtv/bin/*
	popd

	# --------------- EPIA kernel module and tv out ----------
	pushd epiafb
	make INCLUDES="-I$sourcedir/linux/include" || exit 1
	cp epiafb.o $moddir/kernel/drivers/video/
	popd

	pushd epiatvout
	make || exit 1
	strip tvout
	mv tvout $targetdir/usr/bin/epiatvout
	popd
fi

# --------------- devfsd -----------------------------------
if [ "$compileDevfsd" = "y" ]; then
	pushd devfsd
	make KERNEL_DIR=$sourcedir/linux || exit 1
	strip devfsd
	make install PREFIX=$targetdir/devfsd || exit 1
	popd
fi

# --------------- and finally mplayer --------------------------
if [ "$compileMplayer" = "y" ]; then
	pushd mplayer

	# First, some directories with stuff that isn't necessary for
	# Movix are moved into zipfiles so they don't get compiled.
	# libfame, libmp1e are for encoding.
	# opendivx is for divx.com codec integration.
	for lib in libfame libmp1e opendivx; do
		if [ -d $lib ]; then
			zip -qrm9 $lib.zip $lib/
		fi
	done

	if [ "$withDvd" = "y" ]; then
	# Use mplayer's bundled DVD library
		if [ -e libmpdvdkit2.zip ]; then
		# the directory is zipped (previous run without -X)
			unzip -q libmpdvdkit2.zip
			rm libmpdvdkit2.zip
		fi
	else
		# MPlayer shouldn't compile the bundled dvd reading software because that
		# could get us in legal trouble. So move the dvd directory to a zip file.
		if [ -d libmpdvdkit2 ]; then
			zip -rmq9 libmpdvdkit2.zip libmpdvdkit2/
		fi
	fi

	#Need to apply patches?
	if [ -e $configdir/mplayerPatch1 ]; then

		cp $configdir/mplayerPatch* .
		# Ignore patches with a version number, they were symlinked anyway.
		rm mplayerPatch*.*
		
		for patch in mplayerPatch* ; do
			if [ -e $patch.did ]; then
				echo "Patch $patch already applied."
			else
				echo "Applying patch $patch..."
				patch -p1 < $patch || exit 1
				touch $patch.did
			fi
		done
	fi

	cp $configdir/mplayerConfig.$targetname .

	if [ "$disableWin" = "y" ]; then
		echo "Disabling Windows support..."
		perl -pw -i.ori -e \
			's/enable-(dshow|win32|qtx(-codecs)?|real)/disable-$1/g' \
			mplayerConfig.$targetname
		perl -pw -i.ori -e \
			's/--with-win32libdir=[^ ]+//' \
			mplayerConfig.$targetname
	fi

	if [ "X$withoutModules" != "X" ]; then
		vomodules=`echo -n "$withoutModules" | sed "s/,/ /g"`
		for vomod in $vomodules; do
			echo "Disabling $vomod support..."
			perl -pw -i.ori -e \
				"s/enable-$vomod/disable-$vomod/" \
				mplayerConfig.$targetname
		done
	fi
	
	# Things fail in myterious ways if we don't do this
	make clean

	sh mplayerConfig.$targetname || exit 1
	if [ "$optimizeSize" = "y" ]; then
		# Change -O4 to -Os in config.mak
		perl -pw -i.ori -e 's/^(OPTFLAGS *=.*)-O4/$1-Os/' config.mak
	fi
	make || exit 1
	make DESTDIR=$targetdir/mplayer install || exit 1
	cp TVout/matroxtv $targetdir/usr/bin

	# Separately compile the mga_vid kernel module. Errors (that could 
	# happen if the kernel source is not here) are ignored.
	cd drivers
	perl -pw -i.ori -e 's/^[ 	]depmod -a/	echo depmod -a/' Makefile
	make KERNEL_INCLUDES=$sourcedir/linux/include
	make MDIR=$moddir/kernel/drivers/video/matrox install

	popd
fi

# one last popd
popd
