package com.daven.modelviewcontroller;
import java.awt.Graphics2D;
import java.awt.Point;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import javax.swing.JPanel;
import com.daven.java4.slimemold.Patch;
import com.daven.java4.slimemold.SlimeMoldCell;
import com.daven.modelviewcontroller.squaremapping.EightPointCompass;
import com.daven.modelviewcontroller.squaremapping.OrientationMapper;
public class ModelManager
{
private static final Random rand = new Random( System.currentTimeMillis() );
private static int patchesX;
private static int patchesY;
private static int patchPixelSize;
private static List<SimulationObject> population;
private static Map<Point, Patch> patchMatrix;
private static int simulationDelay;
private static JPanel displayArea;
private static Graphics2D graphics;
private static OrientationMapper mapper;
protected ModelManager()
{
patchMatrix = new Hashtable<Point, Patch>();
population = new ArrayList<SimulationObject>();
patchesX = SimulationView.getPatchesCountX();
patchesY = SimulationView.getPatchesCountY();
ModelManager.patchPixelSize = SimulationView.getPatchPixelSize();
ModelManager.displayArea = SimulationView.getDisplayArea();
graphics = SimulationView.getDisplayGraphics();
mapper = new OrientationMapper( patchesX, patchesY, patchPixelSize );
}
public void moveOneRound()
{
moveAllObjects();
modelChanged();
}
/**
* Allows all objects in the simulation to have a "turn"
*/
public void moveAllObjects()
{
for ( SimulationObject so : population )
{
so.move();
}
}
/**
* Updates the display showing the state of the simulation
*/
public void modelChanged()
{
//radiate pheromones
//Eclipse thinks pheromones is spelled wrong. More biologists should build IDEs. Or tech dictionaries.
Set<Point> patchKeys = patchMatrix.keySet();
for ( Point k : patchKeys )
{
Patch centerPatch = patchMatrix.get( k );
if ( centerPatch.getStinkLevel() > 1 )
{
List<Point> adjoiningLocations = mapper.getAllAdjoining( centerPatch.getPosition() );
for ( Point adjoiningLocation : adjoiningLocations )
{
patchMatrix.get( adjoiningLocation ).setStinkLevelWithoutExceeding( centerPatch.getStinkLevel() - 1 );
}
}
}
clearTheBoard();
//draw patches that stink
for ( Point k : patchKeys )
{
Patch p = patchMatrix.get( k );
if ( p.getStinkLevel() > 0 )
p.paint();
}
//draw cells
for ( SimulationObject so : population )
{
so.paint();
}
}
public boolean isOccupied( Point inquiredLocation )
{
Point simulationObjectLocation = new Point();
for ( SimulationObject so : population )
{
simulationObjectLocation = so.getPosition();
if ( simulationObjectLocation.equals( inquiredLocation ) )
{
return true;
}
}
return false;
}
public boolean isOccupied( Point p, EightPointCompass orientation, int distance )
{
return isOccupied( nextPatch( p, orientation, distance ));
}
public void releaseStink( Point location, int stinkLevel )
{
Patch p = patchMatrix.get( location );
p.setStinkLevel( stinkLevel );
}
public int getStinkLevel( Point location )
{
return patchMatrix.get( location ).getStinkLevel();
}
public Point nextPatch( Point currentPosition, EightPointCompass orientation, int distance )
{
return mapper.getLocation( currentPosition, orientation, distance );
}
private void clearTheBoard()
{
if ( population.size() > 0 )
{
graphics.setColor( displayArea.getBackground() );
graphics.fillRect( 0, 0, patchesX * patchPixelSize, patchesY * patchPixelSize );
}
}
public void runInitialSetup()
{
patchMatrix.clear();
for ( int x = 0; x < patchesX; x++ )
{
for ( int y = 0; y < patchesY; y++ )
{
Point location = new Point( x * patchPixelSize, y * patchPixelSize );
patchMatrix.put( location, new Patch( location, graphics, displayArea.getBackground(), patchPixelSize ) );
}
}
population.clear();
Point proposedPosition;
for ( int i = 0; i < SimulationView.getInitialPopulation(); i++ )
{
do
{
int x = rand.nextInt( patchesX ) * patchPixelSize;
int y = rand.nextInt( patchesY ) * patchPixelSize;
proposedPosition = new Point( x, y );
} while ( isOccupied( proposedPosition ) );
int compassOrdinal = rand.nextInt( 8 );
EightPointCompass orientation = EightPointCompass.fromOrdinal( compassOrdinal );
population.add( new SlimeMoldCell( this, proposedPosition, orientation, graphics, patchPixelSize, rand ) );
}
modelChanged();
}
public void setSimulationDelay( int delay )
{
simulationDelay = delay;
}
public int getSimulationDelay()
{
return simulationDelay;
}
}