package edu.calpoly.csc480.Entomo.Area;

import java.awt.*;
import java.io.*;
import java.util.*;

import com.bcurry.www.util.*;

import edu.calpoly.csc480.Entomo.Ant.*;
import edu.calpoly.csc480.Entomo.Event.*;
import edu.calpoly.csc480.Entomo.Seer.*;
import edu.calpoly.csc480.Entomo.Tile.*;
import edu.calpoly.csc480.Entomo.Tile.OdorTile.*;

public class Area implements MoveCallback
{
	public Area() {
		view = new AreaView();
	
		almanac = new Almanac();
		rules = new Rules();

		walls = new FastList();
		dawns = new FastList();
		hives = new FastList();
		odors = new FastList();
		foods = new FastList();

		ants = new FastList();
		dirty = new FastList();

		view.setDocument(this);

		close();
	}
	
	final public AreaView getView()			{return view;}
	final public String getName() {
		return (isOpen() ? file.getName() : "Unnamed");
	}

	final public Almanac getAlmanac()		{return almanac;}
	final public Rules getRules()				{return rules;}

	final public Tile[][] getTiles()			{return tiles;}
	final public Dimension getDimension()	{return size;}

	final public java.util.List getMeans() {return ants;}
	final public java.util.List getDirty()	{return dirty;}

	final public boolean isOpen()				{return (file != null);}

	public void setOwner(Seer seer) {
		this.seer = seer;
	}

	public void setFile(File file) throws IOException {
		this.file = file;
		read(new FileInputStream(file));
	}
	
	public void close() {
		this.file = null;
		killTiles();
		view.streamClosed();
	}

	public void read(InputStream in) throws IOException {
		killTiles();
		makeTiles(readTileRows(in));
		makeAnts();
	
		view.streamRead();
	}

	public void write(PrintWriter out) throws IOException {
		short row, col;

		if (isOpen()) {
			for (row = 0; row < tiles.length; row++) {
				for (col = 0; col < tiles[row].length; col++) {
					out.print(tiles[row][col].toChar());
				}

				out.println("");
			}
		}
		else {
			throw new NotActiveException("Area not open for writing");
		}
	}

	public void start() {
		try {read(new FileInputStream(file));}
		catch (IOException err) {err.printStackTrace();}

		almanac.antsLeft = ants.size();
		almanac.antsGone = 0;

		almanac.foodLeft = foods.size() * rules.foodVigor;
		almanac.foodGone = 0;
	}

	/*
	1: Much of this was done pretty hastily, so there may be a few errors in the
	minor stuff.  Essenetially, what is happening is first we get the ant's
	direction then we loop to cover all the possible maps. For value maps such
	as pheremone and food we use the actual value for the array. For on/off type
	maps such as hasAnt, isWall, is Hive we use 1 for true and 0 for false.
	*/
	public void next() {
		ListIterator itr;
		Means means;
		OdorTile odor;

		dirty.clear();

		// Provide ants with percepts and decay lifetimes
		itr = ants.listIterator();
		while (itr.hasNext()) {
		   means = ((Means)itr.next());
			means.life--;
			means.getAnt().perceive(null/*perceptAr*/);

			if (means.life == 0) {
				((OdorTile)tiles[means.curr.y][means.curr.x]).setMeans(null);

				itr.remove();

				dirty.add(tiles[means.curr.y][means.curr.x]);

				almanac.antsLeft--;
				almanac.antsGone++;

				if (almanac.antsLeft == 0) {
					seer.finish();
					return;
				}
			}
		}

		// Decay pheromone
		itr = odors.listIterator();
		while (itr.hasNext()) {
			odor = ((OdorTile)itr.next());
			odor.decayOdor(rules.odorDecayRate);
			dirty.add(odor);

			if (odor.getOdor() == 0) {
				itr.remove();
			}
		}

		view.update();
	}

	public void stop() {
	}

	public void actuate(Ant ant, int linkX, int linkY) {
		int destX, destY;
		Means means;
		Tile tile;
		OdorTile currTile, destTile;

		means = ant.getMeans();
		destX = means.curr.x + linkX;
		destY = means.curr.y + linkY;

		if (
		 destX >= 0 && destX < size.width &&
		 destY >= 0 && destY < size.height
		) {
			tile = tiles[destY][destX];

			if (!tile.isWall() && !tile.hasAnt()) {
				currTile = (OdorTile)tiles[means.curr.y][means.curr.x];
				destTile = (OdorTile)tile;

				currTile.setMeans(null);
				destTile.setMeans(means);

				if (currTile.getOdor() == 0) {
					odors.add(currTile);
				}

				currTile.spawnOdor(rules.odorSpawnRate);

				means.last.x = means.curr.x;
				means.last.y = means.curr.y;
				means.curr.x = destX;
				means.curr.y = destY;

				dirty.add(currTile);
				dirty.add(destTile);
			}
		}
	}

	protected static final int numLayers = 5;
	protected static final int numDirections = 10;

	protected AreaView view;
	protected Seer seer;

	protected Almanac almanac;
	protected Rules rules;

	protected File file;

	protected java.util.List walls;
	protected java.util.List dawns;
	protected java.util.List hives;
	protected java.util.List odors;
	protected java.util.List foods;

	protected Tile[][] tiles;
	protected Dimension size;

	protected java.util.List dirty;
	protected java.util.List ants;

	/*
	Assumes 1 (perceptAr)array of [5][10] with [0][n](Pheremone),
						 	[1][n](Ant location map),[2][n](Obstacle Map),
						 	[3][n](Food Map), [4][n](Hive Map)
							currX, currY Ant Agent current position
							lastX, lastY Ant Agent last position
	*/
	protected double perceptAr[][];//numLayers][numDirections];

