package ;

import flixel.util.FlxPoint;
import flixel.FlxSprite;
import flixel.group.FlxGroup;
import flixel.util.FlxRect;

class IconGrid extends FlxGroup
{
	var sizeInCells:FlxPoint;
	var cellSize:FlxPoint;
	var gridSprite:FlxSprite;
	var pos(get, never):FlxPoint;
	function get_pos() { return new FlxPoint(gridSprite.x, gridSprite.y); }

	public function new(pos_:FlxPoint, sizeInCells_:FlxPoint)
	{
		super();

		sizeInCells = sizeInCells_;

		var cellBrush = new FlxSprite(0,0);
		cellBrush.loadGraphic("assets/images/IconCell.png");

		cellSize = new FlxPoint(cellBrush.width, cellBrush.height);

		gridSprite = new FlxSprite(pos_.x, pos_.y);
		gridSprite.makeGraphic(Std.int(cellSize.x * sizeInCells.x + 1), Std.int(cellSize.y * sizeInCells.y + 1));
		add(gridSprite);

		for (y in 0...Std.int(sizeInCells.y+1))
		{
			for (x in 0...Std.int(sizeInCells.x+1))
			{
				gridSprite.stamp(cellBrush, Std.int(x*cellSize.x), Std.int(y*cellSize.y));
			}
		}
	}

	private function getSnappedPos(sprite:FlxSprite):FlxPoint
	{
		return new FlxPoint(
			gridSprite.x + Math.round(Math.min(Math.max(sprite.x - gridSprite.x, 0), gridSprite.width-sprite.width) / cellSize.x) * cellSize.x + 1,
			gridSprite.y + Math.round(Math.min(Math.max(sprite.y - gridSprite.y, 0), gridSprite.height-sprite.height) / cellSize.y) * cellSize.y + 1
		);
	}

	private function testOverlap(s0:FlxSprite, s1:FlxSprite, ?s0Pos:FlxPoint):Bool
	{
		if (s0Pos == null) s0Pos = new FlxPoint(s0.x, s0.y);
		return !(
			s0Pos.x + s0.width < s1.x ||
			s0Pos.y + s0.height < s1.y ||
			s0Pos.x > s1.x + s1.width ||
			s0Pos.y > s1.y + s1.height
		);
	}

	public function canPlace(sprite:FlxSprite):Bool
	{
		// check bounds
		if (!testOverlap(sprite, gridSprite)) return false;
		var snappedPos = getSnappedPos(sprite);

		// check placedSprites
		for (m in this)
		{
			if (!Std.is(m, Icon)) continue;
			if (testOverlap(sprite, cast(m, FlxSprite), snappedPos))
				return false;
		}

		return true;
	}

	public function snap(sprite:FlxSprite):Bool
	{
		if (canPlace(sprite))
		{
			var snappedPos = getSnappedPos(sprite);
			sprite.x = snappedPos.x;
			sprite.y = snappedPos.y;
			return true;
		}
		else
		{
			return false;
		}
	}

	public function place(icon:Icon, ?originalPosInGrid:FlxPoint):Bool
	{
		if (snap(icon))
		{
			add(icon);
			return true;
		}
		else if (originalPosInGrid != null && testOverlap(icon, gridSprite))
		{
			// put back to original position in grid if overlapping any part
			icon.setPosition(originalPosInGrid.x, originalPosInGrid.y);
			if (snap(icon))
			{
				add(icon);
				return true;
			}
		}

		return false;
	}

	public function grabIcon(pos:FlxPoint):Icon
	{
		for (m in this)
		{
			if (!Std.is(m, Icon)) continue;
			var icon = cast(m, Icon);
			if (icon.overlapsPoint(pos))
			{
				remove(icon);
				return icon;
			}
		}
		return null;
	}
}
