// Handles Flood Algorithms.
// Worthless Bums 2012.


// Prepare floodfill algorithm
function prepareFloodFill ()
{//echo("prepareFloodFill()");
	// Create flagged status.
	$dungeonFill[$mazeDimension, $mazeDimension] = 0;
	// Loop through the maze room and flag each walkable tile in the corresponding indices in $dungeonFill.
	for (%x = 0; %x < $mazeDimension; %x++)
	{
		for (%y = 0; %y < $mazeDimension; %y++)
		{
			if (!isObject($mazeRoom[%x, %y])	||
				$mazeRoom[%x, %y].status == -3	||
				$mazeRoom[%x, %y].status == -4)
			{
				$dungeonFill[%x, %y] = 1;
			}
			else
			{
				$dungeonFill[%x, %y] = 0;
			}
		}
	}
}

// Floodfills the maze room.
function floodFill (%x, %y)
{//echo("floodFill()");
	// Bounds check.
	if (%x < 0					||
		%x > $mazeDimension	- 1	||
		%y < 0					||
		%y > $mazeDimension - 1)
	{
		return;
	}
	
	// Check if this tile is already filled in $dungeonFill.
	if ($dungeonFill[%x, %y] == 0)
	{
		return;
	}
	
	// Check tile status.
	if (!isObject($mazeRoom[%x, %y]))
	{
		return;
	}
	else if ($mazeRoom[%x, %y].status == -3	||
			 $mazeRoom[%x, %y].status == -4)
	{
		$dungeonFill[%x, %y].status = 0;
	}
	else
	{
		return;
	}
	
	// Flood fill adjacent tiles.
	// NOTE: Should we count diagonal tiles? The squad cannot traverse diagonally but has line of sight so it can be seen where there is more empty space...
	floodFill(%x + 1, %y);
	floodFill(%x - 1, %y);
	floodFill(%x,     %y + 1);
	floodFill(%x,     %y - 1);
}

// Returns true iff all rooms are connected.
function areAllRoomsFilled ()
{//echo("areAllRoomsFilled()");
	// Prepare flood fill.
	prepareFloodFill();
	// Flood fill baseed on active character's position.
	floodFill($playerSquad[$activeCharacter].xIndex, $playerSquad[$activeCharacter].yIndex);
	
	// Checks for any unfilled walkable tile in $dungeonFill.
	for (%i = 0; %i < $mazeDimension; %i++)
	{
		for (%j = 0; %j < $mazeDimension; %j++)
		{
			if ($dungeonFill[%i, %j] != 0)
			{
				
				return false;
			}
		}
	}
	
	return true;
}

