#include <psemek/ui/spinbox.hpp>

namespace psemek::ui
{

	void spinbox::set_value(int v, bool notify)
	{
		v = math::clamp(v, value_range_);
		if (v != value_)
		{
			value_ = v;

			if (notify)
				post_value_changed();
		}
	}

	void spinbox::set_value_range(math::interval<int> i)
	{
		value_range_ = i;
		set_value(value_);
	}

	void spinbox::set_wrap(bool w)
	{
		wrap_ = w;
	}

	void spinbox::inc()
	{
		if (wrap_)
			set_value(((value_ + 1 - value_range_.min) % (value_range_.length() + 1)) + value_range_.min);
		else
			set_value(value_ + 1);
	}

	void spinbox::dec()
	{
		int const range = value_range_.length() + 1;
		if (wrap_)
			set_value(((value_ + range - 1 - value_range_.min) % range) + value_range_.min);
		else
			set_value(value_ - 1);
	}

	void spinbox::on_value_changed(on_value_changed_callback callback, bool notify)
	{
		on_value_changed_ = std::move(callback);
		if (notify)
			post_value_changed();
	}

	void spinbox::post_value_changed()
	{
		if (on_value_changed_)
			post([cb = on_value_changed_, v = value_]{ cb(v); });
	}

}
