#include "touchslider.h"

#include "ui_touchslider.h"


TouchSlider::TouchSlider(QWidget * parent): QGroupBox(parent), ui(new Ui::TouchSlider) {
	ui->setupUi(this);
	ui->barNeg->setMinimum(0);
	prec     = 1;
	id_click = id_set = -1;
	hasZero           = true;
	m_readOnly        = false;
	m_showMinMax      = true;
	m_showIncDec      = true;
}


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


void TouchSlider::on_pbMin_clicked() {
	if (m_readOnly) return;
	ui->barNeg->setValue(ui->barNeg->maximum());
	ui->barPos->setValue(ui->barPos->minimum());
}


void TouchSlider::on_pbMax_clicked() {
	if (m_readOnly) return;
	ui->barNeg->setValue(ui->barNeg->minimum());
	ui->barPos->setValue(ui->barPos->maximum());
}


void TouchSlider::on_pbInc_clicked() {
	if (ui->barPos->value() >= 0 && ui->barNeg->value() == 0) ui->barPos->setValue(ui->barPos->value() + 1);
	if (ui->barNeg->value() > 0) ui->barNeg->setValue(ui->barNeg->value() - 1);
}


void TouchSlider::on_pbDec_clicked() {
	if (ui->barNeg->value() >= 0 && ui->barPos->value() == 0 && hasZero) ui->barNeg->setValue(ui->barNeg->value() + 1);
	if (ui->barPos->value() > 0) ui->barPos->setValue(ui->barPos->value() - 1);
}


void TouchSlider::on_pbZero_clicked() {
	ui->barNeg->setValue(ui->barNeg->minimum());
	ui->barPos->setValue(ui->barPos->minimum());
}


void TouchSlider::setValue(double val) {
	if (val < minimum()) val = minimum();
	if (val > maximum()) val = maximum();
	if (val < 0) {
		ui->barPos->setValue(ui->barPos->minimum());
		if (hasZero) ui->barNeg->setValue(qRound(-val / prec));
	} else {
		ui->barPos->setValue(qRound(val / prec));
		ui->barNeg->setValue(ui->barNeg->minimum());
	}
	updateCaption();
}


double TouchSlider::value() const {
	if (ui->barNeg->value() <= ui->barNeg->minimum())
		return (double)(ui->barPos->value()) * prec;
	else
		return -(double)(ui->barNeg->value()) * prec;
}


void TouchSlider::setMaximum(double max) {
	double val = value();
	if (max < 0) return;
	ui->barPos->setMaximum(qRound(max / prec));
	setValue(val);
	ui->pbMax->setText(QString::number(maximum()));
}


double TouchSlider::maximum() const {
	return (double)(ui->barPos->maximum()) * prec;
}


void TouchSlider::setMinimum(double min) {
	double val = value();
	if (min < 0) {
		hasZero = true;
		ui->barNeg->setMaximum(qRound(-min / prec));
		ui->barPos->setMinimum(0);
		ui->barNeg->setVisible(true);
		ui->pbZero->setVisible(true);
		setValue(val);
	} else {
		hasZero = false;
		ui->barNeg->setMaximum(0);
		ui->barNeg->setVisible(false);
		ui->pbZero->setVisible(false);
		ui->barPos->setMinimum(qRound(min / prec));
		setValue(val);
	}
	ui->pbMin->setText(QString::number(minimum()));
}


double TouchSlider::minimum() const {
	if (hasZero) return -(double)(ui->barNeg->maximum()) * prec;
	return (double)(ui->barPos->minimum()) * prec;
}


void TouchSlider::setPrecision(double precision) {
	double min = minimum();
	double max = maximum();
	double val = value();
	prec       = precision;
	setMinimum(min);
	setMaximum(max);
	setValue(val);
	ui->pbInc->setText("+" + QString::number(precision));
	ui->pbDec->setText("-" + QString::number(precision));
}


double TouchSlider::precision() const {
	return prec;
}


void TouchSlider::updateCaption() {
	setTitle(pref + " " + QString::number(value()) + " " + suff);
	emit valueChanged(value());
	emit valueChanged((int)value());
	emit valueChangedID(id_click, value());
	emit valueChangedID(id_click, (int)value());
}


void TouchSlider::on_barPos_mouseMoveEvent(QMouseEvent * e) {
	if (m_readOnly) return;
	int tx =
#if QT_VERSION_MAJOR <= 5
		e->x();
#else
		e->position().toPoint().x();
#endif
	if (tx > ui->barPos->width()) tx = ui->barPos->width();
	if (tx < 0) {
		if (hasZero) {
			int nx = tx + ui->barNeg->width() + layout()->spacing();
			if (nx < ui->barNeg->width()) {
				QMouseEvent * event = new QMouseEvent(QMouseEvent::MouseMove, QPoint(nx, 0), Qt::NoButton, Qt::NoButton, Qt::NoModifier);
				on_barNeg_mouseMoveEvent(event);
				return;
			}
		}
		tx = 0;
	}
	ui->barPos->setValue(ui->barPos->minimum() +
	                     qRound((double)(tx * (ui->barPos->maximum() - ui->barPos->minimum())) / (double)(ui->barPos->width())));
	ui->barNeg->setValue(ui->barNeg->minimum());
}


