#ifndef __gui__widgets__graph_h
#define __gui__widgets__graph_h

/* This class is defined as a template, so that means everything gets defined here as well :) */

#include <QWidget>
#include <QSize>
#include <QPaintEvent>
#include <QSize>
#include <QRect>
#include <QPainter>
#include <QPainterPath>
#include <QPen>
#include <unordered_map>

template <typename T>
class Graph final : public QWidget {
	public:
		Graph(QWidget* parent = nullptr) : QWidget(parent) {};
		void AddItem(T key, int val) { map[key] = val; update(); updateGeometry(); };
		void Clear() { map.clear(); update(); updateGeometry(); };

	protected:
		static constexpr int ITEM_HEIGHT = 20;
		static constexpr int TEXT_WIDTH = 30;
		inline int GetTotal() {
			int count = 0;
			for (const auto& item : map)
				count += item.second;
			return count;
		}
		QSize minimumSizeHint() const override { return QSize(100, ITEM_HEIGHT * map.size()); };
		void paintEvent(QPaintEvent* event) override {
			const QRect rect = event->rect();
			const int height_of_each = rect.height() / map.size();
			const int size = GetTotal();

			/* now we do the actual painting */
			QPainter painter(this);

			int i = 0;
			for (const auto& item : map) {
				painter.drawText(QRect(rect.x(), rect.y() + i * ITEM_HEIGHT, TEXT_WIDTH, ITEM_HEIGHT), Qt::AlignRight | Qt::AlignVCenter, QString::number(item.first));

				if (size) {
					painter.save();

					QPen pen(Qt::transparent, 0);
					painter.setPen(pen);

					QPainterPath path;
					path.addRect(rect.x()+35, rect.y() + i * ITEM_HEIGHT, (static_cast<double>(item.second)/size)*(rect.width()-35), ITEM_HEIGHT);
					painter.fillPath(path, Qt::blue);
					painter.drawPath(path);

					painter.restore();
				}
				i++;
			}
		};
		std::unordered_map<T, int> map = {};
};

#endif // __gui__widgets__graph_h