#pragma once

#include <psemek/util/flag_set.hpp>
#include <psemek/fonts/font.hpp>
#include <psemek/gfx/color.hpp>

#include <optional>
#include <unordered_set>

namespace psemek::ui
{

	enum class bevel_type
	{
		up,
		down,
	};

	struct element;

	enum class text_style_flag
	{
		bold,
		underline,
		strikethrough,
	};

	using text_style = util::flag_set<text_style_flag, std::uint8_t>;

	struct style
	{
		std::optional<int> scale;

		std::optional<gfx::color_rgba> bg_color;
		std::optional<gfx::color_rgba> fg_color;
		std::optional<gfx::color_rgba> highlight_color;
		std::optional<gfx::color_rgba> action_color;

		std::optional<math::vector<int, 2>> action_offset;

		std::optional<gfx::color_rgba> border_color;
		std::optional<int> border_width;

		std::optional<gfx::color_rgba> bevel_light_color;
		std::optional<gfx::color_rgba> bevel_dark_color;
		std::optional<enum bevel_type> bevel_type;
		std::optional<int> bevel_width;

		std::optional<gfx::color_rgba> axis_color;

		std::optional<int> ref_height;

		std::optional<math::vector<int, 2>> shadow_offset;
		std::optional<gfx::color_rgba> shadow_color;

		std::optional<math::vector<int, 2>> inner_margin;
		std::optional<int> outer_margin;

		std::optional<gfx::color_rgba> text_color;
		std::optional<int> text_scale;
		std::optional<ui::text_style> text_style;
		std::optional<math::vector<int, 2>> text_shadow_offset;

		std::optional<gfx::color_rgba> link_color;
		std::optional<ui::text_style> link_style;

		std::optional<gfx::color_rgba> link_hover_color;
		std::optional<ui::text_style> link_hover_style;

		std::optional<gfx::color_rgba> link_click_color;
		std::optional<ui::text_style> link_click_style;

		std::shared_ptr<fonts::font> font;
		std::shared_ptr<fonts::font> bold_font;

		mutable std::unordered_set<element *> use_as_style;
		mutable std::unordered_set<element *> use_as_own_style;

		style() = default;
		style(style &&) = default;
		style(style const &);

		style & operator = (style &&) = default;
		style & operator = (style const &) = delete;

		void on_changed();
	};

	void merge(style & dst, style const & src);

	style scale(style const & s, float factor);

	style default_style();

}
