#!/usr/bin/bash
version=23


#######################################################################################
# fonction pour afficher ce que fait le scrip
#######################################################################################
fnusage() {
echo  "vp-screen $version
-c <config file>
--config <config file>
-d daemon mode, autoconfiguration if hotplug/hotunplug screen
--dadmon daemon mode, autoconfiguration if hotplug/hotunplug screen
-h show this message
--help sowh this message
-r <ip> <port> <resolution> activate remote security
--remotedesktop <ip> <port> <resolution> activate remote security
-s Show available monitor
--show Show available monitor
-v show version
--version show version"
}
#######################################################################################

#######################################################################################
# fonction pour deplacer les fenetres aux coordonées négatives
#######################################################################################

fnmovewin() {
x=40 ; y=40
while read id sticky xw yw xs ys host win ; do
        if [[ "$sticky" != -* && ( $xw = -* || $yw = -* ) ]]
                then
                        wmctrl -i -r $id -e 0,$x,$y,-1,-1
                        x=$(($x + 40))
                        y=$(($y + 40))
        fi
done < <(wmctrl -lG)
unset x
unset y
}
#######################################################################################

#######################################################################################
# fonction pour définir la position des écan par rapport au fichier de conf ou en auto
#######################################################################################
fn_vpscreendef() {
# test du paramètrage et applacation utilisateur ou automatique :
if [[ -n "$monconf" ]]
then 
# si fichier conf avec valeur valide : application des setting 
	while read screen size ; do
		(( s=$s+1 ))
		ecran[$s]="$screen:$size"
	done < <(xrandr | grep --no-group-separator -A1 -P '^(?!VIRTUAL).* connected' | awk '{print $1}' | sed 'N;s/\n/ /g')
# unset $s for service loop
unset s
	for mon in $monconf
		do
		if [[ "${mon#*:}" = L* ]]
		then 
			xrds[${mon%%:*}]="--output ${ecran[${mon%%:*}]%%:*} --mode ${ecran[${mon%%:*}]##*:} --left-of ${ecran[${mon##*:}]%%:*} "
		elif [[ "${mon#*:}" = R* ]] 
		then
			xrds[${mon%%:*}]="--output ${ecran[${mon%%:*}]%%:*} --mode ${ecran[${mon%%:*}]##*:} --right-of ${ecran[${mon##*:}]%%:*} "
		else
			xrds[${mon%%:*}]="--output ${ecran[${mon%%:*}]%:*} --mode ${ecran[${mon%%:*}]##*:} "
	
		fi
	done
		

else

# si pas de fichier de conf ou valeur non trouver : alors application automatique des ecrans trouver
	while read screen size ; do
		(( s=$s+1 ))
		ecran[$s]="$screen:$size"
	
		if [[ "$s" = 1 ]]
		then 
		xrdb="$xrdb --output ${ecran[$s]%%:*} --mode ${ecran[$s]##*:} "
		else
		(( er=er+1 ))
		xrds[$er]="--output ${ecran[$s]%%:*} --mode ${ecran[$s]##*:} --right-of ${ecran[$er]%%:*} "
		fi
	done < <(xrandr | grep --no-group-separator -A1 -P '^(?!VIRTUAL).* connected' | awk ' {print $1}' | sed 'N;s/\n/ /g')
# unset $s for service loop
unset s
fi
}
#######################################################################################

#######################################################################################
# fonction d'application des écrans définis
#######################################################################################
fnvpscreenapply() {
# importation du fichier de conf ##
source ${confile:=~/.vp-screenrc}
###################################
#######base de la commande :#######
xrdb="xrandr  --output VIRTUAL1 --off "
###################################
#définition des écran disconected #
while read discoscreen ; do
	(( d=d+1 ))
	discoscreen[$d]="$discoscreen"
	xrdd[$d]="--output ${discoscreen[$d]} --off "
done < <(xrandr | grep -P '^(?!VIRTUAL).* disconnected' | awk '{print $1}')
###################################
# unset $d for service loop
unset d
###################################
# calcul du nombre d'ecran ########
nbm=$(xrandr | grep -c -P '^(?!VIRTUAL).* connected')
# définition du parametrage utilisateur :
eval monconf="\$m$nbm"
###################################
### generation des options pour les ecrans actif##
fn_vpscreendef
##################################################
## application des settings :
## de base et ecran déconectées ##
$xrdb${xrdd[*]}
#unset $xrdd for service loop
unset xrdd
sleep 1
## des ecran actif : #############
cxs="debut"
while [[ -n "$cxs" ]] ; do
	(( cs=$cs+1 ))
	if [[ -n ${xrds[$cs]} ]]
	then 
		xrandr ${xrds[$cs]}
		sleep 1
	fi
	cxs=${xrds[$cs]}
done
#unset $cs $cxs $xrds for service loop 
unset xrds
unset cs
unset cxs
}
#######################################################################################