void TouchSlider::on_barNeg_mouseMoveEvent(QMouseEvent * e) {
	if (m_readOnly) return;
	int tx =
#if QT_VERSION_MAJOR <= 5
		e->x();
#else
		e->position().toPoint().x();
#endif
	if (tx < 0) tx = 0;
	if (tx > ui->barNeg->width()) {
		int nx = tx - ui->barPos->width() - layout()->spacing();
		if (nx > 0) {
			QMouseEvent * event = new QMouseEvent(QMouseEvent::MouseMove, QPoint(nx, 0), Qt::NoButton, Qt::NoButton, Qt::NoModifier);
			on_barPos_mouseMoveEvent(event);
			return;
		}
		tx = ui->barNeg->width();
	}
	ui->barNeg->setValue(ui->barNeg->maximum() - qRound((double)(tx * ui->barNeg->maximum()) / (double)(ui->barNeg->width())));
	ui->barPos->setValue(ui->barPos->minimum());
}


void TouchSlider::on_barPos_mousePressEvent(QMouseEvent * e) {
	if (m_readOnly) return;
	int tx =
#if QT_VERSION_MAJOR <= 5
		e->x();
#else
		e->position().toPoint().x();
#endif
	ui->barPos->setValue(ui->barPos->minimum() +
	                     qRound((double)(tx * (ui->barPos->maximum() - ui->barPos->minimum())) / (double)(ui->barPos->width())));
	ui->barNeg->setValue(ui->barNeg->minimum());
}


void TouchSlider::on_barNeg_mousePressEvent(QMouseEvent * e) {
	if (m_readOnly) return;
	int tx =
#if QT_VERSION_MAJOR <= 5
		e->x();
#else
		e->position().toPoint().x();
#endif
	ui->barNeg->setValue(ui->barNeg->maximum() - qRound((double)(tx * ui->barNeg->maximum()) / (double)(ui->barNeg->width())));
	ui->barPos->setValue(ui->barPos->minimum());
}


void TouchSlider::on_barNeg_valueChanged(int) {
	updateCaption();
}


void TouchSlider::on_barPos_valueChanged(int) {
	updateCaption();
}


void TouchSlider::setReadOnly(bool arg) {
	QBoxLayout * bl = qobject_cast<QBoxLayout *>(layout());
	m_readOnly      = arg;
	if (arg) {
		ui->pbDec->hide();
		ui->pbInc->hide();
		if (hasZero) ui->pbZero->hide();
		bl->setStretchFactor(ui->pbMin, 2);
		bl->setStretchFactor(ui->pbMax, 2);
	} else {
		ui->pbDec->show();
		ui->pbInc->show();
		if (hasZero) ui->pbZero->show();
		bl->setStretchFactor(ui->pbMin, 1);
		bl->setStretchFactor(ui->pbMax, 1);
	}
}


void TouchSlider::setShowMinMax(bool arg) {
	QBoxLayout * bl = qobject_cast<QBoxLayout *>(layout());
	m_showMinMax    = arg;
	if (arg) {
		ui->pbMin->show();
		ui->pbMax->show();
		bl->setStretchFactor(ui->pbInc, 2);
		bl->setStretchFactor(ui->pbDec, 2);
		bl->setStretchFactor(ui->pbZero, 2);
	} else {
		ui->pbMin->hide();
		ui->pbMax->hide();
		bl->setStretchFactor(ui->pbInc, 1);
		bl->setStretchFactor(ui->pbDec, 1);
		bl->setStretchFactor(ui->pbZero, 1);
	}
}


void TouchSlider::setShowIncDec(bool arg) {
	QBoxLayout * bl = qobject_cast<QBoxLayout *>(layout());
	m_showIncDec    = arg;
	if (arg) {
		ui->pbDec->show();
		ui->pbInc->show();
		if (hasZero) ui->pbZero->show();
		bl->setStretchFactor(ui->pbMin, 2);
		bl->setStretchFactor(ui->pbMax, 2);
	} else {
		ui->pbDec->hide();
		ui->pbInc->hide();
		if (hasZero) ui->pbZero->hide();
		bl->setStretchFactor(ui->pbMin, 1);
		bl->setStretchFactor(ui->pbMax, 1);
	}
}
