/*
	OmniaFramework - A collection of useful functionality
	Copyright (C) 2025  OmniaX-Dev

	This file is part of OmniaFramework.

	OmniaFramework is free software: you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.

	OmniaFramework is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with OmniaFramework.  If not, see <https://www.gnu.org/licenses/>.
*/

#include "CheckBox.hpp"
#include "../../render/BasicRenderer.hpp"

namespace ogfx
{
	namespace gui
	{
		namespace widgets
		{
			CheckBox& CheckBox::create(const String& text)
			{
				setText(text);
				setPadding({ 5, 5, 5, 5 });
				setTypeName("ogfx::gui::widgets::Label");
				disableDrawBox();
				disableChildren();
				enableBackground(false);
				validate();
				return *this;
			}

			void CheckBox::applyTheme(const ostd::Stylesheet& theme)
			{
				setCheckBorderColor(getThemeValue<Color>(theme, "checkbox.checkBorderColor", Colors::White));
				setCheckBoxColor(getThemeValue<Color>(theme, "checkbox.checkBoxColor", Colors::White));
				setTextColor(getThemeValue<Color>(theme, "checkbox.textColor", Colors::Black));
				setBackGroundColor(getThemeValue<Color>(theme, "checkbox.backgroundColor", Colors::Transparent));
				setFontSize(getThemeValue<i32>(theme, "checkbox.fontSize", 28));
				setBorderRadius(getThemeValue<i32>(theme, "checkbox.borderRadius", 10));
				setBorderWidth(getThemeValue<i32>(theme, "checkbox.borderWidth", 2));
				enableBorder(getThemeValue<bool>(theme, "checkbox.showBorder", false));
				setBorderColor(getThemeValue<Color>(theme, "checkbox.borderColor", Colors::White));
				enableBackground(getThemeValue<bool>(theme, "checkbox.showBackground", false));
				setPadding(getThemeValue<Rectangle>(theme, "checkbox.padding", { 5, 5, 5, 5 }));
				setMargin(getThemeValue<Rectangle>(theme, "checkbox.margin", { 0, 0, 0, 0 }));
				m_checkBorderRadius = getThemeValue<i32>(theme, "checkbox.checkBorderRadius", 5);
				m_checkBorderWidth = getThemeValue<i32>(theme, "checkbox.checkBorderWidth", 1);
			}

			void CheckBox::onDraw(ogfx::BasicRenderer2D& gfx)
			{
				if (m_textChanged)
					__update_size(gfx);
				gfx.drawRoundRect({ getGlobalContentPosition(), m_checkSize }, getCheckBorderColor(), m_checkBorderRadius, m_checkBorderWidth);
				if (isChecked())
					gfx.fillRoundRect({ getGlobalContentPosition() + 5, m_checkSize - 10 }, getCheckBoxColor(), m_checkBorderRadius / 2.0f);
				gfx.drawString(getText(), getGlobalContentPosition() + Vec2 { m_checkSize.x + m_spacing, 0 }, getTextColor(), getFontSize());
			}

			void CheckBox::onMouseReleased(const Event& event)
			{
				if (!isMouseInside())
					return;
				setChecked(!isChecked());
			}

			void CheckBox::setText(const String& text)
			{
				m_text = text;
				m_textChanged = true;
			}

			void CheckBox::setChecked(bool checked)
			{
				if (m_checked == checked)
					return;
				m_checked = checked;
				setThemeQualifier("active", m_checked);
				if (callback_onStateChanged)
					callback_onStateChanged(*this, m_checked);
			}

			void CheckBox::__update_size(ogfx::BasicRenderer2D& gfx)
			{
				auto size = gfx.getStringDimensions(getText(), getFontSize());
				m_checkSize = { cast<f32>(size.y), cast<f32>(size.y) };
				size.x += m_spacing + m_checkSize.x;
				size.x += getPadding().left();
				size.x += getPadding().right();
				size.y += getPadding().top();
				size.y += getPadding().bottom();
				setSize({ cast<f32>(size.x), cast<f32>(size.y) });
				m_textChanged = false;
			}
		}
	}
}
