#include "block_properties.h"
#include "SH_plugin_widgets.h"
#include "qvariantedit.h"
#include <QLabel>
#include <QMessageBox>
#include <QFileDialog>
#include <QPushButton>
#include <QToolButton>
#include <QProcess>


BlockProperties::BlockProperties(QWidget * parent): QDialog(parent), Ui::BlockProperties() {
	setupUi(this);
	connect(properties, SIGNAL(changed()), actions_, SLOT(check()));
	block = 0;
	editor = 0;
}


BlockProperties::~BlockProperties() {
}


QDialog::DialogCode BlockProperties::show(BlockItem * b) {
	block = b;
	if (!block) return QDialog::Rejected;
	buttonEditDB->setVisible(b->data(SH_Block_Source).toInt() == SHDesignerCore::sDatabase);
	editor = SHCORE->blockEditor(b);
	groupConfiguration->setVisible(editor);
	load();
	if (qApp->keyboardModifiers().testFlag(Qt::ControlModifier)) {
		SHPluginBase::PluginAction act("edit");
		QList<SHPluginBase::PluginAction> actions = actions_->actions();
		foreach (SHPluginBase::PluginAction a, actions)
			if (a.name == act.name) {act = a; break;}
		SHCORE->pluginBlockAction(block, act);
		return QDialog::Accepted;
	}
	return (QDialog::DialogCode)exec();
}


void BlockProperties::save() {
	if (!block) return;
	properties->applyProperties();
	pins->applyProperties();
	/*for (int r = 0; r < layoutDevices->rowCount(); ++r) {
		if (!layoutDevices->itemAt(r, QFormLayout::FieldRole)) continue;
		CLineEdit * le = qobject_cast<CLineEdit * >(layoutDevices->itemAt(r, QFormLayout::FieldRole)->widget());
		if (!le) continue;
		BlockItemPin * p = block->pinByText(le->property("_pin").toString());
		if (!p) continue;
		QString name = le->property("_name").toString();
		p->addDevice(name, le->text(), true);
	}*/
	actions_->check();
	PropertyStorage::Property p;
	p.name = property_configuration;
	p.value = configuration;
	p.flags = SHS::Hidden | SHS::Internal;
	block->addProperty(p);
}


void BlockProperties::load() {
	if (!block) return;
	groupProps->hide();
	groupActions->hide();
	groupPins->hide();
	int id = block->data(SH_Block_ID).toInt();
	BlockType & bt(SHCORE->getStorage(block).block_types[id]);
	labelID->setNum(bt.id);
	labelName->setText(bt.name);
	labelGroup->setText(bt.group_name);
	labelVendor->setText(bt.vendor_name);
	labelDescription->setText(bt.description);
	qDeleteAll(_widgets);
	_widgets.clear();
	
	properties->setStorage(block);
	groupProps->setVisible(!properties->isEmpty());
	
	SHPluginBaseBlock * shp = SHCORE->blockPlugin(block);
	if (shp)
		actions_->setActions(shp->addActions(block));
	else
		actions_->clear();
	groupActions->setVisible(!actions_->isEmpty());
	
	pins->setBlock(block);
	groupPins->setVisible(!pins->isEmpty());
	
	actions_->check();

	configuration = block->propertyValueByName(property_configuration).toByteArray();
}


QString BlockProperties::askFile(bool save) {
	if (!editor) return QString();
	QString filter = editor->base->fileExtension();
	if (filter.isEmpty()) filter = tr("All(*)");
	else filter = QString("%1(*.%2)").arg(editor->base->plugin->name(), filter);
	QString fn;
	if (save) fn = QFileDialog::getSaveFileName(this, save ? tr("Export") : tr("Import"), last_file, filter);
	else fn = QFileDialog::getOpenFileName(this, tr("Import"), last_file, filter);
	if (fn.isEmpty()) return QString();
	last_file = fn;
	return fn;
}


void BlockProperties::accept() {
	save();
	block = 0;
	QDialog::accept();
}


void BlockProperties::reject() {
	block = 0;
	QDialog::reject();
}


void BlockProperties::on_buttonBox_clicked(QAbstractButton * button) {
	if (buttonBox->buttonRole(button) == QDialogButtonBox::ResetRole)
		load();
	if (buttonBox->buttonRole(button) == QDialogButtonBox::ApplyRole)
		save();
}


void BlockProperties::on_buttonRecreate_clicked() {
	if (!block) return;
	/*int id = block->propertyByName(SH_Block_Property_ID).value.toInt();
	BlockItem * srcb = SHCORE->src_blocks.value(id, 0);
	if (srcb)
		block->properties() = srcb->properties();*/
	block->clearProperties();
	SHCORE->getStorage(block).loadBlock(block);
	SHCORE->getStorage(block).prepareBlock(block);
	load();
}


void BlockProperties::on_buttonEditDB_clicked() {
	if (!block) return;
	save();
	emit editDatabaseBlock(block->data(SH_Block_ID).toInt());
	accept();
}


void BlockProperties::on_buttonEdit_clicked() {
	if (!editor) return;
	editor->base->device = editor_dialog.widgetDevice;
	editor->base->reset();
	editor->base->load(configuration);
	if (block->isPropertyExists("id"))
		editor->base->setAddress(block->propertyValueByName("id").toInt());
	editor_dialog.show(editor);
	configuration = editor->base->save();
}


void BlockProperties::on_buttonExport_clicked() {
	QString fn = askFile(true);
	if (fn.isEmpty()) return;
	QFile f(fn);
	if (!f.open(QIODevice::ReadWrite)) {
		QMessageBox::critical(this, tr("Export"), tr("Can`t open file \"%1\"!").arg(fn));
		return;
	}
	f.resize(0);
	f.write(configuration);
}


void BlockProperties::on_buttonImport_clicked() {
	QString fn = askFile(false);
	if (fn.isEmpty()) return;
	QFile f(fn);
	if (!f.open(QIODevice::ReadOnly)) {
		QMessageBox::critical(this, tr("Export"), tr("Can`t open file \"%1\"!").arg(fn));
		return;
	}
	configuration = f.readAll();
}


void BlockProperties::on_properties_resetStorageRequest(PropertyStorage * s) {
	BlockItem * srcb = SHCORE->getStorage(block).srcBlock(block);
	if (srcb) *s = srcb->propertyStorage();
}


void BlockProperties::on_actions__executeAction(SHPluginBase::PluginAction action) {
	if (!block) return;
	if (action.flags.testFlag(SHPluginBase::ApplyProperties))
		save();
	SHCORE->pluginBlockAction(block, action);
	if (action.flags.testFlag(SHPluginBase::UpdateProperties))
		load();
	if (action.flags.testFlag(SHPluginBase::CloseDialog))
		done(QDialog::Accepted);
}


void BlockProperties::on_actions__checkRequest(SHPluginBase::PluginAction action, bool * ret) {
	if (!block) return;
	SHPluginBaseBlock * p = SHCORE->blockPlugin(block);
	if (!p) return;
	PropertyStorage pp;
	if (action.flags.testFlag(SHPluginBase::ApplyProperties)) {
		pp = block->propertyStorage();
		properties->applyProperties();
	}
	*ret = p->checkAction(block, action);
	if (action.flags.testFlag(SHPluginBase::ApplyProperties))
		block->properties() = pp.properties();
}
