/*
 * Created on 18.12.2004
 *
 * TODO To change the template for this generated file go to
 * Window - Preferences - Java - Code Style - Code Templates
 */
package de.farafin.snEADy.communication;


/** The Level with all its informations
 *
 * @author roland, lars
 * 
 * 
 * @version $Revision: 1.21 $
 */
public final class D_Level implements I_PlayFieldConstants
{
	/** the filename of the level */
	public String fileName = "";
	
	/** name of the arena */
	public String name = "";
	
	/** Comment to this arena */
	public String comment = "";
		
	/** the autor of the level */
	public String autor = "";
	
	/** height of the playfield */
	public int height = 0;
	
	/** width of the playfield */
	public int width = 0;

	/** the playfield of the game */
	public char[][] playField = null;

	/** the number of maximum player this level was designt for */
	public int maxPlayer = 0;
	
	/** default - constructor
	 */
	public D_Level()
	{
		super();
		fileName = "";
		name = "";
		height = 0;
		width = 0;
		playField = null;	
		maxPlayer = 0;
	}
	
	/** create - constructor
	 * @param name
	 * @param height
	 * @param width
	 * @param playField
	 * @param maxPlayer
	 */
	public D_Level(String fileName, String name, String autor, int height, int width, char[][] playField, int maxPlayer)
	{
		super();
		int i=0;
		this.fileName = fileName;
		this.name = name;
		this.autor = autor;
		this.height = height;
		this.width = width;
		this.playField = new char[playField.length][];
		for(i = 0; i<playField.length; i++) {this.playField[i] = (char[])playField[i].clone();}
		this.maxPlayer = maxPlayer;
	}
	
	/**  constructor
	 * @param name
	 * @param playField uses array-data to compute height and width
	 */
	public D_Level(String fileName, String name, String autor, char[][] playField, int maxPlayer)
	{
		super();
		int i=0;
		this.fileName = fileName;
		this.name = name;
		this.autor = autor;
		this.height = playField.length;
		this.width = playField[0].length;
		this.playField = new char[playField.length][];
		for(i = 0; i<playField.length; i++) {this.playField[i] = (char[])playField[i].clone();}
		this.maxPlayer = maxPlayer;
	}
	
	/** copy - constructor
	 * reference-copy of attrbutes: use copy() if you need a full copy
	 * @param level
	 */
	public D_Level(D_Level level)
	{
		super();
		int i=0;
		this.fileName = level.fileName;
		this.name = level.name;
		this.autor = level.autor; 
		this.height = level.height;
		this.width = level.width;
		this.playField = level.playField;
		this.maxPlayer = level. maxPlayer;
	}
	
	/** arena-based constructor
	 * @param name
	 * @param height
	 * @param width
	 * @param playField
	 * @param maxPlayer
	 */
	
	public D_Level(String name, int height, int width, char[][] playField, int maxPlayer)
	{
		super();
		this.fileName = "";
		this.name = name;
		this.autor = "";
		this.height = height;
		this.width = width;
		this.playField = playField;
		this.maxPlayer = maxPlayer;
	}
	
	
	/* (non-Javadoc)
	 * @see java.lang.Object#clone()
	 */
	public Object clone()
	{
		D_Level level = new D_Level();
		int i=0;
		level.fileName = this.fileName;
		level.name = this.name;
		level.autor = this.autor;
		level.height = this.height;
		level.width = this.width;
		level.playField = new char[this.playField.length][];
		for(i = 0; i<this.playField.length; i++) {level.playField[i] = (char[])this.playField[i].clone();}
		level.maxPlayer = this.maxPlayer;
		return level;
	}
	
	
	/* (non-Javadoc)
	 * @see java.lang.Object#toString()
	 */
	public String toString()
	{
		String result = null;
		int i;
		
		result =  "Name: " + name + "\n";
		result += "Comment: " + comment + "\n"; 
		result += "Autor: " + autor + "\n";
		result += "Size: " + height + "x" + width + "\n";
		result += "MaxPlayer: " + maxPlayer + "\n";
		result += "PlayField:\n";
		for(i=0; i<height; i++) result += String.valueOf(playField[i]) + "\n";

		return result;
	}
	
	/** tests if the coordinates are element of the playField
	 * @param y line
	 * @param x row
	 * @return true if the coordiantes are in height - and width - renge
	 */
	protected boolean isFieldOfLevel(int y, int x)
	{
		if(y < 0 || height < y || x < 0 || width < x) return false;
		return true;
	}
	/** tests if the coordinates are element of the playField
	 * @param vec coordinate as 2D-vector
	 * @return true if the coordiantes are in height - and width - renge
	 */
	protected boolean isFieldOfLevel(D_Vec2D vec){return isFieldOfLevel(vec.y, vec.x);}
	
	/**
	 * @return Returns a copy of the playField.
	 * @return char[][]
	 */
	public char[][] getPlayFieldCopy()
	{
		char[][] pField = new char[playField.length][];
		for(int i = 0; i < pField.length; i++)
		{
			pField[i] = new char[playField[i].length];
		}
		for(int i = 0; i < pField.length; i++)
		{
			for(int j = 0; j < pField[i].length; j++)
			{
				pField[i][j] = playField[i][j];
			}
		}
		
		return pField;
	}
	