	protected void killTiles() {
		walls.clear();
		dawns.clear();
		hives.clear();
		odors.clear();
		foods.clear();

		tiles = null;
		size = null;

		dirty.clear();
		ants.clear();
	}

	protected java.util.List readTileRows(InputStream in) throws IOException {
		char readLine[];
		int lastWidth;
		short row, col;
		Tile tileRow[] = null;
		BufferedReader reader;
		java.util.List tileRows;
		String readLineString;

		tileRows = new LinkedList();
		reader = new BufferedReader(new InputStreamReader(in));		
		readLineString = reader.readLine();
		lastWidth = 0;
		
		for (row = 0; readLineString != null; row++) {
			readLine = readLineString.toCharArray();
			
			if (lastWidth != readLine.length && lastWidth != 0) {
				throw new IOException(
				 "Malformed row at index " + row + " is of unequal length."
				);
			}

			lastWidth = readLine.length;
			tileRow = new Tile[lastWidth];
			tileRows.add(tileRow);

			for (col = 0; col < tileRow.length; col++) {
				tileRow[col] = toTile(readLine[col]);
				tileRow[col].setLocation(new Point(col, row));
			}
			
			readLineString = reader.readLine();
		}

		return tileRows;
	}

	protected void makeTiles(java.util.List tileRows) {
		size = new Dimension(
		 ((Tile[])tileRows.get(0)).length,
		 tileRows.size()
		);

		tiles = new Tile[size.height][size.width];

		for (int row = 0; row < tileRows.size(); row++) {
			tiles[row] = (Tile[])tileRows.get(row);
		}
	}

	protected void makeAnts() {
		DawnTile dawn;
		Ant ant;
		Means means;
	
		ListIterator itr = dawns.listIterator();

		for (int ndx = 0; itr.hasNext(); ndx++) {
		   dawn = ((DawnTile)itr.next());

			ant = new BlindAnt();
			ant.setMoveCallback(this);
			ants.add(means = ant.getMeans());

		   means.curr.x = dawn.getLocation().x;
		   means.curr.y = dawn.getLocation().y;

			means.last.x = means.curr.x + 1;
			means.last.y = means.curr.y + 1;

			means.life = rules.antsVigor;

			dawn.setMeans(means);
		}
	}

	protected Tile toTile(char in) {
		Tile tile;

		switch (in) {
		case '-':
		case '|':
		case 'X': tile = new WallTile(); walls.add(tile); break;
		case 'H': tile = new HiveTile(); hives.add(tile); break;
		case 'S': tile = new DawnTile(); dawns.add(tile); break;
		case ' ': tile = new OdorTile(); break;
		default:
			if (Character.isDigit(in)) {
				tile = new FoodTile(
				 Character.getNumericValue(in) * FoodTile.foodPerUnit);
				foods.add(tile);
			}
			else {
				tile = null;
			}
		}

		return tile;
	}
}