// Correct stairs.
// Place stairs somewhere the squad can definitely get to!
function correctStairs ()
{//echo("correctStairs()");
return;		// Serious crashing issues!
	// Don't place stairs too close to the squad position!
	/*if (VectorDist($playerSquad[$activeCharacter].getPosition(), $mazeRoom[$stairsX, $stairsY].getPosition()) <= 30.0)
	{
		// Remove old stairs.
		$mazeRoom[$stairsX, $stairsY].safeDelete();
		$mazeRoom[$stairsX, $stairsY] = null;
		// Generate new stairs position.
		addStairsToDungeon();
		// Go again!
		correctStairs();
	}
	return;*/
	
	// Flag for stairs found status.
	$stairsFound = false;
	
	// Get the stairs indices.
	%stairsIndices = getIndicesFromTilePosition($stairsPositionX, $stairsPositionY);
	$stairsX = getWord(%stairsIndices, 0);
	$stairsY = getWord(%stairsIndices, 1);
	//echo("$stairsX SPC $stairsY =" SPC $stairsX SPC $stairsY);
	// Create flagged status.
	$dungeonFill[$mazeDimension, $mazeDimension] = 0;
	// Grid of searched tiles.
	$searchedDungeon[$mazeDimension, $mazeDimension] = 0;
	// Fill arrays.
	for (%i = 0; %i < $mazeDimension; %i++)
	{
		for (%j = 0; %j < $mazeDimension; %j++)
		{
			$dungeonFill[%i, %j] = 0;
			$searchedDungeon[%i, %j] = 0;
		}
	}
	// Flood to find stairs starting from the active squad member.
	floodFillToStairs($playerSquad[$activeCharacter].xIndex, $playerSquad[$activeCharacter].yIndex);
	
	// Check if the stairs were found.
	if (!$stairsFound)
	{//echo("stairs not found! =---------------------------------------==============-----------------------========================================");
		// Stairs not found! Need to place stairs on an accessible tile!
		
		// Remove old stairs.
		$mazeRoom[$stairsX, $stairsY].safeDelete();
		$mazeRoom[$stairsX, $stairsY] = null;
		
		// Generate new stairs position.
		do {
			$stairsX = getRandom(1, $mazeDimension - 2);
			$stairsY = getRandom(1, $mazeDimension - 2);
		} while ($dungeonFill[$stairsX, $stairsY] != 1)
		
		// Create stairs at this tile location.
		$mazeRoom[$stairsX, $stairsY] = new Sprite("Stairs")
		{
			status = 1;		// Walkable.
			SceneLayer = 25;
			position = getTilePositionFromIndices($stairsX, $stairsY);
			scenegraph = levelSceneGraph;
			imagemap = "ElevatorImageMap";//"Stairs_32x32ImageMap";
			visible = true;
			size = "4 4";
			item = null;
		};
		addObjectToScene($mazeRoom[$stairsX, $stairsY]);
		// Set new stairs position.
		$stairsPositionX = getWord($mazeRoom[$stairsX, $stairsY].position, 0);
		$stairsPositionY = getWord($mazeRoom[$stairsX, $stairsY].position, 1);
	}
}
// Floodfills the maze room until stairs are reached.
function floodFillToStairs (%xIndex, %yIndex)
{//echo("floodFillToStairs()");
//echo("x, y " SPC %xIndex SPC %yIndex);
	// Bounds check.
	if (%xIndex < 0						||
		%xIndex > $mazeDimension - 1	||
		%yIndex < 0						||
		%yIndex > $mazeDimension - 1)
	{//echo("OUT OF BOUNDS!");
		return;
	}
	
	// Check if this tile is unsearched
	if ($searchedDungeon[%xIndex, %yIndex] == 0)
	{
		// Mark this tile as searched.
		$searchedDungeon[%xIndex, %yIndex] = 1;
	}
	else
	{//echo("SEARCHED ALREADY!");
		return;
	}
	
	// Check if a squad member is on this tile.
	//if (!tileClearOfSquadMembers(%xIndex, %yIndex))
	// Check if this tile has stairs.
	if (%xIndex == $stairsX	&&
		%yIndex == $stairsY)
	{//echo("STAIRS FOUND!=================================================================================================================");
		// Mark path through fog of war!
		//echo("uncovering tile: " SPC %xIndex SPC %yIndex);
		//$fogOfWar.uncoverFogTile(%xIndex, %yIndex);
		
		// Flag stairs as found!
		$stairsFound = true;
		// Create flagged status.
		$dungeonFill[%xIndex, %yIndex] = 1;		// Track tiles the squad can reach for placing room later if we need to!
		
		return;
	}
	
	// Make sure the squad can move onto this tile!
	// NOTE: This MUST go under the above if statement because the stairs are an object in maze room!
	if (isObject($mazeRoom[%xIndex, %yIndex]))
	{//echo("$mazeRoom[%xIndex, %yIndex].status =" SPC $mazeRoom[%xIndex, %yIndex].status);
		// Make sure this object is not a portal the squad can move through!
		if ($mazeRoom[%xIndex, %yIndex].status != -3	&&		// Closed Door.
			$mazeRoom[%xIndex, %yIndex].status != -4)			// Opened Door.
		{//echo("TILE NOT DOOR!");
			
			return;
		}
	}
	else
	{
		// Create flagged status.
		$dungeonFill[%xIndex, %yIndex] = 1;		// Track tiles the squad can reach for placing room later if we need to!
	}
	
	// Create flagged status.
	//$dungeonFill[%xIndex, %yIndex] = 1;		// Track tiles the squad can reach for placing room later if we need to!
	
	if (!$stairsFound)
	{
		// Mark path through fog of war!
		//echo("uncovering tile: " SPC %xIndex SPC %yIndex);
		//$fogOfWar.uncoverFogTile(%xIndex, %yIndex);
		
		// Flood fill adjacent tiles.
		// NOTE: Should we count diagonal tiles? The squad cannot traverse diagonally but has line of sight so it can be seen where there is more empty space...
		floodFillToStairs(%xIndex + 1, %yIndex);
		floodFillToStairs(%xIndex - 1, %yIndex);
		floodFillToStairs(%xIndex,     %yIndex + 1);
		floodFillToStairs(%xIndex,     %yIndex - 1);
	}
}

