# Perl example to save and load SimulatorSettings and WarriorInfo's.
# version 0.02 created on 13 march 2010 by Skybuck Flying ! ;) :)
#
# SimulatorSettings and WarriorInfo's are save and loaded in binary.
#

$false = 0;
$true = 1;

$SizeOfBoolean = 1;
$SizeOfInteger = 4;
$SizeOfTSimulatorBattleType = 1;
$SizeOfTSimulatorScoringType = 1;

sub ReadSimulatorSettings
{
	if ( read( InputFile, $mPSpaceEnabled,$SizeOfBoolean ) != $SizeOfBoolean ) { return $false; } 
	if ( read( InputFile, $mCoreSize, $SizeOfInteger ) != $SizeOfInteger ) { return $false; } 
	if ( read( InputFile, $mPSpaceSize, $SizeOfInteger ) != $SizeOfInteger ) { return $false; } 
	if ( read( InputFile, $mMaxWarriorSize, $SizeOfInteger ) != $SizeOfInteger ) { return $false; } 
	if ( read( InputFile, $mMaxWarriorCount, $SizeOfInteger ) != $SizeOfInteger ) { return $false; } ;
	if ( read( InputFile, $mMaxProcesses, $SizeOfInteger ) != $SizeOfInteger ) { return $false; } 
	if ( read( InputFile, $mMaxCycles, $SizeOfInteger ) != $SizeOfInteger ) { return $false; } 
	if ( read( InputFile, $mMaxRounds, $SizeOfInteger ) != $SizeOfInteger ) { return $false; } 
	if ( read( InputFile, $mMinDistance, $SizeOfInteger ) != $SizeOfInteger ) { return $false; } 
	if ( read( InputFile, $mBattleType, $SizeOfTSimulatorBattleType ) != $SizeOfTSimulatorBattleType ) { return $false; } 
	if ( read( InputFile, $mScoringType, $SizeOfTSimulatorScoringType ) != $SizeOfTSimulatorScoringType ) { return $false; } 

	$mPSpaceEnabled = unpack( "C", $mPSpaceEnabled );
	$mCoreSize = unpack( "L", $mCoreSize );
	$mPSpaceSize = unpack( "L", $mPSpaceSize );
	$mMaxWarriorSize = unpack( "L", $mMaxWarriorSize );
	$mMaxWarriorCount = unpack( "L", $mMaxWarriorCount );
	$mMaxProcesses = unpack( "L", $mMaxProcesses );
	$mMaxCycles = unpack( "L", $mMaxCycles );
	$mMaxRounds = unpack( "L", $mMaxRounds );
	$mMinDistance = unpack( "L", $mMinDistance );
	$mBattleType = unpack( "C", $mBattleType );
	$mScoringType = unpack( "C", $mScoringType );

	return $true;
}

sub WriteSimulatorSettings
{
	$mPSpaceEnabled = pack( "C", $mPSpaceEnabled );
	$mCoreSize = pack( "L", $mCoreSize );
	$mPSpaceSize = pack( "L", $mPSpaceSize );
	$mMaxWarriorSize = pack( "L", $mMaxWarriorSize );
	$mMaxWarriorCount = pack( "L", $mMaxWarriorCount );
	$mMaxProcesses = pack( "L", $mMaxProcesses );
	$mMaxCycles = pack( "L", $mMaxCycles );
	$mMaxRounds = pack( "L", $mMaxRounds );
	$mMinDistance = pack( "L", $mMinDistance );
	$mBattleType = pack( "C", $mBattleType );
	$mScoringType = pack( "C", $mScoringType );

	# apperently perl does not have a decent write function to tell how many bytes were written
	# for now the assumption is enough bytes are available
	print OutputFile $mPSpaceEnabled;
	print OutputFile $mCoreSize;
	print OutputFile $mPSpaceSize;
	print OutputFile $mMaxWarriorSize;
	print OutputFile $mMaxWarriorCount;
	print OutputFile $mMaxProcesses;
	print OutputFile $mMaxCycles;
	print OutputFile $mMaxRounds;
	print OutputFile $mMinDistance;
	print OutputFile $mBattleType;
	print OutputFile $mScoringType;

	return $true;
}

sub ReadWarriorCount
{
	if ( read( InputFile, $mWarriorCount, $SizeOfInteger ) != $SizeOfInteger ) { return $false; } 
	$mWarriorCount = unpack( "i", $mWarriorCount );
	
	return $true;
}

sub WriteWarriorCount
{
	$mWarriorCount = pack( "i", $mWarriorCount );
	print OutputFile $mWarriorCount;
	
	return $true;
}

sub ReadString
{
	if ( read( InputFile, $vStringSize, $SizeOfInteger ) != $SizeOfInteger ) { return $false; } 
	$vStringSize = unpack( "i", $vStringSize );

	if ($vStringSize > 0) 
	{
		if ( read( InputFile, $_[0], $vStringSize ) != $vStringSize ) { return $false; } 
	}
	
	return $true;
}


sub WriteString
{
	$vStringSize = length( $_[0] );
	$vStringSize = pack( "i", $vStringSize );		

	print OutputFile $vStringSize;
	print OutputFile $_[0];
	
	return $true;	
}

sub ReadWarriorInfo
{
	if ( &ReadString( $_[0] ) != $true ) { return $false };
	if ( &ReadString( $_[1] ) != $true ) { return $false };
	return $true;
}

