package edu.calpoly.csc480.Corral.Area;

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

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

abstract public class BaseArea
{
	public BaseArea() {
		field = makeTiles();
		view = makeView();
		
		view.setDocument(this);

		close();
		killMeans();
	}
	
	final public BaseSeer getOwner()				{return seer;}
	final public BaseAreaView getView()			{return view;}

	final public BaseMeans getMeans()			{return means;}
	final public BeamTiles getTiles()			{return field;}
	
	final public String getAgentName() {
		return means.getAgent().getName() + "";
	}
	
	public void setOwner(BaseSeer seer) {
		this.seer = seer;
	}

	public BaseMeans makeMeans(String agentName) {
		this.means = Agents.makeMeans(agentName);
		this.means.setOwner(this);

		initMeans();
		view.meansMade();
		return means;
	}
	
	public void killMeans() {
		this.means = null;
		view.meansKilled();
	}

	abstract public void initMeans();

	public boolean open() {
		return open;
	}

	public void close() {
		open = false;
		view.streamClosed();
	}

	public void read(InputStream in) throws IOException {
		char readLine[];
		short row, col;
		BaseTile tileRow[] = null;
		BufferedReader reader;
		java.util.List tileRows;
		String readLineString;

		open = true;
		
		tileRows = new LinkedList();
		reader = new BufferedReader(new InputStreamReader(in));		
		readLineString = reader.readLine();
		
		for (row = 0; readLineString != null; row++) {
			readLine = readLineString.toCharArray();
			
			tileRow = field.makeTileRow(readLine.length);
			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();
		}

		tiles = field.makeTiles(new Dimension(tileRow.length, tileRows.size()));

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

		view.streamRead();
	}

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

		if (open) {
			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");
		}
	}

	protected boolean open;

	protected BaseAreaView view;
	protected BaseSeer seer;
	
	protected BaseMeans means;
	protected BeamTiles field;
	protected BaseTile tiles[][];
	
	abstract protected BaseAreaView makeView();
	abstract protected BeamTiles makeTiles();
	
	abstract protected BaseTile toTile(char in);
}