/* BottomBarButton.cpp */

/* Copyright (C) 2011-2024 Michael Lugmair (Lucio Carreras)
 *
 * This file is part of sayonara player
 *
 * This program 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.

 * This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "PlaylistBottomBarButton.h"
#include "Utils/Settings/Settings.h"
#include "Gui/Utils/Style.h"
#include <QPixmap>
#include <QPainter>
#include <QPaintEvent>
#include <utility>

namespace
{
	constexpr const auto DefaultCheckedOpacity = 0.3;

	struct PixmapPoint
	{
		int offset {0};
		int dimension {0};
	};

	[[nodiscard]] int scaleIntTo80Percent(const int value)
	{
		return (value * 800) / 1000; // NOLINT(*-magic-numbers)
	}

	[[nodiscard]] PixmapPoint calcPixmapPoint(const int dimension)
	{
		const auto scaled = scaleIntTo80Percent(dimension);
		const auto offset = (dimension - scaled) / 2;
		const auto mod = (dimension - scaled) % 2;

		return {offset, scaled + mod};
	}

	[[nodiscard]] QRect calcPixmapRect(const int width, const int height)
	{
		const auto hor = calcPixmapPoint(width);
		const auto ver = calcPixmapPoint(height);

		return {hor.offset, ver.offset, hor.dimension, ver.dimension};
	}

	[[nodiscard]] QColor colorOrHighlight(const QString& colorString, const bool enabled, const QPalette& palette)
	{
		const auto color = QColor(colorString);
		return (enabled && color.isValid())
		       ? QColor {color}
		       : palette.highlight().color();
	}
}

namespace Playlist
{
	struct BottomBarButton::Private
	{
		QPair<QColor, QColor> checkedColors;
	};

	BottomBarButton::BottomBarButton(const QIcon& icon, QWidget* parent) :
		QPushButton(icon, {}, parent),
		m {Pimpl::make<Private>()}
	{
		ListenSetting(Set::PL_CheckedButtonColorStdThemeEnabled, BottomBarButton::checkedColorChanged);
		ListenSetting(Set::PL_CheckedButtonColorDarkThemeEnabled, BottomBarButton::checkedColorChanged);
		ListenSetting(Set::PL_CheckedButtonColorStdTheme, BottomBarButton::checkedColorChanged);
		ListenSetting(Set::PL_CheckedButtonColorDarkTheme, BottomBarButton::checkedColorChanged);
		ListenSetting(Set::PL_CheckedButtonOpacity, BottomBarButton::checkedOpacityChanged);
	}

	BottomBarButton::~BottomBarButton() = default;

	void BottomBarButton::paintEvent(QPaintEvent* e)
	{
		if(!isChecked())
		{
			QPushButton::paintEvent(e);
		}

		const auto rect = calcPixmapRect(width(), height());
		const auto pixmap = icon().pixmap(rect.width(), rect.height());

		auto painter = QPainter(this);
		if(isChecked())
		{
			const auto r = e->rect();
			painter.setPen(palette().window().color());
			painter.drawRect(r);

			const auto color = Style::isDark() ? m->checkedColors.second : m->checkedColors.first;
			const auto opacity = GetSetting(Set::PL_CheckedButtonOpacityEnabled)
			                     ? GetSetting(Set::PL_CheckedButtonOpacity)
			                     : DefaultCheckedOpacity;
			painter.setOpacity(opacity);
			painter.setPen(color);
			painter.setBrush(color);
			painter.drawRect(r);
			painter.fillRect(r, color);
		}

		painter.setOpacity(1.0);
		painter.drawPixmap(rect, pixmap);
	}

	void BottomBarButton::checkedOpacityChanged()
	{
		repaint();
	}

	void BottomBarButton::checkedColorChanged()
	{
		m->checkedColors = {
			colorOrHighlight(GetSetting(Set::PL_CheckedButtonColorStdTheme),
			                 GetSetting(Set::PL_CheckedButtonColorStdThemeEnabled), palette()),
			colorOrHighlight(GetSetting(Set::PL_CheckedButtonColorDarkTheme),
			                 GetSetting(Set::PL_CheckedButtonColorDarkThemeEnabled), palette()),
		};

		repaint();
	}
}