#######################################################################################
# fonction pour relancer nitrogen si il est présent
#######################################################################################
fnnitro() {
if hash nitrogen 2> /dev/null
	then
	nitrogen --restore
fi
}
#######################################################################################

#######################################################################################
# fonction pour exécuté le script en mode service pour le hotplug/unplug des écrans
#######################################################################################
fnvp-screenservice() {
nmd=$(grep 'disconnected' /sys/class/drm/card*/status | wc -l )
while : ; do
if [[ $nmd = $(grep 'disconnected' /sys/class/drm/card*/status | wc -l ) ]]
        then
                echo $nmd > /dev/null
        else
        nmd=$(grep 'disconnected' /sys/class/drm/card*/status | wc -l )
	fnvpscreenapply
	fnnitro
	fnmovewin
fi
sleep 3 
done
}
#######################################################################################

#######################################################################################
# fonction pour exécuté le script avec secuisation d'une prise de bureau à distance
#######################################################################################
fnremotedesktop() {
rm ~/.screenlayout/disconected
rm ~/.screenlayout/conected
xrandr --addmode VIRTUAL1 $resordp
while :
	do
	netstat -ant | grep "$iprdp:$portrdp .*ESTABLISHED" > /dev/null
	if [[ "$?" = "0" ]] 
		then 
			if [[ -f ~/.screenlayout/conected ]]
				then
					touch ~/.screenlayout/conected
				else
				##~/.screenlayout/Off.sh
					while read discoscreen ; do
				        (( rd=rd+1 ))
				        discoscreen[$rd]="$discoscreen"
				        xrdrd[$rd]="--output ${discoscreen[$d]} --off "
					done < <(xrandr | grep -P '^(?!VIRTUAL1).*connected' | awk '{print $1}')
					xrandr ${xrdrd[*]}
					xrandr --output VIRTUAL1 --mode $resordp
					unset xrdrd
					fnmovewin
					fnnitro
					xscreensaver-command -lock
					touch ~/.screenlayout/conected
					rm ~/.screenlayout/disconected 2> /dev/null
			fi
		else
			if [[ -f ~/.screenlayout/disconected ]]
                                then

                                        touch ~/.screenlayout/disconected
				if [[ $nmd = $(grep 'disconnected' /sys/class/drm/card*/status | wc -l ) ]]
				        then
				                echo $nmd > /dev/null
				        else
					        nmd=$(grep 'disconnected' /sys/class/drm/card*/status | wc -l )
					        fnvpscreenapply
					        fnnitro
					        fnmovewin
				fi
				sleep 3

                                else
				fnvpscreenapply
			        fnnitro
			        fnmovewin
				xscreensaver-command -lock
                                touch ~/.screenlayout/disconected
				rm ~/.screenlayout/conected 2> /dev/null
				rm -rf ~/.nx/*
                        fi
		fi
	sleep 2
done

}
#######################################################################################

#######################################################################################
# Début du script !
#######################################################################################
### Gestion des options ###########
while [[ -n "$1" ]] ; do
	case $1 in
		-c|--config)
			if [[ -n "$2" && "$2" != -* ]]
			then
				confile=$2
				shift
			else
			fnusage
			exit 1
			fi
		;;
		-d|--daemon)
			daemon="yes"
		;;
		-r|--remotedesktop)
			if [[ -n "$2" && "$2" != -* && -n "$3" && "$3" != -* && -n "$4" && "$4" != -* ]]
			then
				iprdp=$2
				portrdp=$3
				resordp=$4
			fnremotedesktop
			else
			fnusage
                        exit 1
                        fi
		;;
		-s|--show)
		echo -e "list of your monitors plugged :\nNumber\tid\tName\t\tresolution"		
		while read screen size ; do
		(( s=$s+1 ))
		name=$(monitor-parse-edid /sys/class/drm/card*${screen%%[[:digit:]]*}-$(echo ${screen##*[[:alpha:]]} | sed 's/-/+/'| bc -l 2> /dev/null )/edid 2> /dev/null | sed -n 's/^Name: \(.*$\)/\1/p')
		echo -e "$s\t$screen\t${name:-no name\t}\t$size"	
		
		done < <(xrandr | grep --no-group-separator -A1 -P '^(?!VIRTUAL).* connected' | awk '{print $1}' | sed 'N;s/\n/ /g')
		exit 0
		;;
		-v|--version)
			echo "vp-screen $version"
			exit 0
		;;
		--)
			break
		;;

		*|-h|--help)
		fnusage
		exit 0
		;;
	esac
	shift
done
###################################
if [[ "$daemon" = yes ]]
	then 
		fnvp-screenservice
	else
		fnvpscreenapply
		fnnitro	
		fnmovewin
fi
