#include "matrixedit.h"

#include "ui_matrixedit.h"

#include <QBoxLayout>


MatrixEdit::MatrixEdit(QWidget * parent): QWidget(parent) {
	ui = new Ui::MatrixEdit();
	ui->setupUi(this);
#if QT_VERSION >= QT_VERSION_CHECK(5, 2, 0)
	ui->table->setSizeAdjustPolicy(QAbstractScrollArea::AdjustToContents);
#endif
	connect(ui->table, SIGNAL(cellChanged(int, int)), this, SIGNAL(changed()));
	ro = false;
}


MatrixEdit::~MatrixEdit() {
	delete ui;
}


bool MatrixEdit::isReadOnly() const {
	return ro;
}


void MatrixEdit::setReadOnly(bool yes) {
	ro = yes;
	/// TODO : readonly not implemented
}


void MatrixEdit::setVectorMode(bool yes) {
	if (yes) {
		ui->spinCols->setValue(1);
	}
	ui->labelCols->setHidden(yes);
	ui->spinCols->setHidden(yes);
	ui->buttonIdentity->setHidden(yes);
}


void MatrixEdit::clear(bool ident) {
	int cc = ui->table->columnCount();
	for (int r = 0; r < ui->table->rowCount(); ++r) {
		for (int c = 0; c < cc; ++c) {
			QTableWidgetItem * i = ui->table->item(r, c);
			if (!i) {
				i = new QTableWidgetItem();
				ui->table->setItem(r, c, i);
			}
			i->setText((ident && (r == c)) ? "1" : "0");
		}
	}
}


void MatrixEdit::changeEvent(QEvent * e) {
	QWidget::changeEvent(e);
	switch (e->type()) {
	case QEvent::LanguageChange: ui->retranslateUi(this); break;
	default: break;
	}
}


QVector<double> MatrixEdit::vector() const {
	QVector<double> ret;
	if (ui->table->columnCount() < 1) return ret;
	ret.resize(ui->table->rowCount());
	ret.fill(0.);
	for (int r = 0; r < ret.size(); ++r) {
		QTableWidgetItem * i = ui->table->item(r, 0);
		if (!i) {
			continue;
		}
		ret[r] = i->text().toDouble();
	}
	return ret;
}


QVector<QVector<double>> MatrixEdit::matrix() const {
	QVector<QVector<double>> ret;
	if (ui->table->columnCount() < 1 || ui->table->rowCount() < 1) return ret;
	int cc = ui->table->columnCount();
	ret.resize(ui->table->rowCount());
	for (int r = 0; r < ret.size(); ++r) {
		ret[r].resize(cc);
		ret[r].fill(0.);
		for (int c = 0; c < cc; ++c) {
			QTableWidgetItem * i = ui->table->item(r, c);
			if (!i) {
				continue;
			}
			ret[r][c] = i->text().toDouble();
		}
	}
	return ret;
}


void MatrixEdit::setVector(const QVector<double> & v) {
	clear();
	if (v.isEmpty()) return;
	blockSignals(true);
	ui->spinRows->setValue(v.size());
	setVectorMode(true);
	for (int r = 0; r < v.size(); ++r) {
		QTableWidgetItem * i = ui->table->item(r, 0);
		if (!i) {
			i = new QTableWidgetItem();
			ui->table->setItem(r, 0, i);
		}
		i->setText(QString::number(v[r]));
	}
	blockSignals(false);
	emit changed();
}


void MatrixEdit::setMatrix(const QVector<QVector<double>> & v) {
	clear();
	if (v.isEmpty()) return;
	if (v[0].isEmpty()) return;
	blockSignals(true);
	int cc = v[0].size();
	ui->spinRows->setValue(v.size());
	ui->spinCols->setValue(cc);
	setVectorMode(false);
	for (int r = 0; r < v.size(); ++r) {
		for (int c = 0; c < v[r].size(); ++c) {
			QTableWidgetItem * i = ui->table->item(r, c);
			if (!i) {
				i = new QTableWidgetItem();
				ui->table->setItem(r, c, i);
			}
			i->setText(QString::number(v[r][c]));
		}
	}
	blockSignals(false);
	emit changed();
}


void MatrixEdit::on_spinRows_valueChanged(int cnt) {
	ui->table->setRowCount(cnt);
	emit changed();
}


void MatrixEdit::on_spinCols_valueChanged(int cnt) {
	ui->table->setColumnCount(cnt);
	emit changed();
}


void MatrixEdit::on_buttonNull_clicked() {
	clear();
}


void MatrixEdit::on_buttonIdentity_clicked() {
	clear(true);
}
