#include <psemek/ui/positioner.hpp>

namespace psemek::ui
{

	shape const & positioner::shape() const
	{
		return shape_;
	}

	void positioner::reshape(math::box<float, 2> const & box)
	{
		shape_.box = box;

		if (!child_)
			return;

		auto sc = child_->size_constraints();

		math::vector<float, 2> size;
		size[0] = sc[0].min;
		size[1] = sc[1].min;

		math::box<float, 2> cbox;
		cbox[0].min = position_[0];
		cbox[1].min = position_[1];
		cbox[0].max = cbox[0].min + size[0];
		cbox[1].max = cbox[1].min + size[1];

		switch (x_)
		{
		case x_align::left:
			break;
		case x_align::center:
			cbox[0] -= size[0] / 2.f;
			break;
		case x_align::right:
			cbox[0] -= size[0];
			break;
		}

		switch (y_)
		{
		case y_align::top:
			break;
		case y_align::center:
			cbox[1] -= size[1] / 2.f;
			break;
		case y_align::bottom:
			cbox[1] -= size[1];
			break;
		}

		if (clamp_)
		{
			cbox[0] += std::max(0.f, box[0].min - cbox[0].min);
			cbox[0] += std::min(0.f, box[0].max - cbox[0].max);
			cbox[1] += std::max(0.f, box[1].min - cbox[1].min);
			cbox[1] += std::min(0.f, box[1].max - cbox[1].max);
		}

		child_->reshape(cbox);
	}

	void positioner::set_position(math::point<float, 2> const & p, x_align x, y_align y, bool clamp)
	{
		if (p != position_ || x_ != x || y_ != y || clamp_ != clamp)
		{
			position_ = p;
			x_ = x;
			y_ = y;
			clamp_ = clamp;

			post_reshape();
		}
	}

}