// FIX BWC	Percepts presently ignored both here and in the ants themselves.
// Calculates the perception matrix on the basis of directional vectors
/*
			int i; // Current layer under analysis
			int currX, currY, lastX, lastY;

			currX = ants.curr.x;
			currY = ants.curr.y;
			lastX = ants.last.x;
			lastY = ants.last.y;

			if (currX == lastX && currY < lastY) // 1
			{ //Heading is North
				for(i = 0; i < numLayers; i++) {
					switch(i)
					case 0:
						perceptAr[i][0] = Tile[currY-2][currX-2].getScent(); 		perceptAr[i][1] = Tile[currY-2][currX-1].getScent();
						perceptAr[i][2] = Tile[currY-2][currX].getScent(); 		perceptAr[i][3] = Tile[currY-2][currX+1].getScent();
						perceptAr[i][4] = Tile[currY-2][currX+2].getScent(); 		perceptAr[i][5] = Tile[currY-1][currX-1].getScent();
						perceptAr[i][6] = Tile[currY-1][currX].getScent(); 		perceptAr[i][7] = Tile[currY-1][currX+1].getScent();
						perceptAr[i][8] = Tile[currY][currX-1].getScent(); 		perceptAr[i][9] = Tile[currY][currX+1].getScent();
						break;
					case 1:
						perceptAr[i][0] = (Tile[currY-2][currX-2].hasAnt())?1:0; 	perceptAr[i][1] = (Tile[currY-2][currX-1].hasAnt())?1:0;
				 		perceptAr[i][2] = (Tile[currY-2][currX].hasAnt())?1:0; 		perceptAr[i][3] = (Tile[currY-2][currX+1].hasAnt())?1:0;
				 		perceptAr[i][4] = (Tile[currY-2][currX+2].hasAnt())?1:0; 	perceptAr[i][5] = (Tile[currY-1][currX-1].hasAnt())?1:0;
				 		perceptAr[i][6] = (Tile[currY-1][currX].hasAnt())?1:0; 		perceptAr[i][7] = (Tile[currY-1][currX+1].hasAnt())?1:0;
				 		perceptAr[i][8] = (Tile[currY][currX-1].hasAnt())?1:0; 		perceptAr[i][9] = (Tile[currY][currX+1].hasAnt())?1:0;
				 		break;
					case 2:
						perceptAr[i][0] = (Tile[currY-2][currX-2].isWall())?1:0; 	perceptAr[i][1] = (Tile[currY-2][currX-1].isWall())?1:0;
				 		perceptAr[i][2] = (Tile[currY-2][currX].isWall())?1:0; 		perceptAr[i][3] = (Tile[currY-2][currX+1].isWall())?1:0;
				 		perceptAr[i][4] = (Tile[currY-2][currX+2].isWall())?1:0; 	perceptAr[i][5] = (Tile[currY-1][currX-1].isWall())?1:0;
				 		perceptAr[i][6] = (Tile[currY-1][currX].isWall())?1:0; 		perceptAr[i][7] = (Tile[currY-1][currX+1].isWall())?1:0;
				 		perceptAr[i][8] = (Tile[currY][currX-1].isWall())?1:0; 		perceptAr[i][9] = (Tile[currY][currX+1].isWall())?1:0;
				 		break;
					case 3:
						perceptAr[i][0] = Tile[currY-2][currX-2].getFood(); 		perceptAr[i][1] = Tile[currY-2][currX-1].getFood();
				 		perceptAr[i][2] = Tile[currY-2][currX].getFood(); 			perceptAr[i][3] = Tile[currY-2][currX+1].getFood();
				 		perceptAr[i][4] = Tile[currY-2][currX+2].getFood();			perceptAr[i][5] = Tile[currY-1][currX-1].getFood();
				 		perceptAr[i][6] = Tile[currY-1][currX].getFood(); 			perceptAr[i][7] = Tile[currY-1][currX+1].getFood();
				 		perceptAr[i][8] = Tile[currY][currX-1].getFood(); 			perceptAr[i][9] = Tile[currY][currX+1].getFood();
				 		break;
					case 4:
						perceptAr[i][0] = (Tile[currY-2][currX-2].isHive())?1:0; 	perceptAr[i][1] = (Tile[currY-2][currX-1].isHive())?1:0;
				 		perceptAr[i][2] = (Tile[currY-2][currX].isHive())?1:0; 		perceptAr[i][3] = (Tile[currY-2][currX+1].isHive())?1:0;
				 		perceptAr[i][4] = (Tile[currY-2][currX+2].isHive())?1:0; 	perceptAr[i][5] = (Tile[currY-1][currX-1].isHive())?1:0;
				 		perceptAr[i][6] = (Tile[currY-1][currX].isHive())?1:0; 		perceptAr[i][7] = (Tile[currY-1][currX+1].isHive())?1:0;
				 		perceptAr[i][8] = (Tile[currY][currX-1].isHive())?1:0; 		perceptAr[i][9] = (Tile[currY][currX+1].isHive())?1:0;
				 		break;
					}// end switch(i)
				}//end for

			}
			else if ( currX > lastX && currY < lastY)
			{ // Heading is North East
				for(int i = 0; i <5; i++)
				{
					switch(i)
					{
						case 0:		{perceptAr[i][0] = Tile[currY-2][currX].getScent();			perceptAr[i][1] = Tile[currY-2][currX+1].getScent();
							 		perceptAr[i][2] = Tile[currY-2][currX+2].getScent();		perceptAr[i][3] = Tile[currY-1][currX+2].getScent();
							 		perceptAr[i][4] = Tile[currY][currX+2].getScent(); 			perceptAr[i][5] = Tile[currY-1][currX].getScent();
							 		perceptAr[i][6] = Tile[currY-1][currX+1].getScent(); 		perceptAr[i][7] = Tile[currY][currX+1].getScent();
							 		perceptAr[i][8] = Tile[currY-1][currX-1].getScent(); 		perceptAr[i][9] = Tile[currY+1][currX+1].getScent();}
							 		break;
						case 1: 	{perceptAr[i][0] = (Tile[currY-2][currX].hasAnt())?1:0; 	perceptAr[i][1] = (Tile[currY-2][currX+1].hasAnt())?1:0;
									 perceptAr[i][2] = (Tile[currY-2][currX+2].hasAnt())?1:0; 	perceptAr[i][3] = (Tile[currY-1][currX+2].hasAnt())?1:0;
									 perceptAr[i][4] = (Tile[currY][currX+2].hasAnt())?1:0; 	perceptAr[i][5] = (Tile[currY-1][currX].hasAnt())?1:0;
									 perceptAr[i][6] = (Tile[currY-1][currX+1].hasAnt())?1:0; 	perceptAr[i][7] = (Tile[currY][currX+1].hasAnt())?1:0;
									 perceptAr[i][8] = (Tile[currY-1][currX-1].hasAnt())?1:0; 	perceptAr[i][9] = (Tile[currY+1][currX+1].hasAnt())?1:0;}
									 break;
						case 2: 	{perceptAr[i][0] = (Tile[currY-2][currX].isWall())?1:0; 	perceptAr[i][1] = (Tile[currY-2][currX+1].isWall())?1:0;
									 perceptAr[i][2] = (Tile[currY-2][currX+2].isWall())?1:0; 	perceptAr[i][3] = (Tile[currY-1][currX+2].isWall())?1:0;
									 perceptAr[i][4] = (Tile[currY][currX+2].isWall())?1:0;		perceptAr[i][5] = (Tile[currY-1][currX].isWall())?1:0;
									 perceptAr[i][6] = (Tile[currY-1][currX+1].isWall())?1:0; 	perceptAr[i][7] = (Tile[currY][currX+1].isWall())?1:0;
									 perceptAr[i][8] = (Tile[currY-1][currX-1].isWall())?1:0; 	perceptAr[i][9] = (Tile[currY+1][currX+1].isWall())?1:0;}
									 break;
						case 3: 	{perceptAr[i][0] = Tile[currY-2][currX].getFood(); 			perceptAr[i][1] = Tile[currY-2][currX+1].getFood();
									 perceptAr[i][2] = Tile[currY-2][currX+2].getFood(); 		perceptAr[i][3] = Tile[currY-1][currX+2].getFood();
									 perceptAr[i][4] = Tile[currY][currX+2].getFood(); 			perceptAr[i][5] = Tile[currY-1][currX].getFood();
									 perceptAr[i][6] = Tile[currY-1][currX+1].getFood(); 		perceptAr[i][7] = Tile[currY][currX+1].getFood();
									 perceptAr[i][8] = Tile[currY-1][currX-1].getFood(); 		perceptAr[i][9] = Tile[currY+1][currX+1].getFood();}
									 break;
						case 4: 	{perceptAr[i][0] = (Tile[currY-2][currX].isHive())?1:0; 	perceptAr[i][1] = (Tile[currY-2][currX+1].isHive())?1:0;
									 perceptAr[i][2] = (Tile[currY-2][currX+2].isHive())?1:0; 	perceptAr[i][3] = (Tile[currY-1][currX+2].isHive())?1:0;
									 perceptAr[i][4] = (Tile[currY][currX+2].isHive())?1:0; 	perceptAr[i][5] = (Tile[currY-1][currX].isHive())?1:0;
									 perceptAr[i][6] = (Tile[currY-1][currX+1].isHive())?1:0; 	perceptAr[i][7] = (Tile[currY][currX+1].isHive())?1:0;
									 perceptAr[i][8] = (Tile[currY-1][currX-1].isHive())?1:0; 	perceptAr[i][9] = (Tile[currY+1][currX+1].isHive())?1:0;}
									 break;
					}// end switch(i)
				}//end for
			}
			else if ( currX > lastX && currY == lastY)
			{ // Heading is East
				for(int i = 0; i <5; i++)
				{
					switch(i)
					{
						case 0:		{perceptAr[i][0] = Tile[currY-2][currX+2].getScent(); 		perceptAr[i][1] = Tile[currY-1][currX+2].getScent();
									 perceptAr[i][2] = Tile[currY][currX+2].getScent(); 		perceptAr[i][3] = Tile[currY+1][currX+2].getScent();
									 perceptAr[i][4] = Tile[currY+2][currX+2].getScent();		perceptAr[i][5] = Tile[currY-1][currX+1].getScent();
									 perceptAr[i][6] = Tile[currY][currX+1].getScent(); 		perceptAr[i][7] = Tile[currY+1][currX+1}.getScent();
									 perceptAr[i][8] = Tile[currY-1][currX].getScent(); 		perceptAr[i][9] = Tile[currY+1][currX].getScent();}
									 break;
						case 1: 	{perceptAr[i][0] = (Tile[currY-2][currX+2].hasAnt())?1:0; 	perceptAr[i][1] = (Tile[currY-1][currX+2].hasAnt())?1:0;
									 perceptAr[i][2] = (Tile[currY][currX+2].hasAnt())?1:0; 	perceptAr[i][3] = (Tile[currY+1][currX+2].hasAnt())?1:0;
									 perceptAr[i][4] = (Tile[currY+2][currX+2].hasAnt())?1:0; 	perceptAr[i][5] = (Tile[currY-1][currX+1].hasAnt())?1:0;
									 perceptAr[i][6] = (Tile[currY][currX+1].hasAnt())?1:0; 	perceptAr[i][7] = (Tile[currY+1][currX+1}.hasAnt())?1:0;
									 perceptAr[i][8] = (Tile[currY-1][currX].hasAnt())?1:0; 	perceptAr[i][9] = (Tile[currY+1][currX].hasAnt())?1:0;}
									 break;
						case 2: 	{perceptAr[i][0] = (Tile[currY-2][currX+2].isWall())?1:0; 	perceptAr[i][1] = (Tile[currY-1][currX+2].isWall())?1:0;
									 perceptAr[i][2] = (Tile[currY][currX+2].isWall())?1:0; 	perceptAr[i][3] = (Tile[currY+1][currX+2].isWall())?1:0;
									 perceptAr[i][4] = (Tile[currY+2][currX+2].isWall())?1:0; 	perceptAr[i][5] = (Tile[currY-1][currX+1].isWall())?1:0;
									 perceptAr[i][6] = (Tile[currY][currX+1].isWall())?1:0; 	perceptAr[i][7] = (Tile[currY+1][currX+1].isWall())?1:0;
									 perceptAr[i][8] = (Tile[currY-1][currX].isWall())?1:0; 	perceptAr[i][9] = (Tile[currY+1][currX].isWall())?1:0;}
									 break;
						case 3: 	{perceptAr[i][0] = Tile[currY-2][currX+2].getFood(); 		perceptAr[i][1] = Tile[currY-1][currX+2].getFood();
									 perceptAr[i][2] = Tile[currY][currX+2].getFood(); 			perceptAr[i][3] = Tile[currY+1][currX+2].getFood();
									 perceptAr[i][4] = Tile[currY+2][currX+2].getFood(); 		perceptAr[i][5] = Tile[currY-1][currX+1].getFood();
									 perceptAr[i][6] = Tile[currY][currX+1].getFood(); 			perceptAr[i][7] = Tile[currY+1][currX+1].getFood();
									 perceptAr[i][8] = Tile[currY-1][currX].getFood(); 			perceptAr[i][9] = Tile[currY+1][currX].getFood();}
									 break;
						case 4: 	{perceptAr[i][0] = (Tile[currY-2][currX+2].isHive())?1:0; 	perceptAr[i][1] = (Tile[currY-1][currX+2].isHive())?1:0;
									 perceptAr[i][2] = (Tile[currY][currX+2].isHive())?1:0; 	perceptAr[i][3] = (Tile[currY+1][currX+2].isHive())?1:0;
									 perceptAr[i][4] = (Tile[currY+2][currX+2].isHive())?1:0; 	perceptAr[i][5] = (Tile[currY-1][currX+1].isHive())?1:0;
									 perceptAr[i][6] = (Tile[currY][currX+1].isHive())?1:0; 	perceptAr[i][7] = (Tile[currY+1][currX+1].isHive())?1:0;
									 perceptAr[i][8] = (Tile[currY-1][currX].isHive())?1:0; 	perceptAr[i][9] = (Tile[currY+1][currX].isHive())?1:0;}
									 break;
					}// end switch(i)
				}//end for
			}
			else if ( currX > lastX && currY > lastY)
			{ //Heading is South East
				for(int i = 0; i <5; i++)
				{
					switch(i)
					{
						case 0:		{perceptAr[i][0] = Tile[currY][currX+2].getScent(); 		perceptAr[i][1] = Tile[currY+1][currX+2].getScent();
									 perceptAr[i][2] = Tile[currY+2][currX+2].getScent(); 		perceptAr[i][3] = Tile[currY+2][currX+1].getScent();
									 perceptAr[i][4] = Tile[currY+2][currX].getScent(); 		perceptAr[i][5] = Tile[currY][currX+1].getScent();
									 perceptAr[i][6] = Tile[currY+1][currX+1].getScent(); 		perceptAr[i][7] = Tile[currY+1][currX].getScent();
									 perceptAr[i][8] = Tile[currY-1][currX+1].getScent(); 		perceptAr[i][9] = Tile[currY+1][currX-1].getScent();}
									 break;
						case 1: 	{perceptAr[i][0] = (Tile[currY][currX+2].hasAnt())?1:0; 	perceptAr[i][1] = (Tile[currY+1][currX+2].hasAnt())?1:0;
									 perceptAr[i][2] = (Tile[currY+2][currX+2].hasAnt())?1:0; 	perceptAr[i][3] = (Tile[currY+2][currX+1].hasAnt())?1:0;
									 perceptAr[i][4] = (Tile[currY+2][currX].hasAnt())?1:0; 	perceptAr[i][5] = (Tile[currY][currX+1].hasAnt())?1:0;
									 perceptAr[i][6] = (Tile[currY+1][currX+1].hasAnt())?1:0; 	perceptAr[i][7] = (Tile[currY+1][currX].hasAnt())?1:0;
									 perceptAr[i][8] = (Tile[currY-1][currX+1].hasAnt())?1:0; 	perceptAr[i][9] = (Tile[currY+1][currX-1].hasAnt())?1:0;}
									 break;
						case 2: 	{perceptAr[i][0] = (Tile[currY][currX+2].isWall())?1:0; 	perceptAr[i][1] = (Tile[currY+1][currX+2].isWall())?1:0;
									 perceptAr[i][2] = (Tile[currY+2][currX+2].isWall())?1:0;	perceptAr[i][3] = (Tile[currY+2][currX+1].isWall())?1:0;
									 perceptAr[i][4] = (Tile[currY+2][currX].isWall())?1:0; 	perceptAr[i][5] = (Tile[currY][currX+1].isWall())?1:0;
									 perceptAr[i][6] = (Tile[currY+1][currX+1].isWall())?1:0; 	perceptAr[i][7] = (Tile[currY+1][currX].isWall())?1:0;
									 perceptAr[i][8] = (Tile[currY-1][currX+1].isWall())?1:0; 	perceptAr[i][9] = (Tile[currY+1][currX-1].isWall())?1:0;}
									 break;
						case 3: 	{perceptAr[i][0] = Tile[currY][currX+2].getFood(); 			perceptAr[i][1] = Tile[currY+1][currX+2].getFood();
									 perceptAr[i][2] = Tile[currY+2][currX+2].getFood(); 		perceptAr[i][3] = Tile[currY+2][currX+1].getFood();
									 perceptAr[i][4] = Tile[currY+2][currX].getFood(); 			perceptAr[i][5] = Tile[currY][currX+1].getFood();
									 perceptAr[i][6] = Tile[currY+1][currX+1].getFood(); 		perceptAr[i][7] = Tile[currY+1][currX].getFood();
									 perceptAr[i][8] = Tile[currY-1][currX+1].getFood(); 		perceptAr[i][9] = Tile[currY+1][currX-1].getFood();}
									 break;
						case 4: 	{perceptAr[i][0] = (Tile[currY][currX+2].isHive())?1:0; 	perceptAr[i][1] = (Tile[currY+1][currX+2].isHive())?1:0;
									 perceptAr[i][2] = (Tile[currY+2][currX+2].isHive())?1:0; 	perceptAr[i][3] = (Tile[currY+2][currX+1].isHive())?1:0;
									 perceptAr[i][4] = (Tile[currY+2][currX].isHive())?1:0; 	perceptAr[i][5] = (Tile[currY][currX+1].isHive())?1:0;
									 perceptAr[i][6] = (Tile[currY+1][currX+1].isHive())?1:0; 	perceptAr[i][7] = (Tile[currY+1][currX].isHive())?1:0;
									 perceptAr[i][8] = (Tile[currY-1][currX+1].isHive())?1:0; 	perceptAr[i][9] = (Tile[currY+1][currX-1].isHive())?1:0;}
									 break;
					}// end switch(i)
				}//end for
			}
			else if ( currX == lastX && currY > lastY)
			{ //Heading is South
				for(int i = 0; i <5; i++)
				{
					switch(i)
					{
						case 0:		{perceptAr[i][0] = Tile[currY+2][currX+2].getScent(); 		perceptAr[i][1] = Tile[currY+2][currX+1].getScent();
									 perceptAr[i][2] = Tile[currY+2][currX].getScent(); 		perceptAr[i][3] = Tile[currY+2][currX-1].getScent();
									 perceptAr[i][4] = Tile[currY+2][currX-2].getScent(); 		perceptAr[i][5] = Tile[currY+1][currX+1].getScent();
									 perceptAr[i][6] = Tile[currY+1][currX].getScent(); 		perceptAr[i][7] = Tile[currY+1][currX-1].getScent();
									 perceptAr[i][8] = Tile[currY][currX+1].getScent(); 		perceptAr[i][9] = Tile[currY][currX-1].getScent();}
									 break;
						case 1: 	{perceptAr[i][0] = (Tile[currY+2][currX+2].hasAnt())?1:0; 	perceptAr[i][1] = (Tile[currY+2][currX+1].hasAnt())?1:0;
									 perceptAr[i][2] = (Tile[currY+2][currX].hasAnt())?1:0; 	perceptAr[i][3] = (Tile[currY+2][currX-1].hasAnt())?1:0;
									 perceptAr[i][4] = (Tile[currY+2][currX-2].hasAnt())?1:0; 	perceptAr[i][5] = (Tile[currY+1][currX+1].hasAnt())?1:0;
									 perceptAr[i][6] = (Tile[currY+1][currX].hasAnt())?1:0; 	perceptAr[i][7] = (Tile[currY+1][currX-1].hasAnt())?1:0;
									 perceptAr[i][8] = (Tile[currY][currX+1].hasAnt())?1:0; 	perceptAr[i][9] = (Tile[currY][currX-1].hasAnt())?1:0;}
									 break;
						case 2: 	{perceptAr[i][0] = (Tile[currY+2][currX+2].isWall())?1:0; 	perceptAr[i][1] = (Tile[currY+2][currX+1].isWall())?1:0;
									 perceptAr[i][2] = (Tile[currY+2][currX].isWall())?1:0; 	perceptAr[i][3] = (Tile[currY+2][currX-1].isWall())?1:0;
									 perceptAr[i][4] = (Tile[currY+2][currX-2].isWall())?1:0; 	perceptAr[i][5] = (Tile[currY+1][currX+1].isWall())?1:0;
									 perceptAr[i][6] = (Tile[currY+1][currX].isWall())?1:0; 	perceptAr[i][7] = (Tile[currY+1][currX-1].isWall())?1:0;
									 perceptAr[i][8] = (Tile[currY][currX+1].isWall())?1:0; 	perceptAr[i][9] = (Tile[currY][currX-1].isWall())?1:0;}
									 break;
						case 3: 	{perceptAr[i][0] = Tile[currY+2][currX+2].getFood(); 		perceptAr[i][1] = Tile[currY+2][currX+1].getFood();
									 perceptAr[i][2] = Tile[currY+2][currX].getFood(); 			perceptAr[i][3] = Tile[currY+2][currX-1].getFood();
									 perceptAr[i][4] = Tile[currY+2][currX-2].getFood(); 		perceptAr[i][5] = Tile[currY+1][currX+1].getFood();
									 perceptAr[i][6] = Tile[currY+1][currX].getFood(); 			perceptAr[i][7] = Tile[currY+1][currX-1].getFood();
									 perceptAr[i][8] = Tile[currY][currX+1].getFood(); 			perceptAr[i][9] = Tile[currY][currX-1].getFood();}
									 break;
						case 4: 	{perceptAr[i][0] = (Tile[currY+2][currX+2].isHive())?1:0; 	perceptAr[i][1] = (Tile[currY+2][currX+1].isHive())?1:0;
									 perceptAr[i][2] = (Tile[currY+2][currX].isHive())?1:0; 	perceptAr[i][3] = (Tile[currY+2][currX-1].isHive())?1:0;
									 perceptAr[i][4] = (Tile[currY+2][currX-2].isHive())?1:0; 	perceptAr[i][5] = (Tile[currY+1][currX+1].isHive())?1:0;
									 perceptAr[i][6] = (Tile[currY+1][currX].isHive())?1:0; 	perceptAr[i][7] = (Tile[currY+1][currX-1].isHive())?1:0;
									 perceptAr[i][8] = (Tile[currY][currX+1].isHive())?1:0; 	perceptAr[i][9] = (Tile[currY][currX-1].isHive())?1:0;}
									 break;
					}// end switch(i)
				}//end for
			}
			else if ( currX < lastX && currY > lastY)
			{ //Heading is South West
				for(int i = 0; i <5; i++)
				{
					switch(i)
					{
						case 0:		{perceptAr[i][0] = Tile[currY+2][currX].getScent(); 		perceptAr[i][1] = Tile[currY+2][currX-1].getScent();
									 perceptAr[i][2] = Tile[currY+2][currX-2].getScent(); 		perceptAr[i][3] = Tile[currY+1][currX-2].getScent();
									 perceptAr[i][4] = Tile[currY][currX-2].getScent(); 		perceptAr[i][5] = Tile[currY+1][currX].getScent();
									 perceptAr[i][6] = Tile[currY+1][currX-1].getScent(); 		perceptAr[i][7] = Tile[currY][currX-1].getScent();
									 perceptAr[i][8] = Tile[currY+1][currX+1].getScent();		perceptAr[i][9] = Tile[currY-1][currX-1].getScent();}
									 break;
						case 1: 	{perceptAr[i][0] = (Tile[currY+2][currX].hasAnt())?1:0; 	perceptAr[i][1] = (Tile[currY+2][currX-1].hasAnt())?1:0;
									 perceptAr[i][2] = (Tile[currY+2][currX-2].hasAnt())?1:0; 	perceptAr[i][3] = (Tile[currY+1][currX-2].hasAnt())?1:0;
									 perceptAr[i][4] = (Tile[currY][currX-2].hasAnt())?1:0; 	perceptAr[i][5] = (Tile[currY+1][currX].hasAnt())?1:0;
									 perceptAr[i][6] = (Tile[currY+1][currX-1].hasAnt())?1:0; 	perceptAr[i][7] = (Tile[currY][currX-1].hasAnt())?1:0;
									 perceptAr[i][8] = (Tile[currY+1][currX+1].hasAnt())?1:0; 	perceptAr[i][9] = (Tile[currY-1][currX-1].hasAnt())?1:0;}
									 break;
						case 2: 	{perceptAr[i][0] = (Tile[currY+2][currX].isWall())?1:0; 	perceptAr[i][1] = (Tile[currY+2][currX-1].isWall())?1:0;
									 perceptAr[i][2] = (Tile[currY+2][currX-2].isWall())?1:0; 	perceptAr[i][3] = (Tile[currY+1][currX-2].isWall())?1:0;
									 perceptAr[i][4] = (Tile[currY][currX-2].isWall())?1:0; 	perceptAr[i][5] = (Tile[currY+1][currX].isWall())?1:0;
									 perceptAr[i][6] = (Tile[currY+1][currX-1].isWall())?1:0; 	perceptAr[i][7] = (Tile[currY][currX-1].isWall())?1:0;
									 perceptAr[i][8] = (Tile[currY+1][currX+1].isWall())?1:0; 	perceptAr[i][9] = (Tile[currY-1][currX-1].isWall())?1:0;}
									 break;
						case 3: 	{perceptAr[i][0] = Tile[currY+2][currX].getFood(); 			perceptAr[i][1] = Tile[currY+2][currX-1].getFood();
									 perceptAr[i][2] = Tile[currY+2][currX-2].getFood(); 		perceptAr[i][3] = Tile[currY+1][currX-2].getFood();
									 perceptAr[i][4] = Tile[currY][currX-2].getFood(); 			perceptAr[i][5] = Tile[currY+1][currX].getFood();
									 perceptAr[i][6] = Tile[currY+1][currX-1].getFood(); 		perceptAr[i][7] = Tile[currY][currX-1].getFood();
									 perceptAr[i][8] = Tile[currY+1][currX+1].getFood(); 		perceptAr[i][9] = Tile[currY-1][currX-1].getFood();}
									 break;
						case 4: 	{perceptAr[i][0] = (Tile[currY+2][currX].isHive())?1:0; 	perceptAr[i][1] = (Tile[currY+2][currX-1].isHive())?1:0;
									 perceptAr[i][2] = (Tile[currY+2][currX-2].isHive())?1:0; 	perceptAr[i][3] = (Tile[currY+1][currX-2].isHive())?1:0;
									 perceptAr[i][4] = (Tile[currY][currX-2].isHive())?1:0; 	perceptAr[i][5] = (Tile[currY+1][currX].isHive())?1:0;
									 perceptAr[i][6] = (Tile[currY+1][currX-1].isHive())?1:0; 	perceptAr[i][7] = (Tile[currY][currX-1].isHive())?1:0;
									 perceptAr[i][8] = (Tile[currY+1][currX+1].isHive())?1:0; 	perceptAr[i][9] = (Tile[currY-1][currX-1].isHive())?1:0;}
									 break;
					}// end switch(i)
				}//end for
			}
			else if ( currX < lastX && currY == lastY)
			{ //Heading is West
				for(int i = 0; i <5; i++)
				{
					switch(i)
					{
						case 0:		{perceptAr[i][0] = Tile[currY+2][currX-2].getScent(); 		perceptAr[i][1] = Tile[currY+1][currX-2].getScent();
									 perceptAr[i][2] = Tile[currY][currX-2].getScent(); 		perceptAr[i][3] = Tile[currY-1][currX-2].getScent();
									 perceptAr[i][4] = Tile[currY-2][currX-2].getScent(); 		perceptAr[i][5] = Tile[currY+1][currX-1].getScent();
									 perceptAr[i][6] = Tile[currY][currX-1].getScent(); 		perceptAr[i][7] = Tile[currY-1][currX-1].getScent();
									 perceptAr[i][8] = Tile[currY+1][currX].getScent(); 		perceptAr[i][9] = Tile[currY-1][currX].getScent();}
									 break;
						case 1: 	{perceptAr[i][0] = (Tile[currY+2][currX-2].hasAnt())?1:0; 	perceptAr[i][1] = (Tile[currY+1][currX-2].hasAnt())?1:0;
									 perceptAr[i][2] = (Tile[currY][currX-2].hasAnt())?1:0; 	perceptAr[i][3] = (Tile[currY-1][currX-2].hasAnt())?1:0;
									 perceptAr[i][4] = (Tile[currY-2][currX-2].hasAnt())?1:0; 	perceptAr[i][5] = (Tile[currY+1][currX-1].hasAnt())?1:0;
									 perceptAr[i][6] = (Tile[currY][currX-1].hasAnt())?1:0; 	perceptAr[i][7] = (Tile[currY-1][currX-1].hasAnt())?1:0;
									 perceptAr[i][8] = (Tile[currY+1][currX].hasAnt())?1:0; 	perceptAr[i][9] = (Tile[currY-1][currX].hasAnt())?1:0;}
									 break;
						case 2: 	{perceptAr[i][0] = (Tile[currY+2][currX-2].isWall())?1:0; 	perceptAr[i][1] = (Tile[currY+1][currX-2].isWall())?1:0;
									 perceptAr[i][2] = (Tile[currY][currX-2].isWall())?1:0; 	perceptAr[i][3] = (Tile[currY-1][currX-2].isWall())?1:0;
									 perceptAr[i][4] = (Tile[currY-2][currX-2].isWall())?1:0; 	perceptAr[i][5] = (Tile[currY+1][currX-1].isWall())?1:0;
									 perceptAr[i][6] = (Tile[currY][currX-1].isWall())?1:0; 	perceptAr[i][7] = (Tile[currY-1][currX-1].isWall())?1:0;
									 perceptAr[i][8] = (Tile[currY+1][currX].isWall())?1:0; 	perceptAr[i][9] = (Tile[currY-1][currX].isWall())?1:0;}
									 break;
						case 3: 	{perceptAr[i][0] = Tile[currY+2][currX-2].getFood(); 		perceptAr[i][1] = Tile[currY+1][currX-2].getFood();
									 perceptAr[i][2] = Tile[currY][currX-2].getFood(); 			perceptAr[i][3] = Tile[currY-1][currX-2].getFood();
									 perceptAr[i][4] = Tile[currY-2][currX-2].getFood(); 		perceptAr[i][5] = Tile[currY+1][currX-1].getFood();
									 perceptAr[i][6] = Tile[currY][currX-1].getFood(); 			perceptAr[i][7] = Tile[currY-1][currX-1].getFood();
									 perceptAr[i][8] = Tile[currY+1][currX].getFood(); 			perceptAr[i][9] = Tile[currY-1][currX].getFood();}
									 break;
						case 4: 	{perceptAr[i][0] = (Tile[currY+2][currX-2].isHive())?1:0; 	perceptAr[i][1] = (Tile[currY+1][currX-2].isHive())?1:0;
									 perceptAr[i][2] = (Tile[currY][currX-2].isHive())?1:0; 	perceptAr[i][3] = (Tile[currY-1][currX-2].isHive())?1:0;
									 perceptAr[i][4] = (Tile[currY-2][currX-2].isHive())?1:0; 	perceptAr[i][5] = (Tile[currY+1][currX-1].isHive())?1:0;
									 perceptAr[i][6] = (Tile[currY][currX-1].isHive())?1:0; 	perceptAr[i][7] = (Tile[currY-1][currX-1].isHive())?1:0;
									 perceptAr[i][8] = (Tile[currY+1][currX].isHive())?1:0; 	perceptAr[i][9] = (Tile[currY-1][currX].isHive())?1:0;}
									 break;
					}// end switch(i)
				}//end for
			}
			else if ( currX < lastX && currY < lastY)
			{ //Heading is North West
				for(int i = 0; i <5; i++)
				{
					switch(i)
					{
						case 0:		{perceptAr[i][0] = Tile[currY][currX-2].getScent(); 		perceptAr[i][1] = Tile[currY-1][currX-2].getScent();
									 perceptAr[i][2] = Tile[currY-2][currX-2].getScent(); 		perceptAr[i][3] = Tile[currY-2][currX-1].getScent();
									 perceptAr[i][4] = Tile[currY-2][currX].getScent(); 		perceptAr[i][5] = Tile[currY][currX-1].getScent();
									 perceptAr[i][6] = Tile[currY-1][currX-1].getScent(); 		perceptAr[i][7] = Tile[currY-1][currX].getScent();
									 perceptAr[i][8] = Tile[currY+1][currX-1].getScent(); 		perceptAr[i][9] = Tile[currY-1][currX+1].getScent();}
									 break;
						case 1: 	{perceptAr[i][0] = (Tile[currY][currX-2].hasAnt())?1:0; 	perceptAr[i][1] = (Tile[currY-1][currX-2].hasAnt())?1:0;
									 perceptAr[i][2] = (Tile[currY-2][currX-2].hasAnt())?1:0; 	perceptAr[i][3] = (Tile[currY-2][currX-1].hasAnt())?1:0;
									 perceptAr[i][4] = (Tile[currY-2][currX].hasAnt())?1:0; 	perceptAr[i][5] = (Tile[currY][currX-1].hasAnt())?1:0;
									 perceptAr[i][6] = (Tile[currY-1][currX-1].hasAnt())?1:0; 	perceptAr[i][7] = (Tile[currY-1][currX].hasAnt())?1:0;
									 perceptAr[i][8] = (Tile[currY+1][currX-1].hasAnt())?1:0; 	perceptAr[i][9] = (Tile[currY-1][currX+1].hasAnt())?1:0;}
									 break;
						case 2: 	{perceptAr[i][0] = (Tile[currY][currX-2].isWall())?1:0; 	perceptAr[i][1] = (Tile[currY-1][currX-2].isWall())?1:0;
									 perceptAr[i][2] = (Tile[currY-2][currX-2].isWall())?1:0; 	perceptAr[i][3] = (Tile[currY-2][currX-1].isWall())?1:0;
									 perceptAr[i][4] = (Tile[currY-2][currX].isWall())?1:0; 	perceptAr[i][5] = (Tile[currY][currX-1].isWall())?1:0;
									 perceptAr[i][6] = (Tile[currY-1][currX-1].isWall())?1:0; 	perceptAr[i][7] = (Tile[currY-1][currX].isWall())?1:0;
									 perceptAr[i][8] = (Tile[currY+1][currX-1].isWall())?1:0; 	perceptAr[i][9] = (Tile[currY-1][currX+1].isWall())?1:0;}
									 break;
						case 3: 	{perceptAr[i][0] = Tile[currY][currX-2].getFood(); 			perceptAr[i][1] = Tile[currY-1][currX-2].getFood();
									 perceptAr[i][2] = Tile[currY-2][currX-2].getFood(); 		perceptAr[i][3] = Tile[currY-2][currX-1].getFood();
									 perceptAr[i][4] = Tile[currY-2][currX].getFood(); 			perceptAr[i][5] = Tile[currY][currX-1].getFood();
									 perceptAr[i][6] = Tile[currY-1][currX-1].getFood(); 		perceptAr[i][7] = Tile[currY-1][currX].getFood();
									 perceptAr[i][8] = Tile[currY+1][currX-1].getFood(); 		perceptAr[i][9] = Tile[currY-1][currX+1].getFood();}
									 break;
						case 4: 	{perceptAr[i][0] = (Tile[currY][currX-2].isHive())?1:0; 	perceptAr[i][1] = (Tile[currY-1][currX-2].isHive())?1:0;
									 perceptAr[i][2] = (Tile[currY-2][currX-2].isHive())?1:0; 	perceptAr[i][3] = (Tile[currY-2][currX-1].isHive())?1:0;
									 perceptAr[i][4] = (Tile[currY-2][currX].isHive())?1:0; 	perceptAr[i][5] = (Tile[currY][currX-1].isHive())?1:0;
									 perceptAr[i][6] = (Tile[currY-1][currX-1].isHive())?1:0; 	perceptAr[i][7] = (Tile[currY-1][currX].isHive())?1:0;
									 perceptAr[i][8] = (Tile[currY+1][currX-1].isHive())?1:0; 	perceptAr[i][9] = (Tile[currY-1][currX+1].isHive())?1:0;}
									 break;
					}// end switch(i)
				}//end for
			}//end if
*/