#include "core.h"
#include "schemeprocess.h"


SHSchemeProcess::SHSchemeProcess(QObject * parent): QObject(parent) {
	view_ = 0;
	list_ = 0;
	cur_item = 0;
	icons[SHS::mcError] = QIcon(":/icons/dialog-error.png");
	icons[SHS::mcWarning] = QIcon(":/icons/dialog-warning.png");
	texts[NameEmpty] = tr("Block name is empty");
	texts[NamesEqual] = tr("Some blocks has equal names");
	texts[NamesNonC] = tr("Block name is non C-identifier");
	texts[IDsEqual] = tr("Some blocks has equal ID");
	texts[WrongBusConnect] = tr("Wrong bus connect");
	texts[DanglingBus] = tr("Dangling bus");
}


SHSchemeProcess::~SHSchemeProcess() {
}


void SHSchemeProcess::setErrorsList(QListWidget * list) {
	list_ = list;
	if (!list_) return;
	connect(list_, SIGNAL(itemSelectionChanged()), this, SLOT(itemSelected()));
}


void SHSchemeProcess::addItem(SHS::MessageClass c, SHSchemeProcess::EWType t, QGraphicsItem * i) {
	cur_item = i;
	addMessage(c, texts[t]);
}


void SHSchemeProcess::checkForErrors() {
	if (!list_) return;
	list_->blockSignals(true);
	list_->clear();
	checkScheme();
	checkPlugins();
	cur_item = 0;
	list_->blockSignals(false);
}


void SHSchemeProcess::checkScheme() {
	if (!view_) return;
	QList<BlockBusItem*> wbl = view_->wrongConnectedBuses(), busl = view_->buses();
	foreach (BlockBusItem * b, wbl) {
		busl.removeOne(b);
		addItem(SHS::mcError, SHSchemeProcess::WrongBusConnect, b);
	}
	foreach (BlockBusItem * b, busl) {
		if (b->connectedBlocks().isEmpty())
			addItem(SHS::mcWarning, SHSchemeProcess::DanglingBus, b);
	}
	QList<BlockItem*> blockl = view_->blocks();
	foreach (BlockItem * b, blockl) {
		if (b->propertyByName("name").value.toString().isEmpty())
			addItem(SHS::mcWarning, SHSchemeProcess::NameEmpty, b);
		else {
			if (!isCName(b->propertyByName("name").value.toString()))
				addItem(SHS::mcError, SHSchemeProcess::NamesNonC, b);
		}
	}
	for (int i = 0; i < blockl.size(); ++i) {
		BlockItem * b(blockl[i]);
		for (int j = i + 1; j < blockl.size(); ++j) {
			BlockItem * b2(blockl[j]);
			if (b->propertyByName("name").value.toString() == b2->propertyByName("name").value.toString()) {
				addItem(SHS::mcError, SHSchemeProcess::NamesEqual, b);
				addItem(SHS::mcError, SHSchemeProcess::NamesEqual, b2);
			}
		}
	}
}


void SHSchemeProcess::checkPlugins() {
	if (!view_) return;
	QList<BlockItem*> blockl = view_->blocks();
	foreach (BlockItem * b, blockl) {
		SHPluginBaseBlock * p = SHCORE->blockPlugin(b);
		cur_item = b;
		if (p) p->checkBlock(b);
	}
	QList<BlockBusItem*> busl = view_->buses();
	foreach (BlockBusItem * b, busl) {
		SHPluginBaseBus * p = SHCORE->busPlugin(b);
		cur_item = b;
		if (p) p->checkBus(b);
	}
}


void SHSchemeProcess::addMessage(int c, QString text) {
	if (!list_) return;
	QListWidgetItem * ni = new QListWidgetItem(icons[c], text);
	ni->setData(Qt::UserRole, qulonglong(cur_item));
	list_->addItem(ni);
}


void SHSchemeProcess::itemSelected() {
	if (!list_) return;
	QListWidgetItem * ci = list_->currentItem();
	if (ci == 0) return;
	if (ci->data(Qt::UserRole).isNull()) return;
	view_->centerOn((QGraphicsItem*)(ci->data(Qt::UserRole).toULongLong()));
}
