#! /usr/bin/perl

# register-window-manager
# Copyright 1998 Sean Perry, Marcelo Magallon, Branden Robinson and
# Marcus Brinkmann.
# Licensed under the GNU GPL.

# History
# 0.2.7 - Fixed bug: The word boundaries introduced a bug, now checking for
#         whole line matching (#30186, Gorgo). Cleaned up a bit of the
#         source (using numeric values instead of strings in &ifexists). [MB]
# 0.2.6 - Fixed bug: Watch out for word boundaries (#28936, Daniel Martin). [MB]
# 0.2.5 - made /usr/X11R6/bin error more terse [BR]
# 0.2.4 - Fixed bug: The script will refuse to add /usr/X11R6/bin/*
#         window managers. [MB]
# 0.2.3 - minor cosmetic changes [BR]
# 0.2.2 - Removed debug line. [MB]
# 0.2.1 - Fixed bug in --default handling. [MB]
# 0.2   - Fixed minor typo in usage text ("the the" -> "be the"). [MB]
#       - Added removal of /usr/X11R6/bin/* entries. [MB]
#         This is done to remove policy violation of prior window
#         managers.  This is radical, but simple.  At some later time,
#         the code that does this should probably be removed, so even
#         /usr/X11R6/bin/* style paths work.
#       - Added configuration variables. [MB]
#       - Reworked file handling.  Read once, write once, modify array. [MB]
# 0.1   - Initial Version

# Configuration

$wm_file = '/etc/X11/window-managers';
$df_path = '/usr/bin/X11/';

while ($ARGV[0] =~ m/^--/) {
	$_ = shift(@ARGV);
	if (/--add/) {
		$mode="add";
	} elsif (/--remove/) {
		$mode="remove";
	} elsif (/--default/) {
		$mode="default";
	} elsif (/--ask/) {
		$ask="true";
	} else {
		&usage;
	}
}

unless( $#ARGV == 0 ) { 
	&usage;
}

if( $ARGV[0] !~ m/^\// ) {
	$WM = $df_path . $ARGV[0];
}
else {
	$WM = $ARGV[0];
}

open(WMFILE, $wm_file) || 
	die("Error opening $wm_file!\n");
@WMS = <WMFILE>;
close WMFILE;

&kill_dirty_policy_violation();

if ( $ask eq "true") {
	&ask($mode, $WM);
}

if( $mode eq 'add' ) {
	&add_to_file($WM);
} 
elsif( $mode eq 'default' ) {
	&make_default($WM);
} 
elsif( $mode eq 'remove' ) {
	&rm_from_file($WM);
} 

open (WMFILE, '>'.$wm_file) ||
	die("Error opening $wm_file for writing!\n");
print WMFILE @WMS;
close WMFILE;

###
#
# Usage information
#
###
sub usage {
	print <<EOT;
Usage: $0 [--ask] {--add|--default|--remove} <wm>

Options:
  --ask            Asks for confimation of the requested action

Actions:
  --add            Adds the specified window manager to the bottom of the
                   $wm_file file
  --remove         Removes the specified window manager
  --default        Adds the specified window manager to the top of the
                   $wm_file file, thus making it the system
                   default

<wm> can be the full path to the window manager excecutable, or just the
filename ($df_path will be prepended to it).
EOT
	exit(0);
}

###
#
# Asks for confirmation of the requested action
#
###
sub ask {
	($mode) = shift(@_);
	($WM)   = @_;

	print "The following window managers are listed in $wm_file:\n\n";
	foreach (@WMS) {
		if (m/\//) {
			print "\t" . $_;
		}
	}
	print "\n";

	if ($mode eq "add") {
		$prompt = "Do you want to add $WM to the list";
	} elsif ($mode eq "remove") {
		$prompt = "Do you want to remove $WM from the list";
	} elsif ($mode eq "default") {
		$prompt = "Do you want make $WM the default";
	}

	&ask_n($prompt) || exit(0);
}

###
#
# Asks a question, "No" is the default
#
###
sub ask_n {
	my $answer;
	print @_,"? [No] ";
	$answer=<STDIN>;
	return ( $answer =~ /^\s*y/i );
}

###
#
# Adds window manager passed to the end of window-managers file
#
###
sub add_to_file {
	($wm) = @_;

	return if(&ifexists($wm));
	die ("not adding window manager with path /usr/X11R6/bin/ per Debian policy\n") if ($wm =~ /^\/usr\/X11R6\/bin\//);

	push @WMS, $wm."\n";
}

###
#
# Makes window manager passed the default by putting it first
#
###
sub make_default {
	($wm) = @_;
	my $found = -1;

	if(&ifexists($wm)) {
		&rm_from_file($wm);
	}

	while ($WMS[$found+1] !~ /^\// && $found <= $#WMS) {
		$found++;
	}
	splice (@WMS, $found+1, 0, $wm."\n");	# insert window manager at top
}

###
#
# Removes passed window manager from window-managers file
#
###
sub rm_from_file {
	($wm) = @_;
	my @backup = ();

	foreach (@WMS) {
		push (@backup, $_) unless ( m/^$wm$/ );
	}
	@WMS = @backup;
}

###
#
# returns 1 if window manager exists in the file, 0 otherwise
#
###
sub ifexists {
	($wm) = @_;
	foreach (@WMS) {
		if( m/^$wm$/ ) {
			return 1;
		}
	}
	return 0;
}

##
#
# kills all /usr/X11R6/bin/* entries.
#
###
sub kill_dirty_policy_violation {
	my @backup = ();

	foreach (@WMS) {
		push (@backup, $_) unless ( m!^/usr/X11R6/bin/! );
	}
	@WMS = @backup;
}
