#pragma once

#include <psemek/ui/element.hpp>
#include <psemek/ui/box_shape.hpp>
#include <psemek/gfx/texture.hpp>

namespace psemek::ui
{

	struct rich_image_view
		: element
	{
		std::shared_ptr<gfx::texture_2d> image() const { return image_; }
		void set_image(std::shared_ptr<gfx::texture_2d> image);

		// Zoom is defined as (size of painted pixels)/(size of texture pixels)
		math::interval<float> zoom_range() const { return zoom_range_; }
		void set_zoom_range(math::interval<float> range);

		math::point<float, 2> center() const { return center_; }
		float zoom() const { return zoom_; }

		void set_center(math::point<float, 2> const & center);
		void set_zoom(float zoom);

		math::box<float, 2> region() const;

		bool allow_overflow() const { return allow_overflow_; }
		void set_allow_overflow(bool value);

		bool on_event(mouse_move  const & e) override;
		bool on_event(mouse_click const & e) override;
		bool on_event(mouse_wheel const & e) override;
		bool on_event(key_press   const & e) override;

		struct shape const & shape() const override { return shape_; }
		void reshape(math::box<float, 2> const & bbox) override;

		void update(float dt) override;

		void draw(painter & p) const override;

	protected:
		virtual void on_region_changed() {}

	private:
		std::shared_ptr<gfx::texture_2d> image_;
		math::interval<float> zoom_range_ = {0.f, std::numeric_limits<float>::infinity()};
		float zoom_ = 1.f;
		float zoom_tgt_ = 1.f;
		math::point<float, 2> center_{0.f, 0.f};
		bool allow_overflow_ = false;
		gfx::color_rgba color_{0, 0, 0, 0};
		box_shape shape_;

		bool mouseover_ = false;
		std::optional<math::point<int, 2>> mouse_;
		std::optional<math::point<int, 2>> drag_;

		void post_region_changed();
	};

}
