#ifndef WIDGETS_GRAPHPLOTTER_RULER_H
#define WIDGETS_GRAPHPLOTTER_RULER_H

#include "GraphPlotter.h"


// -- TDE NAMESPACE ----------------------------------------------------

namespace TDE {

// -- Widgets NAMESPACE ------------------------------------------------

namespace Widgets {

namespace Plot {


class Ruler;

typedef SHARED_PTR<QGraphicsScene> QGraphicsScenePtr;
typedef SHARED_PTR<GraphPlotter> GraphPlotterPtr;

typedef SHARED_PTR<Ruler> RulerPtr;

class WIDGETS_EXPORT Ruler : public QGraphicsView
{
	Q_OBJECT
    Q_PROPERTY(Qt::AnchorPoint anchor READ anchor WRITE anchor)
    Q_ENUMS(Qt::AnchorPoint)
    Q_PROPERTY(double ticsEvery READ ticsEvery WRITE ticsEvery)
    Q_PROPERTY(double minorTicsEvery READ minorTicsEvery WRITE minorTicsEvery)
    Q_PROPERTY(double ticsScaleFactor READ ticsScaleFactor WRITE ticsScaleFactor)
    Q_PROPERTY(QColor bgColor READ bgColor WRITE bgColor)
    Q_PROPERTY(QColor ticsColor READ ticsColor WRITE ticsColor)
    Q_PROPERTY(QColor bgColor READ bgColor WRITE bgColor)
    Q_PROPERTY(int labelsFontSize READ labelsFontSize WRITE labelsFontSize)
    Q_PROPERTY(int labelsOffset READ labelsOffset WRITE labelsOffset)

public:
    Ruler(QWidget* parent = 0);
    Ruler(GraphPlotterPtr plotterPtr, Qt::AnchorPoint anchor = DEFAULT_ANCHOR, QWidget* parent = 0);
    Ruler(GraphPlotterPtr plotterPtr, DataSetPtr dataSetPtr, Qt::AnchorPoint anchor = DEFAULT_ANCHOR, QWidget* parent = 0);
    virtual ~Ruler();

public slots:
	virtual void redraw();

	virtual bool 	        hasPlotter() const 						{ return m_plotter_ptr.get(); }
	virtual GraphPlotterPtr plotter() const 						{ return m_plotter_ptr; }
	virtual void            plotter(GraphPlotterPtr plotterPtr);

	virtual bool 	   hasReferenceDataSet() const 					{ return m_ref_dataset.get(); }
	virtual DataSetPtr referenceDataSet() const 					{ return m_ref_dataset; }
	virtual void       referenceDataSet(DataSetPtr dataSetPtr, bool explicit_ = true);
	virtual void       referenceDataSet(const std::string& name, bool explicit_ = true);

	virtual Qt::AnchorPoint anchor() const                          { return m_anchor; }
	virtual Qt::AnchorPoint anchor(Qt::AnchorPoint anchor, bool redraw = true);
	virtual bool isLeft() const                                     { return (m_anchor == Qt::AnchorLeft); }
	virtual bool isRight() const                                    { return (m_anchor == Qt::AnchorRight); }
	virtual bool isTop() const                                      { return (m_anchor == Qt::AnchorTop); }
	virtual bool isBottom() const                                   { return (m_anchor == Qt::AnchorBottom); }
	virtual bool horizontal() const                                 { return (m_anchor == Qt::AnchorTop) || (m_anchor == Qt::AnchorBottom); }
	virtual bool vertical() const                                   { return (! horizontal()); }
	virtual double ticsEvery() const								{ return m_tics_every; }
	virtual double ticsEvery(double value, bool redraw = true);
	virtual double minorTicsEvery() const							{ return m_minor_tics_every; }
	virtual double minorTicsEvery(double value, bool redraw = true);
	virtual double ticsScaleFactor() const                          { return m_tics_scale_factor; }
	virtual double ticsScaleFactor(double value, bool redraw = true);

	virtual QColor	bgColor() const							{ return m_bg_color; }
	virtual QColor	bgColor(const QColor& value, bool redraw = true);
	virtual QColor	ticsColor() const						{ return m_tics_color; }
	virtual QColor	ticsColor(const QColor& value, bool redraw = true);
	virtual QColor	minorTicsColor() const					{ return m_minor_tics_color; }
	virtual QColor	minorTicsColor(const QColor& value, bool redraw = true);
	virtual int     labelsFontSize() const                  { return m_labels_fontsize; }
	virtual int     labelsFontSize(int value, bool redraw = true);
	virtual int     labelsOffset() const                    { return m_labels_offset; }
	virtual int     labelsOffset(int value, bool redraw = true);

	virtual QSize  internalSize() const;
	virtual QSizeF internalSizeF() const;

protected slots:
	virtual void on_dataset_update(QString name, long updated_id);
	virtual void on_dataset_rangechange(QRectF range);
	virtual void on_plotter_ref_ds_change(QString name);		// reference dataset changed

signals:

protected:
	virtual bool computeTicsScale(double& ticsScale, double& nMinorTics, double& nTics) const;
	virtual void drawScene(bool invalidate = false);
	virtual void resizeEvent(QResizeEvent* event);

public:
	static const QColor DEFAULT_BG_COLOR;
	static const QColor DEFAULT_TICS_COLOR;
	static const QColor DEFAULT_MINOR_TICS_COLOR;
	static const int    DEFAULT_LABELS_FONTSIZE;
	static const int    DEFAULT_LABELS_OFFSET;

	static const Qt::AnchorPoint DEFAULT_ANCHOR;
	static const double DEFAULT_MAJOR_TICS;
	static const double DEFAULT_MINOR_TICS;
	static const double DEFAULT_TICS_SCALE_FACTOR;

private:
	QGraphicsScenePtr m_scene;

	GraphPlotterPtr m_plotter_ptr;
	DataSetPtr m_ref_dataset;
	bool m_explicit_ref_dataset;
	QMetaObject::Connection m_ds_update_connection;
	QMetaObject::Connection m_ds_rangechange_connection;
	QMetaObject::Connection m_ref_ds_connection;

	Qt::AnchorPoint m_anchor;
	double m_tics_every;
	double m_minor_tics_every;
	double m_tics_scale_factor;

	QColor m_bg_color;
	QColor m_tics_color;
	QColor m_minor_tics_color;
	int m_labels_fontsize;
	int m_labels_offset;

	bool   m_plot_surface_set;
	QRectF m_plot_surface;
};


} /* end of namespace Plot */

} /* end of namespace Widgets */

} /* end of namespace TDE */

#endif /* WIDGETS_GRAPHPLOTTER_RULER_H */
