#ifndef __gui__widgets__graph_h
#define __gui__widgets__graph_h

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

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