package PerlRPG::Script;
use strict;
require Exporter;
use SDL;
use SDL::Event;
use SDLx::App;
use SDLx::Sprite;
use SDLx::Sprite::Animated;
use PerlRPG::Console;
use PerlRPG::Game;
use PerlRPG::Assets;

use vars qw/@ISA @EXPORT @EXPORT_OK/;
@ISA = qw/Exporter/;
@EXPORT = qw/CompileScripts RunScript RunScriptTick/;
@EXPORT_OK = @EXPORT;

my %labels;
my $current_file;
my $current_line;

my %script_commands = (
	'Wait'			=> {'sub' => sub {},					'wait'	=> 1},
	
	'Jump'			=> {'sub' => \&PerlRPG::Script::RunScript,		'wait'	=> 0},

	'Show'			=> {'sub' => \&PerlRPG::Drawing::ShowSprite,		'wait'	=> 0},
	'Hide'			=> {'sub' => \&PerlRPG::Drawing::HideSprite,		'wait'	=> 0},
	'SetBackground'		=> {'sub' => \&PerlRPG::Drawing::SetBackgroundColor,	'wait'	=> 0},

	'ScanDirectory'		=> {'sub' => \&PerlRPG::Assets::ScanDirectory,		'wait'	=> 0},
	'LoadAssets'		=> {'sub' => \&PerlRPG::Assets::LoadAssets,		'wait'	=> 0},
	'UnloadAsset'		=> {'sub' => \&PerlRPG::Assets::UnloadAsset,		'wait'	=> 0},
	'SetAssetOption'	=> {'sub' => \&PerlRPG::Assets::SetAssetOption,		'wait'	=> 0},
);

# Load script files, locate labels
sub CompileScripts {
	my @scripts = sort { $a cmp $b } LoadAssets('gs');
	%labels = ();
	
	foreach my $name (@scripts) {
		my $ref = GetAsset($name);
		for(my $line = 0; $line < @$ref-0; $line++) {
			my($lbl)=$ref->[$line]=~/^\s*(\S+):\s*$/;
			if($lbl) {
				$labels{$lbl} = {
					'File'	=> $name,
					'Line'	=> $line,
					};
				LogData(DEBUG, "Found script label '$lbl' at $name:$line");
			}
		}
	}
}

# Setup script to run
sub RunScript {
	my($label)=@_;

	if(exists $labels{$label}) {
		$current_file = $labels{$label}{'File'};
		$current_line = $labels{$label}{'Line'};
		LogData(DEBUG, "RunScript($label) moving to $current_file:$current_line");
	} else {
		LogData(ERROR, "RunScript($label) unknown label");
	}
}

# Run script from current position until a wait condition
sub RunScriptTick {
	for(;;) {
		my $script = GetAsset($current_file); # current_file can change in RunScriptLine, so reload each time
		my $file = $current_file;
		my $line = $current_line++;
		if($line >= @$script) {
			LogData(ERROR, "Script file ended");
			SetOption('Running', 0);
			return;
		}
		if(RunScriptLine($file, $line, $script->[$line])) {
			return;
		}
	}
};

# Returns true if a wait condition is seen
sub RunScriptLine {
	my($file, $linenum, $line)=@_;

	# Remove comments	
	$line=~s/#.+$//; # Remove comments
	$line=~s/^\s+//; # Remove leading whitespace
	$line=~s/\s+$//; # Remove trailing whitespace

	if($line=~/^\s*\S+:\s*$/ || $line=~/^\s+$/ || !$line) {
		# Label or blank, skip
		return 0;
	}

	my($cmd, @opts)=split(/\s+/, $line);
	LogData(DEBUG, "$file:$linenum $cmd(" . join(',',@opts) . ")");
	if(exists $script_commands{$cmd}) {
		$script_commands{$cmd}{'sub'}->(@opts);
		return $script_commands{$cmd}{'wait'};
	}

	LogData(ERROR, "Unknown command '$cmd' in script at $file:$linenum");
	return undef;
}
1;
