package PerlRPG::Console;
use strict;
require Exporter;
use Devel::StackTrace;
use IO::Select;
use vars qw/$StackTraceLevel $LogLevel @InputCallbacks %ConsoleCommands @LogCallbacks @ISA @EXPORT @EXPORT_OK/;

@ISA = qw/Exporter/;

use constant {
	DEBUG	=> 0,
	INFO	=> 1,
	STATUS	=> 2,
	WARN	=> 3,
	ERROR	=> 4,
	CRIT	=> 5,
	FATAL	=> 6,
};
my @debugnames=qw/DEBUG INFO STATUS WARN ERROR CRIT FATAL/;
$StackTraceLevel = ERROR;
$LogLevel = DEBUG;
@LogCallbacks = ();
@InputCallbacks = (\&StdinConsole);

@EXPORT_OK = ();
@EXPORT = qw/DEBUG INFO STATUS WARN ERROR CRIT FATAL LogData/;

sub LogData {
	my($level, $log, @args)=@_;
	my($file, $line);
	(undef, $file, $line)=caller();
	if($level < DEBUG || $level > FATAL) {
		$level = FATAL;
	}
	return if($level < $LogLevel);

	my $str = sprintf("[%6s] %s $log\n", $debugnames[$level], scalar localtime(), @args);
	my $stack;

	if($level >= $StackTraceLevel) {
		my $trace = Devel::StackTrace->new;
		$stack=$trace->as_string();
	}

	print $str . $stack;
	foreach my $ref (@LogCallbacks) {
		$ref->($level, $log, $file, $line, $str, $stack);
	}
}

sub HandleConsole {
	foreach my $ref (@InputCallbacks) {
		my @lines = $ref->();
		foreach (@lines) {
			ConsoleLine($_);
		}
	}
}

sub ConsoleLine {
	my $line=shift(@_);
	LogData(DEBUG, "Got console input '$line'");
}

my $InBuf='';
my $InSelect=IO::Select->new(\*STDIN);
sub StdinConsole {
	while($InSelect->can_read(0)) {
		my $buffer;
		my $bytes = read(STDIN, $buffer, 1024, 0);
		$InBuf.=$buffer;
	}

	my @lines=split(/\n/, $InBuf);
	my $InBuf = shift(@lines);
	return @lines;
}

1;
