/*****************************************************************************
 * $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 VOLUMERENDERINGWIDGET_H
#define VOLUMERENDERINGWIDGET_H

// - Qt stuff
#include <QWidget>
#include <QString>

// - Local Stuff
#include "ColorPointWidget.h"
#include "GradientOpacityWidget.h"
#include "TransparencyPointWidget.h"

#include "ui_VolumeRenderingWidget.h"

class VolumeRenderingAction;
/**
 * @ingroup group_sdk_actions_image_volumerendering
 *
 * @brief
 * The widget allows the user to select the desired parameter for the transfer function.
 *
 * The transfer function allows one to select the desired (R,G,B,alpha) values of the rendered 3D image.
 * \image html actions/volume_rendering_2.png "The transfer function widget." width=10cm
 *
 */
class VolumeRenderingWidget : public QWidget {
    Q_OBJECT

public:
    /// Default construtor
    VolumeRenderingWidget(VolumeRenderingAction* myAction, QWidget* parent = nullptr);

    /// update the UI using the given name (current image name) and its visibility
    /// existVR should be true if the volume rendering component of the image was alread created using a colormap
    /// visibility is given by the action's proprety
    void updateUI(QString name, bool existVR);

    /// get the current visibility value
    bool visibility();

    // ----------- Destructor
    ~VolumeRenderingWidget() override;

    // ----------- Transparency
    void removeTransparencyPoint(TransparencyPointWidget* point);

    void setDefaultTransparencies(QMap<int, double> defaultTransparencies);

    void addTransparency(int grayLevel, double transparency);

    QMap<int, double> getTransparencyPoints();

    // ----------- Colors
    void removeColorPoint(ColorPointWidget* point);

    void setDefaultColors(QMap<int, QColor> defaultColors);

    void addColor(int grayLevel, QColor color);

    QMap<int, QColor> getColorPoints();

    // ----------- Gradient Opacity
    void removeOpacityPoint(GradientOpacityWidget* point);

    void setDefaultOpacities(QMap<int, double> defaultOpacities);

    void addGradientOpacity(int grayLevel, double opacity);

    QMap<int, double> getOpacityPoints();

    // ----------- Lights
    void setAmbient(double ambient);
    double getAmbient();

    void setDiffuse(double diffuse);
    double getDiffuse();

    void setSpecular(double specular);
    double getSpecular();

    void load(QString filename);

signals:
    /// emitted when the user clicked on the Refresh button
    void refresh();

public slots:
    /// Load / Save / Reset colormaps
    virtual void loadColorMap();
    virtual void saveColorMap();
    virtual void resetColorMap();
    /// When to change volume rendering
    virtual void refreshVolumeRendering();
    /// Transparency
    virtual void addTransparency();
    /// Color
    virtual void addColor();
    /// Gradient Opacity
    virtual void addGradientOpacity();
    /// ambient Light Value Editing
    virtual void ambientLightSliderChanged(int);
    virtual void ambientLightSpinBoxChanged(double);
    /// Diffuse Light Value Editing
    virtual void diffuseLightSliderChanged(int);
    virtual void diffuseLightSpinBoxChanged(double);
    /// Specular Light Value Editing
    virtual void specularLightSliderChanged(int);
    virtual void specularLightSpinBoxChanged(double);
    // visibilty
    virtual void visibilityToggled(bool);
private:
    Ui_VolumeRenderingWidget ui;
    QList<ColorPointWidget*> colorPoints;
    QList<GradientOpacityWidget*> gradientOpacities;
    QList<TransparencyPointWidget*> transparencies;
    VolumeRenderingAction* myAction;
};

#endif
