#ifndef HistogramWidget_h
#define HistogramWidget_h

/******************************************************************************
*
* Copyright (C) 2002 Hugo PEREIRA <mailto: hugo.pereira@free.fr>
*
* This is free software; you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later
* version.
*
* This software 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 General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License along with
* this program.  If not, see <http://www.gnu.org/licenses/>.
*
*******************************************************************************/

#include "Counter.h"
#include "Debug.h"

#include <QList>
#include <QResizeEvent>
#include <QScrollArea>
#include <QVector>
#include <QWidget>

//* drawing area
class HistogramWidget: public QWidget, private Base::Counter<HistogramWidget>
{

    Q_OBJECT

    public:

    //* constructor
    explicit HistogramWidget( QScrollArea* );

    //* visible height
    void setVisibleHeight( int value )
    { visibleHeight_ = value; }

    //* text
    void setText( QString text )
    { text_ = text; }

    //* handles foreground and fill color for histograms
    class Color: private Base::Counter<Color>
    {

        public:

        //* constructor
        explicit Color( const QString& name ):
            Counter( "HistogramWidget::Color" ),
            name_( name ),
            gradient_( 0, 0, 1, 0 ),
            use_gradient_( false )
        {
            Debug::Throw( "HistogramWidget::Color::Color.\n" );
            update();
        }

        //* update from options
        void update();

        //* update gradient
        void updateGradient( const QSize& size );

        //* foreground
        const QColor& foreground() const
        { return foreground_; }

        //* background
        QBrush background() const
        { return (use_gradient_) ? QBrush( gradient_ ) : QBrush( background_ ); }

        private:

        //* name
        QString name_;

        //* foreground color
        QColor foreground_;

        //* background color
        QColor background_;

        //* background brush (with gradient)
        QLinearGradient gradient_;

        //* brush
        bool use_gradient_;

    };

    //* dataset
    class DataSet: private Base::Counter<DataSet>
    {
        public:

        //* dataset list
        using List = QList<DataSet>;

        //* values
        using ValueList = QVector<double>;

        //* constructor
        explicit DataSet( const QString& name = HistogramWidget::tr( "Generic Dataset" ), const QString& optionName = QString() ):
            Counter( "HistogramWidget::DataSet" ),
            name_( name ),
            color_( optionName )
        { Debug::Throw( "HistogramWidget::DataSet::DataSet.\n" ); }

        //* name
        void setName( const QString& name )
        { name_ = name; }

        //* name
        const QString& name() const
        { return name_; }

        //* store values
        void setValues( const ValueList& values )
        { values_ = values; }

        //* get values
        const ValueList& values() const
        { return values_; }

        //* get values
        ValueList& values()
        { return values_; }

        //* color
        void setColor( const Color& color )
        { color_ = color; }

        //* color
        const Color& color() const
        { return color_; }

        //* color
        Color& color()
        { return color_; }

        private:

        //* name
        QString name_;

        //* values
        ValueList values_;

        //* color
        HistogramWidget::Color color_;

    };

    //* dataset
    void clearDataSets();

    //* dataset
    void resetDataSets()
    { dataSets_.clear(); }

    //* dataset
    void addDataSet( const DataSet& dataset )
    { dataSets_ << dataset; }

    //* get dataset
    const DataSet& dataSet( int index ) const
    { return dataSets_[index]; }

    //* get dataset
    DataSet& dataSet( int index )
    { return dataSets_[index]; }

    private Q_SLOTS:

    //* update configuration
    void _updateConfiguration();

    protected:

    //*@name event handlers
    //@{

    //* repaint
    void paintEvent( QPaintEvent *e );

    //* resize event [overloaded]
    void resizeEvent( QResizeEvent* );

    //@}

    private:

    //* parent scroll area
    QScrollArea* parent_;

    //* paint text
    void _paintText( QRect );

    //* text
    QString text_;

    //* number of tick marks along x axis
    int divX_;

    //* number of tick marks along y axis
    int divY_;

    //* division color
    Color divColor_;

    //* visible height
    int visibleHeight_;

    //* data sets
    DataSet::List dataSets_;

};

#endif
