#!/usr/local/bin/perl -w
#
# FNET/ICB CLIENT 1.4   11/12/97
# John M Vinopal        banshee@resort.com
#
# Copyright (C) 1996,1997, The Resort, All Rights Reserved.
# Permission is granted to copy and modify this program for
# non-commercial purposes, so long as this copyright notice is
# preserved.  This software is distributed without warranty.
#

package CMDLINE;

use strict;
#use diagnostics;

$| = 1;	# Flush stdout!

# cmdline is a raw mode tty hack to emulate all the stdin
# line editing tools in an os independent manner.  sequences
# like ^w just never exist on anything but unix.
# cmdline(End of line Char, OS Type, Function Ref for Tabs)
sub	cmdline
{
	my ($EOL, $os, $tabfunc) = @_;
	my ($line, $linelen);
	$line = '';
	$linelen = 0;
	
	while (1) {
		my ($ch, $ordch, $backspace);
		until (defined($ch = getc())) {;}
		$backspace = 0;
		
	GO: $ordch = ord($ch);
		if ($ordch > 31 && $ordch < 127) {			# Add a normal character.
			# XXXX - define buffersize somewhere else.
			if ($linelen == 200) {		# A finite input buffer.
				print "\007";
			} else {
				$line = $line.$ch;
				$linelen++;
				print $ch;
			}
		} else {
			if ($ordch == 3) {		# Ctrl-c.
				if ($linelen == 0) {
					print "^c: use /quit$EOL";
					goto EXIT;
				}
				$line = '';
				$backspace = $linelen;
			} elsif ($ordch == 8 || $ordch == 127) {		# Ctrl-h
				if ($linelen == 0) {
					goto EXIT;
				}
				$line = substr($line, 0, $linelen-1);
				$backspace = 1;
			} elsif ($ordch == 9) {		# Ctrl-i. Tab.
				if ($linelen == 0) {
					my	($str, $len);
					($ch, $len, $str) = &$tabfunc();
					$line = $str;
					$linelen = $len;
					goto GO if ($ch);
				}
			} elsif ($ordch == 10) {	# Ctrl-j. NL.
				goto EXIT;
			} elsif ($ordch == 13) {	# Ctrl-m. Return.
				goto EXIT;
			} elsif ($ordch == 18) {	# Ctrl-r
				if ($linelen == 0) {
					goto EXIT;
				}
				print "$EOL";
				print $line;
			} elsif ($ordch == 21) {	# Ctrl-u
				if ($linelen == 0) {
					goto EXIT;
				}
				$line = '';
				$backspace = $linelen;
			} elsif ($ordch == 23) {	# Ctrl-w
				if ($linelen == 0) {
					goto EXIT;
				}
				my $pos = $linelen-1;
				# Skip all of the spaces.
				while ($pos >= 0 and (substr($line, $pos, 1) eq ' ')) {
					$backspace++;
					$pos--;
				}
				# And one following word.
				while ($pos >= 0 and (substr($line, $pos, 1) ne ' ')) {
					$backspace++;
					$pos--;
				}
			} elsif ($ordch == 26) {	# Ctrl-z
				if ($os eq "Unix") {
					kill 'TSTP', $$;
				} else {
					print "\007";
				}
			} else {			# Beep and complain.
				if ($linelen == 0) {
					goto EXIT;
				}
				print "Bad Char: $ordch";
			}

			# Clean up the line after the control character.
			if ($linelen > 0) {
				if ($backspace > 0) {
					print "\010" x $backspace;
					print "\040" x $backspace;
					print "\010" x $backspace;
					$linelen -= $backspace;
					$backspace = 0;
					if ($linelen == 0) {
						$line = '';
						goto EXIT;
					}
				}
				# Clip the stored line to $linelen characters.
				$line = substr($line, 0, $linelen);
			}
		}
	} # End while(1) loop.
	EXIT:
	if ($linelen == 0) {
		print "\007";
	}
	return($line);
}
	
1;
