#ifndef COMBINED_SLIDER_H
#define COMBINED_SLIDER_H

#include <QtGui>
#include "ui_combinedSlider.h"
#include <cassert>
#include <iostream>
#include <sstream>
#include <qstringbuilder.h>

class CombinedSlider : public QWidget {
Q_OBJECT
private:
	Ui::CombinedSlider ui_;
	bool isInside_;
	bool canEmit_;

	int min_;
	int max_;
	int current_;
	QString activeSlaveStyle;
	QString deactiveSlaveStyle;
signals:
	void valueChanged(int newValue);
public slots:
	void sliderValueChangedSlot(int newValue) {
		ui_.currentEdit->setText(QString::number(newValue));
		ui_.slaveSlider->setValue(newValue);
		ui_.dominantSlider->showCurrent(false);

		emit valueChanged(newValue);
	}

	void lineEditValueChangedSlot(const QString & newText) {	
		if (!newText.isEmpty()) {
			bool isParsed = false;

			int newValue = newText.toInt(&isParsed);

			if (newValue < min_) {
				setValue(min_);
				return;
			}
			else if (newValue > max_) {
				setValue(max_);
				return;
			}

			ui_.dominantSlider->setValue(newValue);
			ui_.slaveSlider->setValue(newValue);
			   
			current_ = newValue;

			emit valueChanged(newValue);
		}
	}

	void lineEditLostFocusSlot() {
		if (ui_.currentEdit->text().isEmpty() || current_ < min_) {
			setValue(min_);
		}
	}

	virtual void setGeometry(const QRect & rect) {
		QWidget::setGeometry(rect);

		ui_.dominantSlider->resize(rect.width(), ui_.dominantSlider->height());
		ui_.slaveSlider->resize(rect.width(), ui_.slaveSlider->height());
		ui_.currentEdit->resize(rect.width(), ui_.currentEdit->height());
	}

private:
	void setStyleStrings() {

		std::stringstream s;

		s << "#slaveSlider::groove:horizontal:disabled {";
		s << "border-top: 0;";
		s << "background: white;";
		s << "height: 16px;";
		s << "}";

		s << "#slaveSlider::sub-page:horizontal:disabled {";
		s << "background:qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0  #66e, stop:1 #bbf);";
		s << "border: 1px solid #777;";
		s << "height: 10px;";
		s << "border-top: 0;";
		s << "}";

		s << "#slaveSlider::add-page:horizontal:disabled {";
		s << "background: #fff;";
		s << "border: 1px solid #777;";
		s << "height: 10px;";
		s << "border-top: 0;";
		s << "}";

		s << "#slaveSlider::handle:horizontal:disabled {";
		s << "background: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 #ccc, stop:1 #aaa);";
		s << "border: 1px solid #777;";
		s << "border-top: 0;";
		s << "margin-bottom: -1px;";
		s << "width: 13px;";
		s << "}";

		activeSlaveStyle = QString::fromUtf8(s.str().c_str());

		std::stringstream c;

		c << "#slaveSlider::groove:horizontal:disabled {";
		c << "border-top: 0;";
		c << "background: white;";
		c << "height: 16px;";
		c << "}";

		c << "#slaveSlider::sub-page:horizontal:disabled {";
		c << "background:qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0  #66e, stop:1 #bbf);";
		c << "border: 1px solid #777;";
		c << "height: 10px;";
		c << "border-top: 0;";
		c << "}";

		c << "#slaveSlider::add-page:horizontal:disabled {";
		c << "background: #fff;";
		c << "border: 1px solid #777;";
		c << "height: 10px;";
		c << "border-top: 0;";
		c << "}";

		c << "#slaveSlider::handle:horizontal:disabled {";
		c << "background: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 #ccc, stop:1 #aaa);";
		c << "border: 1px solid #777;";
		c << "border-top: 0;";
		c << "margin-bottom: -1px;";
		c << "width: 1px;";
		c << "}";

		deactiveSlaveStyle = QString::fromUtf8(c.str().c_str());
	}
public:
	virtual void setEnabled(bool enabled) {
		bool wasEnabled = ui_.dominantSlider->isEnabled();

		if (enabled != wasEnabled) {
			ui_.dominantSlider->setEnabled(enabled);
			updateStyle();
		}

		QWidget::setEnabled(enabled);
	}

	void setFocusOnEdit() {
		ui_.currentEdit->setFocus();
	}

	CombinedSlider(QWidget * parent) : QWidget(parent) {

		ui_.setupUi(this);

		isInside_ = false;
		canEmit_ = false;

		min_ = 0;

		QObject::connect(
			ui_.dominantSlider, SIGNAL(valueChanged(int)),
			this, SLOT(sliderValueChangedSlot(int)));

		QObject::connect(
			ui_.currentEdit, SIGNAL(textChanged(const QString &)),
			this, SLOT(lineEditValueChangedSlot(const QString &)));

		QObject::connect(
			ui_.currentEdit, SIGNAL(lostFocus()),
			this, SLOT(lineEditLostFocusSlot()));	

		setStyleStrings();

		updateStyle();
	}

	void updateStyle() {
		if (ui_.dominantSlider->isEnabled()) {
			ui_.slaveSlider->setStyleSheet(activeSlaveStyle);
		}
		else {
			ui_.slaveSlider->setStyleSheet(deactiveSlaveStyle);
		}
	}

	virtual void setValue(int newValue) {
		ui_.dominantSlider->setValue(newValue);
	}

	virtual int getValue() {
		return ui_.dominantSlider->value();
	}

	void setValueToMaximum() {
		setValue(this->max_);
	}

	virtual void setLimits(int min, int max) {
		this->min_ = min;
		this->max_ = max;

		QValidator * inputRange = new QIntValidator(min, max, this);
		
		ui_.currentEdit->setValidator(inputRange);

		ui_.dominantSlider->setMinimum(min);
		ui_.dominantSlider->setMaximum(max);

		ui_.slaveSlider->setMinimum(min);
		ui_.slaveSlider->setMaximum(max);
	}

	void setName(const std::wstring & name) {
		ui_.dominantSlider->setName(name);
	}
};

#endif