#include <psemek/ui/frame.hpp>
#include <psemek/ui/null_shape.hpp>

namespace psemek::ui
{

	void frame::set_min_size(std::optional<math::vector<float, 2>> const & size)
	{
		min_size_ = size;
		post_reshape();
	}

	void frame::set_max_size(std::optional<math::vector<float, 2>> const & size)
	{
		max_size_ = size;
		post_reshape();
	}

	void frame::set_fixed_size(math::vector<float, 2> const & size)
	{
		min_size_ = size;
		max_size_ = size;
		post_reshape();
	}

	shape const & frame::shape() const
	{
		static null_shape const fallback;
		if (child_)
			return child_->shape();
		return fallback;
	}

	void frame::reshape(math::box<float, 2> const & box)
	{
		if (child_)
			child_->reshape(box);
	}

	math::box<float, 2> frame::size_constraints() const
	{
		auto sc = element::size_constraints();
		if (child_)
			sc = child_->size_constraints();

		if (min_size_)
		{
			sc[0].min = std::max(sc[0].min, (*min_size_)[0]);
			sc[1].min = std::max(sc[1].min, (*min_size_)[1]);
		}

		if (max_size_)
		{
			sc[0].max = std::min(sc[0].max, (*max_size_)[0]);
			sc[1].max = std::min(sc[1].max, (*max_size_)[1]);
		}

		return sc;
	}

	math::interval<float> frame::width_constraints(float height) const
	{
		auto wc = element::width_constraints(height);
		if (child_)
			wc = child_->width_constraints(height);

		if (min_size_)
			wc.min = std::max(wc.min, (*min_size_)[0]);

		if (max_size_)
			wc.max = std::min(wc.max, (*max_size_)[0]);

		return wc;
	}

	math::interval<float> frame::height_constraints(float width) const
	{
		auto wc = element::height_constraints(width);
		if (child_)
			wc = child_->height_constraints(width);

		if (min_size_)
			wc.min = std::max(wc.min, (*min_size_)[1]);

		if (max_size_)
			wc.max = std::min(wc.max, (*max_size_)[1]);

		return wc;
	}

}
