#include "flags_edit.h"
#include <QBoxLayout>
#include <QLayout>
#include <QDebug>


FlagsEdit::FlagsEdit(QWidget * parent): QWidget(parent) {
	setLayout(new QBoxLayout(QBoxLayout::TopToBottom));
	_value = 0;
}


void FlagsEdit::setEnum(const QMetaEnum & e) {
	_delete();
	for (int i = 0; i < e.keyCount(); ++i) {
		QCheckBox * cb = new QCheckBox(QString("%1 (0x%2)").arg(e.key(i)).arg(QString::number(e.value(i), 16)));
		cb->setProperty("__value", e.value(i));
		layout()->addWidget(cb);
		_checks << cb;
		connect(cb, SIGNAL(clicked(bool)), this, SLOT(setChecks()));
	}
	setChecks();
}


void FlagsEdit::setFlags(int f) {
	_value = f;
	setChecks();
}


void FlagsEdit::setToolTip(int e, const QString & tt) {
	foreach (QCheckBox * cb, _checks)
		if (cb->property("__value").toInt() == e)
			cb->setToolTip(tt);
}


int FlagsEdit::flags() const {
	int ret = 0;
	foreach (QCheckBox * cb, _checks) {
		int cbv = cb->property("__value").toInt();
		if (cb->checkState() == Qt::Checked && cbv != 0)
			ret |= cbv;
	}
	return ret;
}


void FlagsEdit::_delete() {
	qDeleteAll(_checks);
	_checks.clear();
}


void FlagsEdit::setChecks() {
	bool new_ = true;
	QCheckBox * sb = 0;
	if (sender())
		foreach (QCheckBox * cb, _checks)
			if (cb == sender()) {
				new_ = false;
				sb = cb;
				break;
			}
	if (!new_ && sb) {
		int cbv = sb->property("__value").toInt();
		if (sb->isChecked()) {
			if (cbv == 0) _value = 0;
			else _value |= cbv;
		} else _value &= ~cbv;
	}
	foreach (QCheckBox * cb, _checks) {
		cb->blockSignals(true);
		int cbv = cb->property("__value").toInt();
		int state = (_value & cbv);
		if (state == cbv) state = Qt::Checked;
		else if ((state & cbv) > 0) state = Qt::PartiallyChecked;
		else state = Qt::Unchecked;
		if (cbv == 0) state = _value == 0 ? Qt::Checked : Qt::Unchecked;
		cb->setCheckState((Qt::CheckState)state);
		cb->blockSignals(false);
	}
}
