$chunkd::XYBase = "0123456789abcdef";

function chunkSO::loadChunkTick( %this, %str, %idx )
{
	cancel( %this.loadChunkTick );
	
	%quotaUsage = 0;
	%quotaLimit = 32;
	%count = getFieldCount( %str );
	
	for ( %idx ; %idx < %count && %quotaUsage < %quotaLimit ; %idx++ )
	{
		%field = getField( %str, %idx );
		
		%px = strPos( $chunkd::XYBase, getSubStr( %field, 0, 1 ) );
		%py = strPos( $chunkd::XYBase, getSubStr( %field, 1, 1 ) );
		%pz = mFloor( getSubStr( %field, 2, 3 ) );
		%tp = getSubStr( %field, 5, strLen( %field ) );
		
		%this.setBlock( %px, %py, %pz, %tp );
		%quotaUsage++;
	}
	
	if ( %idx >= %count )
	{
		%this.initializing = false;
		return;
	}
	
	%this.loadChunkTick = %this.schedule( 128, "loadChunkTick", %str, %idx );
}

function chunkSO::loadChunk( %this )
{
	if ( %this.blockCount )
	{
		return true;
	}
	
	if ( isEventPending( %this.loadChunkTick ) )
	{
		return true;
	}
	
	if ( isEventPending( %this.generateChunkTick ) )
	{
		return true;
	}
	
	if ( !isFile( %path = %this.getFilePath() ) )
	{
		return false;
	}
	
	%fo = new fileObject();
	%fo.openForRead( %path );
	
	%str = %fo.readLine();
	
	while( !%fo.isEOF() )
	{
		%str = %str NL %fo.readLine();
	}
	
	%fo.close();
	%fo.delete();
	
	%str = strReplace( %str, "\xFA", "\t" );
	%this.loadChunkTick( %str, 0 );
}

function chunkSO::saveChunk( %this )
{
	if ( %this.unloading )
	{
		return;
	}
	
	if ( getSimTime() - %this.lastSaveTime < 30000 )
	{
		if ( isEventPending( %this.queuedSavePoint ) )
		{
			%this.queuedSavePoint = %this.schedule( ( getSimTime() - %this.lastSaveTime ) + 16, "saveChunk" );
		}
		
		return false;
	}
	else if ( isEventPending( %this.queuedSavePoint ) )
	{
		cancel( %this.queuedSavePoint );
	}
	
	if ( isEventPending( %this.loadChunkTick ) )
	{
		return false;
	}
	
	if ( isEventPending( %this.generateChunkTick ) )
	{
		return false;
	}
	
	%path = %this.getFilePath();
	%this.lastSaveTime = getSimTime();
	
	if ( !isWriteableFileName( %path ) )
	{
		return false;
	}
	
	%fo = new fileObject();
	%fo.openForWrite( %path );
	
	for ( %i = 0 ; %i < %this.blockCount ; %i++ )
	{
		%type = %this.blockType[ %i ];
		%pos = %this.blockPos[ %i ];
		%px = getWord( %pos, 0 );
		%py = getWord( %pos, 1 );
		%pz = getWord( %pos, 2 );
		%px = getSubStr( $chunkd::XYBase, %px, 1 );
		%py = getSubStr( $chunkd::XYBase, %py, 1 );
		
		if ( strLen( %pz ) == 2 )
		{
			%pz = "0" @ %pz;
		}
		else if ( strLen( %pz ) == 1 )
		{
			%pz = "00" @ %pz;
		}
		
		%string = %string @ ( strLen( %string ) ? "\xFA" : "" ) @ %px @ %py @ %pz @ %type;
	}
	
	%fo.writeLine( %string );
	%fo.close();
	%fo.delete();
	
	return true;
}