#include <psemek/ui/spawn.hpp>
#include <psemek/ui/event_interceptor.hpp>
#include <psemek/ui/positioner.hpp>
#include <psemek/ui/screen.hpp>

namespace psemek::ui
{

	namespace
	{

		struct opaque_event_interceptor
			: event_interceptor
		{
			bool transparent() const override { return false; }
		};

	}

	bool spawn(element * root, std::shared_ptr<element> element, math::point<float, 2> const & position)
	{
		ui::screen * screen = find_last_parent_of_type<struct screen>(root);
		if (!screen)
			return false;

		auto event_interceptor = std::make_shared<opaque_event_interceptor>();
		auto positioner = std::make_shared<struct positioner>();
		positioner->set_child(element);
		event_interceptor->set_child(positioner);

		auto loop = screen->loop();

		auto close = [root = event_interceptor.get()]{
			auto p = dynamic_cast<struct screen *>(root->parent());
			if (p)
				p->remove_child(root);
		};

		event_interceptor->on_mouse_click([loop, close](ui::mouse_click const & e) -> bool {
			if (e.down && (e.button == ui::mouse_button::right || e.button == ui::mouse_button::left))
			{
				loop->post(close);
				return true;
			}

			return false;
		});

		event_interceptor->on_key_press([loop, close](key_press const & e) -> bool {
			if (e.down && e.key == SDLK_ESCAPE)
			{
				loop->post(close);
				return true;
			}

			return false;
		});

		event_interceptor->on_mouse_move([](mouse_move const &){ return true; });

		send_fake_mouse_move_event(event_interceptor.get(), true);

		positioner->set_position(position, positioner::x_align::left, positioner::y_align::top);
		screen->add_child(event_interceptor, screen::x_policy::fill, screen::y_policy::fill);
		return true;
	}

}