sub WriteWarriorInfo
{
	if ( &WriteString( $_[0] ) != $true ) { return $false };
	if ( &WriteString( $_[1] ) != $true ) { return $false };
	return $true;
}

sub TestOutput
{
	$OutputFilename = "Settings.bin";

	open( OutputFile, ">", "$OutputFilename" ) or die "Can't open $OutputFilename: $!";

	binmode( OutputFile );

	# simulator settings
	$mPSpaceEnabled = $true;
	$mCoreSize = 8000;
	$mPSpaceSize = 500;
	$mMaxWarriorSize = 100;
	$mMaxWarriorCount = 10;
	$mMaxProcesses = 8000;
	$mMaxCycles = 80000;
	$mMaxRounds = 100;
	$mMinDistance = 100;
	$mBattleType = 0;		# 0 = duel, 1 = multi
	$mScoringType = 2;		# 0 = wins, 1 = wins and ties, 2 = survivor
	
	
	if ( &WriteSimulatorSettings() == $true )
	{
		print "WriteSimulatorSettings() successfull. \n";

		# example how to write 5 warrior "info"'s to the settings file
		# the DetailedSimulator.exe uses this "info" to read the warriors from the disk.

		# warriors
		$mWarriorCount = 5;

		if ( &WriteWarriorCount() == $true )
		{
			print "WriteWarriorCount() successfull. \n";

			$mWarriorName = "BombSpawnerV4";
			$mWarriorFilename = "Warriors\\BombSpawnerV4Binary.red";
			
			if ( &WriteWarriorInfo( $mWarriorName, $mWarriorFilename ) == $true )
			{
				print "WriteWarriorInfo() successfull. \n";		
			}
			
			$mWarriorName = "DivideAndConcuerV2Quicker";
			$mWarriorFilename = "Warriors\\DivideAndConcuerV2QuickerBinary.red";
			
			if ( &WriteWarriorInfo( $mWarriorName, $mWarriorFilename ) == $true )
			{
				print "WriteWarriorInfo() successfull. \n";		
			}

			$mWarriorName = "MiniDeathStarV20";
			$mWarriorFilename = "Warriors\\MiniDeathStarV20Binary.red";
			
			if ( &WriteWarriorInfo( $mWarriorName, $mWarriorFilename ) == $true )
			{
				print "WriteWarriorInfo() successfull. \n";		
			}			

			$mWarriorName = "Skybuck's Great Battleship V6";
			$mWarriorFilename = "Warriors\\Skybuck's Great Battleship V6 Binary.red";
			
			if ( &WriteWarriorInfo( $mWarriorName, $mWarriorFilename ) == $true )
			{
				print "WriteWarriorInfo() successfull. \n";		
			}			

			$mWarriorName = "TheWorstOfSkybuckV1";
			$mWarriorFilename = "Warriors\\TheWorstOfSkybuckV1Binary.red";
			
			if ( &WriteWarriorInfo( $mWarriorName, $mWarriorFilename ) == $true )
			{
				print "WriteWarriorInfo() successfull. \n";		
			}			
			
		} else
		{
			print "WriteWarriorCount() failed. \n";
		}	
		
		
		
	} else
	{
		print "WriteSimulatorSettings() failed. \n";
	}
	
	close( OutputFile );
}

sub TestInput
{
	$InputFilename = "Settings.bin";

	open( InputFile, "<", "$InputFilename" ) or die "Can't open $InputFilename: $!";

	binmode( InputFile );

	if ( &ReadSimulatorSettings() == $true )
	{
		print "ReadSimulatorSettings() successfull: \n";		
		print "mPSpaceEnabled: "; 	print $mPSpaceEnabled; print "\n";
		print "mCoreSize: ";		print $mCoreSize; print "\n";
		print "mPSpaceSize: ";		print $mPSpaceSize; print "\n";
		print "mMaxWarriorSize: ";	print $mMaxWarriorSize; print "\n";
		print "mMaxWarriorCount: ";	print $mMaxWarriorCount; print "\n";
		print "mMaxProcesses: ";	print $mMaxProcesses; print "\n";
		print "mMaxCycles: "; 		print $mMaxCycles; print "\n";
		print "mMaxRounds: ";		print $mMaxRounds; print "\n";
		print "mMinDistance: ";		print $mMinDistance; print "\n";
		print "mBattleType:	";		print $mBattleType; print "\n";
		print "mScoringType: ";		print $mScoringType; print "\n";

		if ( &ReadWarriorCount() == $true )
		{
			print "ReadWarriorCount() successfull: \n";
			print "mWarriorCount: "; print $mWarriorCount; print "\n";		
			
			$vWarriorIndex = 0;
			
			while ( ($vWarriorIndex < $mWarriorCount) && (&ReadWarriorInfo( $mWarriorName, $mWarriorFilename ) == $true) )
			{
				print "WarriorName: "; print $mWarriorName; print "\n";
				print "WarriorFilename: "; print $mWarriorFilename; print "\n";
				$vWarriorIndex = $vWarriorIndex + 1;
			}			
		} else
		{
			print "ReadWarriorCount() failed. \n";
		}
	
	} else
	{
		print "ReadSimulatorSettings() failed. \n";
	}

	close( InputFile );
}


sub Main
{
	&TestOutput();
	&TestInput();

}

&Main();
