#!/bin/bash
#functions
function check_user()
{
	echo "Checking the root id..............."
	rootid=$UID
	if ((rootid==ROOTID)); then
		echo "${BELL}Error:You should be the normal user to run the install3D!";
		exit 1;
	fi
	echo "You are welcome!"
} 	

function check_input()
{
	echo "Checking the input parameters..............."
	if (($#==0)) || (($1<1)) || (($1>2));then
		echo "${BELL}Usage:install [-u] destdir"
		exit 1
	fi
	if (($1==1));then
		XLOC=$2
	else
		if [[ $2 != '-u' ]];then
			echo "${BELL}Error:'-u' should be entered to uninstall the savage drivers!"
			exit 1;
		else
			XLOC=$3
			check_loc
			uninstall_drv
			exit 1
		fi
	fi
}

function check_loc()
{
	echo "Checking the source location of XFree86 4.2.0:${XLOC}..................."
	if [ -d $XLOC ];then
	    pushd . > /dev/null
	    cd $XLOC > /dev/null
	    XFullLoc=`pwd`
	    popd > /dev/null
  	    echo "The Full path of XFree86 4.2.0 souce code is ${XFullLoc}"
	else
	    echo "${BELL}Error:${XLOC} is not a exist directory!"
	    exit 1
	fi
	
}

function check_version()
{
	echo "Checking the version................."
#get the major version
majorversion=`sed -n '/^\#define[ ]*XF86_VERSION_MAJOR/p' $1|sed -e 's/[\#a\-z[[:space:]]*//g'| sed -e 's/XF86//g' |  sed -e 's/[\A-\Z]//g'`
#get the minor version
minorversion=`sed -n '/^\#define[ ]*XF86_VERSION_MINOR/p' $1|sed -e 's/[\#a\-z[[:space:]]*//g'| sed -e 's/XF86//g' | sed -e 's/[\A-\Z]//g'`
#get the patch version
patchversion=`sed -n '/^\#define[ ]*XF86_VERSION_PATCH/p' $1|sed -e 's/[\#a\-z[[:space:]]*//g'| sed -e 's/XF86//g' | sed -e 's/[\A-\Z]//g'`
#get the combined version
if (( XVERSION == ${majorversion}${minorversion}${patchversion}));then
	echo >/dev/null;
else
	echo "${BELL}Error:The source code is not the XFree86 4.2.0 version!"
	exit 1
fi
}	

function check_cf()
{
 	echo "Checking the config file....................."
	if [ -f ${XFullLoc}${XCF} ];then
		echo >/dev/null
	else
		echo "${BELL}Error:Miss the ${XFullLoc}${XCF}!"
		exit 1
	fi
	if [ -f ${XFullLoc}${XMAKEFILE} ];then
		echo >/dev/null
	else
		echo "${BELL}Error:Miss the ${XFullLoc}${XMAKEFILE}!"
		exit 1
	fi
	if [ -f ${XFullLoc}${XMAKELINUX} ];then
		echo >/dev/null
	else
		echo "${BELL}Error:Miss the ${XFullLoc}${XMAKELINUX}!"
		exit 1
	fi
}
function check_dri()
{
 	echo "Checking the dri....................."
	if [ -d ${XFullLoc}${XDRISOUR} ];then
		echo >/dev/null
	else
		echo "${BELL}Error:The dri source code should be installed first!"
		exit 1
	fi
}


function check_drm()
{
 	echo "Checking the drm..................."
	if [ -d ${XFullLoc}${XKER} ];then
		echo >/dev/null
	else
		echo "${BELL}Error:The drm source code should be installed first!"
		exit 1
	fi
}


function check_mesa()
{
 	echo "Checking the mesa......................"
	if [ -d ${XFullLoc}${XMESA} ];then
		echo >/dev/null
	else
		echo "${BELL}Error:The mesa source code should be installed first!"
		exit 1
	fi
}

function check_savage()
{
    if [ $# == 0 ];then	 	
	echo "Checking the old savage driver installed....................."
	i=0
	while ((i<SCNUM)); do 
		if [ -f ${XFullLoc}${SCHECK[i]} ];then
			j='o'
			while [ $j != 'n' ] && [ $j != 'y' ];do
				echo $i
				echo "${BELL}Warning:The savage 3D driver may be installed,Do you want to continue or abort installing:(y/n)"
				read -n 1 -s j
			done;
			if [ $j == 'n' ]; then
				echo "${BELL}Warning:Exit the installation because savage 3D driver already installed"
				exit 1
			fi
			echo "continue checking.........."
		fi
		((i++))
	done;
    else
	
	echo "Checking the  installed savage driver....................."
	i=0
	while ((i<SCNUM)); do 
		if [ -f ${XFullLoc}${SCHECK[i]} ];then
			echo > /dev/null
		else
				echo "${BELL}Warning:The installation failed! Please first uninstall the savage driver,"
				echo "then reinstall the savage driver"
				exit 1
		fi
		((i++))
	done;
    fi	
}

function check_s3source()
{

	echo "Checking the savage driver to be installed....................."
	i=0
	while ((i<SSNUM)); do 
		if [ -f ${SSRC[i]} ];then
			echo > /dev/null
		else
			echo "${BELL}Error:Miss source code of savage driver!"
			exit 1
		fi
		((i++))
	done;

	echo "The savage driver can be installed into the sourcecode now!"
}


function check_xcinfo()
{
#check the version 
	verfile=${XFullLoc}${XVERSIONFILE};		
	echo "Checking the necessary information of source code XFree86 4.2.0......."
	if [ -f $verfile ];then
		check_version $verfile;
	else
		echo "${BELL}Error:The version file:${verfile} isn't exist!"
		exit 1
	fi
#check config file
	check_cf
#check mesa source code
	check_mesa
#check dri souce code
	check_dri
#check drm source code
	check_drm
#check savage driver
	check_savage
}


function copy_src()
{
	echo "${BELL}Now installing the savage driver source code.........."
        if [ -d ${XFullLoc}${X2D} ];then
		echo >/dev/null
	else
		mkdir ${XFullLoc}${X2D}
	fi
		
        if [ -d ${XFullLoc}${X3D} ];then
		echo >/dev/null
	else
		mkdir ${XFullLoc}${X3D}
	fi

	i=0;
	while ((i<CCNUM));do
		echo "Remove ${SNAME[i]}!"
		rm -f ${XFullLoc}${SDEL[i]}
		echo "install ${SNAME[i]}!"
		cp ${SORI[i]}  ${XFullLoc}${SCOPY[i]}
	((i++))
	done;
	echo "${BELL}Now Complete installing the savage driver source code!"
}

function uninstall_drv()
{

	echo "${BELL}Now uninstalling the savage driver source code.........."
	j=${XFullLoc}${XCF}.s3
	if [ -f ${j} ];then 
		rm -f ${XFullLoc}${XCF}
		cp -f ${j} ${XFullLoc}${XCF} 
	fi
	j=${XFullLoc}${XMAKEFILE}.s3
	if [ -f ${j} ];then 
		rm -f ${XFullLoc}${XMAKEFILE}
		cp -f ${j} ${XFullLoc}${XMAKEFILE} 
	fi
	i=0;
	while ((i<CCNUM));do
		echo "Remove ${SNAME[i]}!"
		rm -f ${XFullLoc}${SDEL[i]}
	((i++))
	done;
	echo "${BELL}Now Complete uninstalling the savage driver source code!"
}
function search_line()
{
	sline=`sed -n -e "/${sstr}/=" ${cfile} |sed -n "1,1p"`
}

function copy_lines()
{
	if (($#==0));then
		sed -n -e "${fline},${sline}p" ${cfile} >> ${tmpFile}
		((sline++))
		((fline=sline))
	else
		sed -n -e "${fline},\$p" ${cfile} >> ${tmpFile}
	fi
}

function rep_line()
{
	sed -n -e "${fline},${sline}p" ${cfile} | sed -e "s/${reps}/${repd}/">>${tmpFile}
	((sline++))
	((fline=sline))	
}	
function write_lines()
{
	i=0
	while ((i<wnum));do
		echo "${fbuf[i]}${wbuf[i]}" >>${tmpFile}
		((i++))
	done;
}
function rep_item
{
	search_line 
	((sline--))
	copy_lines
        rep_line
}
function insert_item
{
	search_line
	((sline-=$1))
	copy_lines
	write_lines
}
function modi_xf86cf()
{
	fline=1
	cfile=${XFullLoc}${XCF}
#touch the new tmp file	
	rm -fr ${tmpFile}
	touch ${tmpFile}
#replace one line match the string	
	sstr="^#${SPTAB}*define${SPTAB}*DriDrivers"
	reps='gamma'
	repd=${DriDrivers}
	rep_item
#insert  line match the string
	sstr="^#${SPTAB}*define${SPTAB}*GlxBuiltInMesa"
	wbuf[0]="#   ifndef GlxBuiltInSavage"
	fbuf[0]=''
	wbuf[1]="#     define GlxBuiltInSavage     NO"
	fbuf[1]=''
	wbuf[2]="#   endif"
	fbuf[2]=''
	wnum=3
	insert_item 2
#insert line match the string
	sstr="^#${SPTAB}*define${SPTAB}*GlxDriverUsesMesa"
	wbuf[0]="GlxBuiltInSavage || \\"
	fbuf[0]=$'\t'
	wnum=1
	insert_item 2
#insert line match the string
	sstr="^#${SPTAB}*define${SPTAB}*GlxUseBuiltInDRIDriver"
	wbuf[0]="GlxBuiltInSavage  || \\"
	fbuf[0]=$'\t'
	wnum=1
	insert_item 2
#insert line match the string	
	sstr="^#${SPTAB}*undef${SPTAB}*DriDrivers"
	wbuf[0]="#      if GlxBuiltInSavage"
	fbuf[0]=''
	wbuf[1]="#         define DriDrivers savage"
	fbuf[1]=''
	wbuf[2]="#      endif"
	fbuf[2]=''
        wnum=3
	insert_item 0
#copy the rest lines to the tmp file
	copy_lines last
#backup the source xfree86 and modify it
	cp -f ${cfile} ${cfile}.s3
	rm -f ${cfile}
	cp -f ${tmpFile} ${cfile}
}
function modi_imakefile()
{
	fline=1
	cfile=${XFullLoc}${XMAKEFILE}
#touch the new tmp file	
	rm -fr ${tmpFile}
	touch ${tmpFile}
#replace one line match the string	
	sstr="${SPTAB}*SRCS"
	reps='xf86drm.c'
	repd='xf86drm.c xf86drmSavage.c'
	rep_item

#replace one line match the string	
	sstr="${SPTAB}*OBJS"
	reps='xf86drm.o'
	repd='xf86drm.o xf86drmSavage.o'
	rep_item
#insert line match the string
	sstr="${SPTAB}*LinkSourceFile"
	wbuf[0]='LinkSourceFile(xf86drmSavage.c,$(XF86OSSRC)/$(OS_SUBDIR2)/drm)'
	fbuf[0]=''
	wnum=1
	insert_item 0

#insert line match the string
	sstr="^#include${SPTAB}*<Library"
	wbuf[0]='LinkSourceFile(savage_drm.h,$(XF86OSSRC)/$(OS_SUBDIR2)/drm/kernel)'
	fbuf[0]=''
	wnum=1
	insert_item 1
#copy the rest lines to the tmp file
	copy_lines last
#backup the source xfree86 and modify it
	cp -f ${cfile} ${cfile}.s3
	rm -f ${cfile}
	cp -f ${tmpFile} ${cfile}
}
function modi_mklinux()
{
	fline=1
	cfile=${XFullLoc}${XMAKELINUX}
#touch the new tmp file	
	rm -fr ${tmpFile}
	touch ${tmpFile}
#replace one line match the string	
	sstr='mga.o'
	reps='mga.o'
	repd='mga.o savage.o'
	rep_item
#insert line match the string	
	sstr="MGAOBJS"
	wbuf[0]='SAVAGEOBJS=    savage_drv.o savage_dma.o savage_state.o'
	fbuf[0]=''
	wbuf[1]='SAVAGEHEADERS= savage.h savage_drv.h savage_drm.h $(DRMHEADERS) $(DRMTEMPLATES)'
	fbuf[1]=''
        wnum=2
	insert_item 1
#insert line match the string	
	sstr='mga_drv.o:'
	wbuf[0]='savage_drv.o: savage_drv.c'
	fbuf[0]=''
	wbuf[1]='$(CC) $(MODCFLAGS) -DEXPORT_SYMTAB -I$(TREE) -c $< -o $@'
	fbuf[1]=$'\t'
	wbuf[2]='savage.o: $(SAVAGEOBJS)'
	fbuf[2]=''
	wbuf[3]='$(LD) -r $^ -o  $@'
	fbuf[3]=$'\t'
        wnum=4
	insert_item 1
#insert line match the string	
	sstr='$(MGAOBJS):'
	wbuf[0]='$(SAVAGEOBJS):$(SAVAGEHEADERS)'
	fbuf[0]=''
        wnum=1
	insert_item 1
#copy the rest lines to the tmp file
	copy_lines last
#backup the source xfree86 and modify it
	cp -f ${cfile} ${cfile}.s3
	rm -f ${cfile}
	cp -f ${tmpFile} ${cfile}
}

function modi_files()
{
	echo "Now modifing the related files....................."
#modify the config/cf/xfree86.cf
	modi_xf86cf
#modify the lib/GL/dri/drm/Imakefile
	modi_imakefile
#modify the programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/Makefile.linux
 	modi_mklinux	
	echo "Finish modifing the related files!"
}
#Global Var
#define the destination to be isntalled for checking
XVERSION=420
XF86DIR="/programs/Xserver/hw/xfree86"
XVERSIONFILE="${XF86DIR}/xf86Version.h"
XDRISOUR="/lib/GL/dri"
X3D="/lib/GL/mesa/src/drv/savage"
X2D="${XF86DIR}/drivers/savage"
XOS="${XF86DIR}/os-support"
XS2D=2D
XS3D=3D
XSDRM=DRM
XSKER=DRM/kernel
XMESA="/extras/Mesa"
XDRM="${XF86DIR}/os-support/linux/drm"
XKER="${XDRM}/kernel"
#define the config file
XCF="/config/cf/xfree86.cf"
XMAKEFILE="${XDRISOUR}/drm/Imakefile"
XMAKELINUX="${XKER}/Makefile.linux"
S2D=0
S3D=1
SDRM=2
SKER=3
SCNUM=4
declare -a SCHECK
SCHECK[S2D]="${X2D}/savage_dri.c"
SCHECK[S3D]="${X3D}/savage_xmesa.c"
SCHECK[SDRM]="${XDRM}/xf86drmSavage.c"
SCHECK[SKER]="${XKER}/savage_dma.c"
ROOTID=0
BELL=$'\a'
SRET=$'\n'
NEWLINE=$'\n'
XLOC=''
XFullLoc=''
#define the src to be installed for checking
declare -a SSRC
SS2D=0
SS3D=1
SSDRM=2
SSKER=3
SSNUM=4

SSRC[SS2D]="${XS2D}/savage_dri.c"
SSRC[SS3D]="${XS3D}/savage_xmesa.c"
SSRC[SSDRM]="${XSDRM}/drm/xf86drmSavage.c"
SSRC[SSKER]="${XSKER}/drm.h"


#define the installation commands and paths
#Note: CCKER3: drmP.h is an additional file needed by C3 cpu for "cmpxchg".
declare -a SDEL
declare -a SCOPY
declare -a SORI
CC2D=0
CC3D=1
CCDRM1=2
CCDRM2=3
CCKER1=4
CCKER2=5
CCKER3=6
CCNUM=7

SDEL[CC2D]="${X2D}/*"
SDEL[CC3D]="${X3D}/*"
SDEL[CCDRM1]="${XDRM}/xf86drmSavage.c"
SDEL[CCDRM2]="${XOS}/xf86drmSavage.h"
SDEL[CCKER1]="${XKER}/savage*"
SDEL[CCKER2]="${XKER}/drm.h"
SDEL[CCKER3]="${XKER}/drmP.h"

SCOPY[CC2D]="${X2D}"
SCOPY[CC3D]="${X3D}"
SCOPY[CCDRM1]="${XDRM}/xf86drmSavage.c"
SCOPY[CCDRM2]="${XOS}/xf86drmSavage.h"
SCOPY[CCKER1]="${XKER}"
SCOPY[CCKER2]="${XKER}/drm.h"
SCOPY[CCKER3]="${XKER}/drmP.h"

SORI[CC2D]="${XS2D}/*"
SORI[CC3D]="${XS3D}/*"
SORI[CCDRM1]="${XSDRM}/drm/xf86drmSavage.c"
SORI[CCDRM2]="${XSDRM}/xf86drmSavage.h"
SORI[CCKER1]="${XSKER}/savage*"
SORI[CCKER2]="${XSKER}/drm.h"
SORI[CCKER3]="drmP.h"

SNAME[CC2D]='2D source'
SNAME[CC3D]='3D source'
SNAME[CCDRM1]='DRM source'
SNAME[CCDRM2]='DRM source'
SNAME[CCKER1]='DRM source'
SNAME[CCKER2]='DRM source'
SNAME[CCKER3]='DRM source'

#define the modified information var
fline=0
sline=0
cfile=' '
sstr=' '
reps=' '
repd=' '
declare -a wbuf
declare -a fbuf
wnum=0
SPTAB='[[:space:]]'
DriDrivers='gamma savage'
tmpFile="/tmp/thisFile"
#check the right permision (root)
#check_user;
#check the input
check_input $# $*;
#check the location of source code of Xfree86 4.2.0
check_loc;
#check the necessary information of Xfree86 4.2.0
check_xcinfo;
#check the savage modules and files to be installed
check_s3source;
#copy the savage modules and files to the right location
copy_src;
#modify the files required
modi_files;
#check the result
check_savage install
echo "${BELL}:Complete the installation!"
