/*****************************************************************************
 * $CAMITK_LICENCE_BEGIN$
 *
 * CamiTK - Computer Assisted Medical Intervention ToolKit
 * (c) 2001-2025 Univ. Grenoble Alpes, CNRS, Grenoble INP - UGA, TIMC, 38000 Grenoble, France
 *
 * 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

// -- QT stuff
#include <QMap>

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

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

class HistogramGraphicsRectItem;
class ImageLutModel;
/**
 * @ingroup group_sdk_actions_image_lut
 *
 * @brief
 * The class ImageLutWidget defines a widget controling the Look Up Table of
 *  an instance of ImageComponent.
 *
 * Uses double data type to manage the histogram. This allows for managin properly all
 * type of voxel datatype.
 *
 * @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 (requires an ImageComponent with a LUT)
    void updateComponent(camitk::ImageComponent*);

    /// show tool tip from the histogramGraphicsRectItem
    void showHistogramTooltip(QPointF);

private slots:

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

    /// Slot called when the level sping box has changed
    void levelSpinBoxChanged(double);

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

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

    /// 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();

    /// change the number of histogram bins
    void binComboBoxChanged(QString);

    /// 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 initLevel(double value);

    /// Init window slider and text with its minimum, maximum and current value.
    void initWindow(double value);

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

    /// draws the histogram and LUT graphic representations
    void drawGraphics();

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

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

    /// update binComboBox with the actual number of bins in the model
    void updateBinComboBox();

    /// Update minColor or maxColor attribut and set the given push button background to the given color
    /// using stylesheet depending on the whichButton QString.
    /// Also update the transparency states.
    /// Guarantees that the UI and minColor/maxColor attributes are coherent
    /// @param whichColor QString parameter specify which button is to set. It should be either "min" or "max"
    /// @param newColor the new color value to use
    /// @return true if whichColor and color are valid and the background was set
    bool setColor(QString whichColor, QColor newColor);

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

    /// the graphics item around all other item in the graphics view
    /// (needed to scale the histogram view to this rectangle and to show a tool tip when mouse hover
    HistogramGraphicsRectItem* histogramGraphicsRectItem;

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

    /// min and max colors
    QColor minColor;
    QColor maxColor;

    /// the current image LUT model (histogram, etc...)
    ImageLutModel* model;

    /// History of all the models computed so far
    /// This optimizes the change of images currently selected by the action
    /// and avoir re-computation
    QMap<camitk::ImageComponent*, ImageLutModel*> allModels;
};

#endif
