package de.tu_darmstadt.gdi.others;

import java.awt.Point;

/**
 * @author Ibrahim Alyahya <ibr.alyahya@gmail.com>
 * @version 06.04.2010 12:02
 */
public class Block {
	
	/**
	 * the posison of this Block
	 */
	private Point head;
	
	/**
	 * the points which this block covers
	 */
	private Point[] points;
	
	/**
	 * the value (type) of this block
	 */
	private String value;
	
	/**
	 * some of values (types)
	 */
	private static String m="m",a="a",b="b",c="c",d="d",M="M",A="A",B="B",C="C",D="D";
	
	/**
	 * the default width and height of block in pixel
	 */
	private static int WIDTH = 100, HEIGHT = 100;
		
	/**
	 * @param x the x-coodinate of this block
	 * @param y the y-coordinate of this block
	 * @param value the type of this block
	 */
	public Block(int x, int y, String value){
		this(new Point(x,y),value);
	}
	
	/**
	 * @param head the position of this block
	 * @param value the type of this block
	 */
	public Block(Point head, String value){
		setHead(head);
		setValue(value);
		setPoints(computePoints());
	}
	
	/**
	 * to compute the points which been covered by this block
	 * @return the points as Point[]
	 */
	public Point[] computePoints(){
		return computePoints(getHead(), getValue());
	}
	
	/**
	 * this method computes the points which been covered by a block,
	 * maybe you need to change the values of WIDTH, HEIGHT and type (see above !) TODO skin changing
	 */
	public static Point[] computePoints(Point head, String value){
		Point[] points = new Point[0];
		if(head != null)
		{
			int x = (int)head.getX(), y = (int)head.getY();
			if(value == m || value == M || value == a || value == A)
				points = new Point[]{head,new Point(x+WIDTH,y)};
			else
				if(value == b || value == B)
					points = new Point[]{head,new Point(x+WIDTH,y),new Point(x+2*WIDTH,y)};
				else
					if(value == c || value == C)
						points = new Point[]{head,new Point(x,y+HEIGHT)};
					else
						if(value == d || value == D)
							points = new Point[]{head,new Point(x,y+HEIGHT),new Point(x,y+2*HEIGHT)};
		}
		return points;
	}
	
	/**
	 * to check if any of points been covered by this block
	 * @param points the points to check
	 * @return boolean which represents if any these points been covered by this block
	 */
	public boolean hasAnyOfThisPoints(Point[] points){
		if(points != null)
			for(int i = 0 ; i < points.length ; i++)
				if(hasThisPoint(points[i]))
					return true;
		return false;
	}
	
	/**
	 * to check if a point been covered by this block
	 * @param point the point to check
	 * @return boolean which represents if this point been covered by this block
	 */
	public boolean hasThisPoint(Point point){
		for(int i = 0 ; i < points.length ; i++)
			if(point.getX() == points[i].getX() && point.getY() == points[i].getY())
				return true;
		return false;
	}
	
	/**
	 * to determine the width in pixel of this block
	 * @return the width in pixel as int
	 */
	public int getHeight(){
		int height = -1;
		if(value == m || value == M || value == a || value == A || value == b || value == B)
			height = HEIGHT;
		else
			if(value == c || value == C)
				height = 2*HEIGHT;
			else
				if(value == d || value == D)
					height = 3*HEIGHT;
		return height;
	}
	
	/**
	 * to determine the height in pixel of this block
	 * @return the height in pixel as int
	 */
	public int getWidth(){
		int width = -1;
		if(value == m || value == M || value == a || value == A)
			width = 2*WIDTH;
		else
			if(value == b || value == B)
				width = 3*WIDTH;
			else
				if(value == c || value == C || value == d || value == D)
					width = WIDTH;
		return width;
	}

	/**
	 * @return the head
	 */
	public Point getHead() {
		return head;
	}

	/**
	 * @param x the x-coordinate of the head to set
	 * @param y the y-coordinate of the head to set
	 */
	public void setHead(int x, int y){
		setHead(new Point(x,y));
	}
	
	/**
	 * @param head the head to set
	 */
	public void setHead(Point head) {
		this.head = head;
		setPoints(computePoints(head, getValue()));
	}

	/**
	 * @return the value
	 */
	public String getValue() {
		return value;
	}

	/**
	 * @param value the value to set
	 */
	public void setValue(String value) {
		this.value = value;
		setPoints(computePoints(getHead(), value));
	}

	/**
	 * @return the points
	 */
	public Point[] getPoints() {
		return points;
	}

	/**
	 * @param points the points to set
	 */
	public void setPoints(Point[] points) {
		this.points = points;
	}
	
	/**
	 * to represent this.points in String
	 * @return the representaion in String
	 */
	public String pointsToString(){
		StringBuffer sb = new StringBuffer();
		sb.append("has these points = {");
		for(int i = 0 ; i < points.length ; i++){
			sb.append("(").append((int)points[i].getX()).append(",").append((int)points[i].getY()).append(")");
			if(i+1 < points.length)
				sb.append(", ");
			}
		sb.append("}");
		return sb.toString();
	}
	
	/**
	 * to represent this block in String, some information been ignored like getWidth() and getHeight() 
	 */
	public String toString(){
		return "( " + String.valueOf(getHead().getX()) + " , " + String.valueOf(getHead().getY()) + " ) = " + getValue() + ", " + pointsToString();
	}
}
