/*
    QAD - Qt ADvanced

    Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef EVALSPINBOX_H
#define EVALSPINBOX_H

#include "qad_widgets_export.h"

#include <QAbstractSpinBox>


class QPIEvaluator;
class QLabel;


class QAD_WIDGETS_EXPORT EvalSpinBox: public QAbstractSpinBox {
	Q_OBJECT
	Q_PROPERTY(double value READ value WRITE setValue NOTIFY valueChanged USER true)
	Q_PROPERTY(QString expression READ expression WRITE setExpression USER true)
	Q_PROPERTY(QString defaultText READ defaultText WRITE setDefaultText)
	Q_PROPERTY(bool clearButtonVisible READ isClearButtonVisible WRITE setClearButtonVisible)
	Q_PROPERTY(bool calculationVisible READ isCalculationVisible WRITE setCalculationVisible)
	Q_PROPERTY(int precision READ precision WRITE setPrecision)
	Q_PROPERTY(double singleStep READ singleStep WRITE setSingleStep)

public:
	explicit EvalSpinBox(QWidget * parent = nullptr);
	~EvalSpinBox() override;

	double value() const;
	const QString & expression() const;
	const QString & defaultText() const { return dt; }
	bool isClearButtonVisible() const { return cw_visible; }
	bool isCalculationVisible() const { return calc_visible; }
	bool isCleared() const;
	int precision() const { return precision_; }
	double singleStep() const { return m_singleStep; }

	void stepBy(int steps) override;
	void clear() override;
	QSize sizeHint() const override;

public slots:
	void setExpression(const QString & expr);
	void setValue(double val);
	void setDefaultText(const QString & t);
	void setClearButtonVisible(bool visible);
	void setCalculationVisible(bool visible);
	void setPrecision(int precision) { precision_ = precision; }
	void setSingleStep(double step) { m_singleStep = step; }

protected:
	QString text() const { return QAbstractSpinBox::text(); }

	StepEnabled stepEnabled() const override;
	void focusInEvent(QFocusEvent * event) override;
	void focusOutEvent(QFocusEvent * event) override;
	void wheelEvent(QWheelEvent * event) override;

	void stepByDouble(double steps);

private slots:
	void clearMouseRelease(QMouseEvent * e);
	void textChanged_(const QString & text);
	void setExpressionSlot();
	void resizeIcons();

signals:
	void valueChanged(double val);
	void cleared();

private:
	bool eventFilter(QObject * o, QEvent * e) override;
	void resizeEvent(QResizeEvent *) override;
	void changeEvent(QEvent * e) override;
	void statusPaintEvent();
	void cwPaintEvent();

	QWidget * status;
	QWidget * cw;
	QPIEvaluator * eval;
	QLabel * label;
	QImage icon_ok;
	QImage icon_fail;
	QImage icon_calc;
	QImage icon;
	QImage clear_im;
	QString dt;
	bool cw_visible = false, calc_visible = true;
	int precision_      = -1;
	double m_singleStep = 1.;
};

#endif // EVALSPINBOX_H
