/*****************************************************************************
 * $CAMITK_LICENCE_BEGIN$
 *
 * CamiTK - Computer Assisted Medical Intervention ToolKit
 * (c) 2001-2018 Univ. Grenoble Alpes, CNRS, TIMC-IMAG UMR 5525 (GMCAO)
 *
 * Visit http://camitk.imag.fr for more information
 *
 * This file is part of CamiTK.
 *
 * CamiTK is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * CamiTK 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 version 3 for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with CamiTK.  If not, see <http://www.gnu.org/licenses/>.
 *
 * $CAMITK_LICENCE_END$
 ****************************************************************************/


#ifndef ImageLutWidget_H
#define ImageLutWidget_H

// -- stl stuff
#include <string>
#include <fstream>
#include <vector>
#include <sstream>

// -- QT stuff
#include <QListWidget>
#include <QLineEdit>
#include <QCheckBox>
#include <QMap>
#include <QPushButton>
#include <QGraphicsView>
#include <QGraphicsSimpleTextItem>

// -- vtk stuff
#include <vtkWindowLevelLookupTable.h>
#include <vtkSmartPointer.h>

// -- Camitk stuff
#include "ui_ImageLutWidget.h"

// -- Core image component stuff classes
#include <ImageComponent.h>

/**
 * @ingroup group_sdk_actions_image_lut
 *
 * @brief
 * The class ImageLutWidget defines a widget controling the Look Up Table of
 *  an instance of ImageComponent.
 *
 * @note
 * The ui is defined in the corresponding ImageLutWidget.ui
 *
 */
class ImageLutWidget : public QWidget {
    Q_OBJECT

public:
    /// Default construtor
    ImageLutWidget(QWidget* parent = nullptr);

    /// destructor
    ~ImageLutWidget() override;

    /// load the LUT data using the LUT from the image component
    void updateComponent(camitk::ImageComponent*);

private slots:

    /// Slot called when the slider for the lut level has changed
    void sliderLUTLevelChanged(int);

    /// Slot called when the line edit for the lut level has changed
    void lineEditLUTLevelChanged();

    /// Slot called when the slider for the window width has changed
    void sliderLUTWindowChanged(int);

    /// Slot called when the line edit for the window width has changed
    void lineEditLUTWindowChanged();

    /// Slot called when the invert button is clicked
    void invertButtonClicked();

    /// slot called when the min color button is clicked
    void setMinColor();

    /// slot called when the max color button is clicked
    void setMaxColor();

    /// Slot that reset changed applied to the LUT
    virtual void resetLUT();

    /// Update the component LUT using the GUI values
    void applyLUT();

protected:

    /// overwritten from QWidget to ensure fit in view, see fitView()
    void resizeEvent(QResizeEvent*) override;

    /// overwritten from QWidget to ensure fit in view, see fitView()
    void showEvent(QShowEvent*) override;

private:

    /// Init level slider and text with its minimum, maximum and current value.
    void initLevelGUI(int min, int max, int value);

    /// Init window slider and text with its minimum, maximum and current value.
    void initWindowGUI(int min, int max, int value);

    /// init a slider
    void initSlider(QSlider* slider, int min, int max, int value);

    /// block/unblock signals for all the GUI widgets
    void blockAllSignals(bool);

    /// draws the histogram and LUT graphic representation
    void draw();

    /// ensure that all graphics are completely visible and only that
    void fitView();

    /// fill the data for the histogram
    template<class DATATYPE> void fillHistogramTable(DATATYPE* data, unsigned int dataDim, DATATYPE minVal, DATATYPE maxVal);

    /// update the gradient display in the widget
    void updateGradient();

    /// the current ImageComponent
    camitk::ImageComponent* myComponent;

    /// Min the possible data value (given by the data type of the image)
    double lutMin;

    /// Min the possible data value (given by the data type of the image)
    double lutMax;

    /// Table containing histogram bins \note use double as it can have a high number of pixel of the same number
    double* greyLevels;

    /// highest number of grey level (highest value in greyLevels array) \note use double as it can have a high number of pixel of the same number
    double highestGreyLevel;

    /// size of greyLevels \note the maximum number of histogram bins is UINT_MAX
    unsigned int nbHistoBins;

    /// does the user asked for an invert LUT
    bool invert;

    /// the graphics item around all other item in the graphics view
    QGraphicsRectItem* sceneRectItem;

    /// the Qt GUI (build by ImageLutWidget.ui)
    Ui::ui_ImageLutWidget ui;

};

#endif
