#pragma once
#include <cmath>

#include "rect.h"

class dpi_helper {
public:
	static void set_global_scale(float in_scale) {
		global_scale_ = in_scale;
	}
	static auto get_global_scale() {
		return global_scale_;
	}

	static auto physical_to_logical(float in_physical) {
		return in_physical / global_scale_;
	}
	static auto logical_to_physical(float in_logical) {
		return in_logical * global_scale_;
	}
	template<typename T>
	static auto physical_to_logical(const Eigen::Vector2<T>& in_physical) {
		return in_physical / global_scale_;
	}
	template<typename T>
	static auto logical_to_physical(const Eigen::Vector2<T>& in_logical) {
		return in_logical * global_scale_;
	}

	static auto snap_to_pixel(float in_logical) {
		auto physical_value = logical_to_physical(in_logical);
		auto snapped_value = std::round(physical_value);
		return physical_to_logical(snapped_value);
	}
	template<typename T>
	static auto snap_to_pixel(const Eigen::Vector2<T>& in_logical) {
		auto x = snap_to_pixel(in_logical.x());
		auto y = snap_to_pixel(in_logical.y());
		return Eigen::Vector2<T>(x, y);
	}

	template<typename T>
	static auto snap_rect_to_pixels(const rect_t<T>& in_rect) {
		auto top_left = snap_to_pixel(in_rect.top_left());
		auto bottom_right = snap_to_pixel(in_rect.bottom_right());
		return rect_t<T>(top_left, bottom_right - top_left);
	}
private:
	inline static float global_scale_ = 1.f;
};