// Trace a path to the stairs from the active squad member.
function traceStairs ()
{//echo("traceStairs()");
	// Flag for stairs found status.
	$stairsFound = false;
	
	// Get the stairs indices.
	//%stairsIndices = getIndicesFromTilePosition($stairsPositionX, $stairsPositionY);
	//$stairsX = getWord(%stairsIndices, 0);
	//$stairsY = getWord(%stairsIndices, 1);
	$stairsX = $stairsXIndex;
	$stairsY = $stairsYIndex;
	//echo("$stairsX SPC $stairsY =" SPC $stairsX SPC $stairsY);
	// Create flagged status.
	$dungeonFill[$mazeDimension, $mazeDimension] = 0;
	// Grid of searched tiles.
	$searchedDungeon[$mazeDimension, $mazeDimension] = 0;
	// Fill arrays.
	for (%i = 0; %i < $mazeDimension; %i++)
	{
		for (%j = 0; %j < $mazeDimension; %j++)
		{
			$dungeonFill[%i, %j] = 0;
			$searchedDungeon[%i, %j] = 0;
		}
	}
	// Flood to find stairs starting from the active squad member!
	//floodFillTraceStairs($stairsX, $stairsY);
	floodFillTraceStairs($playerSquad[$activeCharacter].xIndex, $playerSquad[$activeCharacter].yIndex);
	
	// Check if the stairs were found.
	/*if (!$stairsFound)
	{//echo("stairs not found! =---------------------------------------==============-----------------------========================================");
		
	}
	else
	{//echo("stairs found! =---------------------------------------==============-----------------------========================================");
	
	}*/
}
// Floodfills the maze room until stairs are reached.
function floodFillTraceStairs (%xIndex, %yIndex)
{//echo("floodFillTraceStairs()");
//echo("x, y " SPC %xIndex SPC %yIndex);
	// Bounds check.
	if (%xIndex < 0						||
		%xIndex > $mazeDimension - 1	||
		%yIndex < 0						||
		%yIndex > $mazeDimension - 1)
	{//echo("OUT OF BOUNDS!");
		return false;
	}
	
	// Check if this tile is unsearched
	if ($searchedDungeon[%xIndex, %yIndex] == 0)
	{
		// Mark this tile as searched.
		$searchedDungeon[%xIndex, %yIndex] = 1;
	}
	else
	{//echo("SEARCHED ALREADY!");
		return false;
	}
	
	// Check if a squad member is on this tile.
	//if (!tileClearOfSquadMembers(%xIndex, %yIndex))
	// Check if this tile has stairs.
	if (%xIndex == $stairsX	&&
		%yIndex == $stairsY)
	{//echo("STAIRS FOUND!=================================================================================================================");
		// Mark path through fog of war!
		//echo("uncovering tile: " SPC %xIndex SPC %yIndex);
		$fogOfWar.uncoverFogTile(%xIndex, %yIndex);
		
		// Flag stairs as found!
		$stairsFound = true;
		// Create flagged status.
		$dungeonFill[%xIndex, %yIndex] = 1;		// Track tiles the squad can reach for placing room later if we need to!
		
		return true;
	}
	
	// Make sure the squad can move onto this tile!
	// NOTE: This MUST go under the above if statement because the stairs are an object in maze room!
	if (isObject($mazeRoom[%xIndex, %yIndex]))
	{//echo("$mazeRoom[%xIndex, %yIndex].status =" SPC $mazeRoom[%xIndex, %yIndex].status);
		// Make sure this object is not a portal the squad can move through!
		if ($mazeRoom[%xIndex, %yIndex].status != -3	&&		// Closed Door.
			$mazeRoom[%xIndex, %yIndex].status != -4)			// Opened Door.
		{//echo("TILE NOT DOOR!");
			
			return false;
		}
	}
	else
	{
		// Create flagged status.
		$dungeonFill[%xIndex, %yIndex] = 1;		// Track tiles the squad can reach for placing room later if we need to!
	}
	
	// If stairs have not been found.
	if (!$stairsFound)
	{
		// Check return status of adjacent tiles.
		if (floodFillTraceStairs(%xIndex + 1, %yIndex))
		{
			$fogOfWar.uncoverFogTile(%xIndex, %yIndex);
			return true;
		}
		if (floodFillTraceStairs(%xIndex - 1, %yIndex))
		{
			$fogOfWar.uncoverFogTile(%xIndex, %yIndex);
			return true;
		}
		if (floodFillTraceStairs(%xIndex,     %yIndex + 1))
		{
			$fogOfWar.uncoverFogTile(%xIndex, %yIndex);
			return true;
		}
		if (floodFillTraceStairs(%xIndex,     %yIndex - 1))
		{
			$fogOfWar.uncoverFogTile(%xIndex, %yIndex);
			return true;
		}
	}
}