package edu.calpoly.csc480.Corral.Agent.Util;

import java.awt.*;
import java.util.*;
import java.util.List;

import edu.calpoly.csc480.Corral.Tile.*;

public class Chart {
	public Chart() {
		lastRow = lastCol = -1;
		rows = new ArrayList();
	}

	final public String toString() {
		int y, x;
		List row;
		String string = "Chart[";

		for (y = 0; y <= lastRow; y++) {
			row = (List)rows.get(y);

			for (x = 0; x <= lastCol; x++) {
				string = string + row.get(x) + ",\n ";
			}
		}

		return string + "]";
	}

	final public boolean haveTurnedTo(Point location) {
		return getItem(location).turnedTo;
	}

	final public boolean haveMovedTo(Point location) {
		return getItem(location).movedTo;
	}

	public void setTurnedTo(Point location) {
		getItem(location).turnedTo = true;
	}

	public void setMovedTo(Point location) {
		getItem(location).movedTo = true;
	}

	public void add(BaseTile tile) {
		int y;
		Point location;
		
		if (get(tile.getLocation()) == null) {
			location = tile.getLocation();

			expand(location);
			getItem(location).tile = tile;
		}
	}

	public BaseTile get(Point location) {
		if (location.y > lastRow || location.x > lastCol) {
			return null;
		}
		else {
			return getItem(location).tile;
		}
	}

	protected class ChartItem {
		BaseTile tile;
		boolean turnedTo, movedTo;

		public ChartItem() {
			this(null);
		}

		public ChartItem(BaseTile tile) {
			this.tile = tile;
			this.turnedTo = this.movedTo = false;
		}

		final public String toString() {
			return "ChartItem[" +
			 "turnedTo=" + turnedTo + "," +
			 "movedTo=" + movedTo + "," +
			 tile +
			 "]";
		}
	}

	protected int lastRow, lastCol;
	protected List rows;

	final protected List getRow(int y) {
		return (List)rows.get(y);
	}

	final protected ChartItem getItem(Point location) {
		return (ChartItem)getRow(location.y).get(location.x);
	}

	// FIX BWC	Optimize by growing by location.x + some growth factor.
	final protected void expand(Point location) {
		expandColumns(location.x);
		expandRows(location.y);
	}

	final protected void expandColumns(int newLastCol) {
		int x, y;
		List curRow;

		newLastCol++;
		
		if (newLastCol > lastCol) {
			for (y = 0; y <= lastRow; y++) {
				curRow = getRow(y);

				for (x = lastCol + 1; x <= newLastCol; x++) {
					curRow.add(x, new ChartItem());
				}
			}

			lastCol = newLastCol;
		}
	}

	
	final protected void expandRows(int newLastRow) {
		int x, y;
		List newRow;

		newLastRow++;

		if (newLastRow > lastRow) {
			for (y = lastRow + 1; y <= newLastRow; y++) {
				rows.add(y, newRow = new ArrayList(lastCol + 1));

				for (x = 0; x <= lastCol; x++) {
					newRow.add(x, new ChartItem());
				}
			}

			lastRow = newLastRow;
		}
	}
}