	/** returns the character of the specified coordinates
	 * @param y line number
	 * @param x row number
	 * @return the charactor of the specified field and '?' if the field does not exist
	 */
	public char getCharOf(int y, int x)
	{
		if(!isFieldOfLevel(y, x)) return '?';
		return playField[y][x];
	}

	/** returns the character of the specified coordinates
	 * @param vec the vector of the field that should returned
	 * @return the charactor of the specified field
	 */
	public char getCharOf(D_Vec2D vec){return getCharOf(vec.y, vec.x);}
	
	/** 
	 * @param l lineNumber
	 * @return the line, null if line doesnt exist
	 */
	public char[] getLineCopy(int l)
	{
		char[] line = new char[height];
		if(l < 0 || l > height-1) return null;
		for(int i = 0; i < height; i++)
		{
			line[i] = this.playField[l][i];
		}
		return line;
	}
	
	/** 
	 * @param r rowNumber
	 * @return the row, null if row doesnt exist
	 */
	public char[] getRowCopy(int r)
	{
		char[] row = new char[width];
		if(r < 0 || r > width-1) return null;
		for(int i = 0; i < width; i++)
		{
			row[i] = this.playField[i][r];
		}
		return row;
	}
	
	/** @return Returns the height. */
	public int getHeight(){return height;}
	/** @return Returns the maxPlayer. */
	public int getMaxPlayer(){return maxPlayer;}
	/** @return Returns the name. */
	public String getName(){return name;}
	/** @return Returns the width. */
	public int getWidth(){return width;	}

	/**
	 * @param y line
	 * @param x row
	 * @return true if there is a goody at the coordinates
	 * 
	 * @see I_PlayFieldConstants
	 */
	public boolean isFree(int y, int x)
	{
		if(!isFieldOfLevel(y, x)) return false;
		return playField[y][x] == FREE;
	}
	/**
	 * @param vec controll this position
	 * @return true if there is a goody at <code>vec</code> position
	 * 
	 * @see I_PlayFieldConstants
	 */
	public boolean isFree(D_Vec2D vec){	return isFree(vec.y, vec.x);}

	/**
	 * @param y line
	 * @param x row
	 * @return true if there is a goody at the coordinates
	 * 
	 * @see I_PlayFieldConstants
	 */
	public boolean isWall(int y, int x)
	{
		if(!isFieldOfLevel(y, x)) return false;
		return playField[y][x] == WALL;
	}
	/** 
	 * @param vec controll this position
	 * @return true if there is a goody at <code>vec</code> position
	 * 
	 * @see I_PlayFieldConstants
	 */
	public boolean isWall(D_Vec2D vec){return isWall(vec.y, vec.x);}

	/**
	 * @param y line
	 * @param x row
	 * @return true if there is a goody at the coordinates
	 * 
	 * @see I_PlayFieldConstants
	 */
	public boolean isSnake(int y, int x)
	{
		if(!isFieldOfLevel(y, x)) return false;
		return (playField[y][x] >= PLAYER_0 && playField[y][x] <= PLAYER_9);
	}
	/**
	 * @param vec controll this position
	 * @return true if there is a goody at <code>vec</code> position
	 * 
	 * @see I_PlayFieldConstants
	 */
	public boolean isSnake(D_Vec2D vec){return isSnake(vec.y, vec.x);}
		
	/**
	 * @param y line
	 * @param x row
	 * @return true if there is a goody at the coordinates
	 * 
	 * @see I_PlayFieldConstants
	 */
	public boolean isGoody(int y, int x)
	{
		if(!isFieldOfLevel(y, x)) return false;
		return (playField[y][x] >= SPEED && playField[y][x] <= GOODY_z);
	}
	/**
	 * @param vec controll this position
	 * @return true if there is a goody at <code>vec</code> position
	 * 
	 * @see I_PlayFieldConstants
	 */
	public boolean isGoody(D_Vec2D vec){return isGoody(vec.y, vec.x);}

	/**
	 * @param y line
	 * @param x row
	 * @return true if there is a goody at the coordinates
	 * 
	 * @see I_PlayFieldConstants
	 */
	public boolean isSpecialField(int y, int x)
	{
		if(!isFieldOfLevel(y, x)) return false;
		return (playField[y][x] >= EXIT && playField[y][x] <= FIELD_Z);
	}
	/**
	 * @param vec controll this position
	 * @return true if there is a goody at <code>vec</code> position
	 * 
	 * @see I_PlayFieldConstants
	 */
	public boolean isSpecialField(D_Vec2D vec){	return isSpecialField(vec.y, vec.x);}
	
	/** copys all data from <code>level</code> to the lokal instance. there is no new Instance created if
	 * all array sizes fit to each other 
	 * @param level the origin where the date should be copyed from
	 */
	public void copyOnMe(D_Level level)
	{
		this.fileName = level.fileName;
		if(this.height != level.height || this.width != level.width)
		{
			this.playField = new char[level.height][level.width];
		}
		//level.goodyParams.copyOnThis(this.goodyParams);
		this.height = level.height;
		this.width = level.width;
		this.maxPlayer = level.maxPlayer;
		this.name = level.name;
		this.comment = level.comment;
		this.autor = level.autor;
		

		
		for(int i = 0; i < this.height; i++)
		{
			for(int j = 0; j < this.width; j++)
			{
				this.playField[i][j] = level.playField[i][j]; 
			}
		}
	}
}
