/* 
 * JSweet - http://www.jsweet.org
 * Copyright (C) 2015 CINCHEO SAS <renaud.pawlak@cincheo.fr>
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *     http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package source.blocksgame;

import static def.dom.Globals.document;
import static jsweet.util.Lang.union;

import def.dom.CanvasRenderingContext2D;
import def.dom.HTMLImageElement;
import source.blocksgame.util.AnimatedElement;
import source.blocksgame.util.Collisions;
import source.blocksgame.util.MobileElement;
import source.blocksgame.util.Point;
import source.blocksgame.util.Vector;

public class BlockElement extends AnimatedElement {

	public static int CELL_SIZE = 44;
	public static HTMLImageElement spriteBreakableBlock = (HTMLImageElement)document.getElementById("sprite-breakable-block");
	public static HTMLImageElement spriteUnbreakableBlock = (HTMLImageElement)document.getElementById("sprite-unbreakable-block");

	public double size;
	public GameArea area;
	public int hitstoBreak;
	private Vector gravity = null;
	public boolean playerDisabled = false;
	public double x;
	public double y;
	public int cellX;
	public int cellY;

	public BlockElement(int hitsForBreaking) {
		this.hitstoBreak = hitsForBreaking;
	}

	protected void drawBreakable(CanvasRenderingContext2D ctx) {
		ctx.drawImage(spriteBreakableBlock, 0, 0, 100, 100, x, y, CELL_SIZE, CELL_SIZE);
	}

	protected void drawUnbreakable(CanvasRenderingContext2D ctx) {
		ctx.drawImage(spriteUnbreakableBlock, 0, 0, 100, 100, x, y, CELL_SIZE, CELL_SIZE);
	}

	public String toString() {
		return "BLOCK(" + this.hitstoBreak + ")";
	}

	protected void clear(CanvasRenderingContext2D ctx) {
		ctx.clearRect(this.x, this.y, this.size, this.size);
	}

	public void render(CanvasRenderingContext2D ctx) {
		if (this.isVisible()) {
			if (this.hitstoBreak == -1) {
				this.drawUnbreakable(ctx);
			} else {
				this.drawBreakable(ctx);
			}
		}
	}

	@Override
	public void renderAnimation(CanvasRenderingContext2D animationCtx, CanvasRenderingContext2D areaCtx) {
		if (this.hitstoBreak == -1) {
			this.drawUnbreakable(animationCtx);
			animationCtx.beginPath();
			animationCtx.fillStyle = union("rgba(255,255,255,0.4)");
			animationCtx.rect(this.x, this.y, this.size, this.size);
			animationCtx.fill();
		} else {
			if (this.getAnimationStep() == 1) {
				render(areaCtx);
			}
			double factor = this.getRemainingAnimationSteps() / this.getAnimationStepCount();
			animationCtx.save();
			animationCtx.translate(this.x + this.size / 2, this.y + this.size / 2);
			animationCtx.scale(factor, factor);
			animationCtx.translate(-this.x - this.size / 2, -this.y - this.size / 2);
			this.drawBreakable(animationCtx);
			animationCtx.restore();
		}
		this.nextAnimationStep();
	}

	public boolean isVisible() {
		return this.hitstoBreak != 0;
	}

	public boolean contains(Point point, double radius) {
		if (point.x + radius > this.x + this.size) {
			return false;
		}
		if (point.x - radius < this.x) {
			return false;
		}
		if (point.y + radius > this.y + this.size) {
			return false;
		}
		if (point.y - radius < this.y) {
			return false;
		}
		return true;
	}

	public boolean overlaps(Point point, double radius) {
		if (point.x + radius > this.x + this.size) {
			return false;
		}
		if (point.x - radius < this.x) {
			return false;
		}
		if (point.y + radius > this.y + this.size) {
			return false;
		}
		if (point.y - radius < this.y) {
			return false;
		}
		return true;
	}

	public boolean hit(Ball ball, Vector hitObjectDirection, Point hitPoint) {
		if (this.hitstoBreak > 0) {
			this.hitstoBreak--;
		}
		if (hitPoint == null) {
			ball.speedVector.applyBounce(hitObjectDirection);
		} else {
			MobileElement refMobile = new MobileElement(hitPoint, 10000000, 0, 0);
			Collisions.sphericCollision(refMobile, ball);
		}
		if (this.hitstoBreak == -1) {
			this.initAnimation(2);
		} else {
			this.area.blockCount--;
			this.area.remainingBlocks.innerHTML="Blocks: "+this.area.blockCount;
			if(this.area.blockCount==0) {
				this.area.end(0);
			}
			this.area.clearAll = true;
			this.initAnimation(5);
		}
		return true;
	}

	public void onBallOver(Ball ball) {
		if (this.gravity != null) {
			ball.speedVector.add(this.gravity);
		}
	}

	public Point center() {
		return new Point(this.x + this.size / 2, this.y + this.size / 2);
	}

	public void setGravity(Vector gravity) {
		this.gravity = gravity;
	}

	public void onAddedToArea() {
	}

}