/*****************************************************************************
 * $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$
 ****************************************************************************/
#include "ThresholdVTK.h"

//
// Generated source for action "Threshold"
// 2024-04-28 - 14:12:43
//

// CamiTK includes
#include <Property.h>
#include <Log.h>





// includes for specific types
#include <vtkImageThreshold.h>
#include <vtkCallbackCommand.h>
#include <vtkNew.h>


// This action process ImageComponent, include is required
#include <ImageComponent.h>
#include <Application.h>

using namespace camitk;

// -------------------- process --------------------
Action::ApplyStatus ThresholdVTK::process() {
    // set the waiting cursor during processing
    QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
    Application::showStatusBarMessage(tr("Computing threshold..."));
    Application::resetProgressBar();
    vtkSmartPointer<vtkCallbackCommand> progressCallback = vtkSmartPointer<vtkCallbackCommand>::New();
    progressCallback->SetCallback(&Application::vtkProgressFunction);

    // Process each targets
    for (Component* selected : getTargets()) {
        ImageComponent* inputComp = dynamic_cast <ImageComponent*>(selected);

        vtkNew<vtkImageThreshold> imageThreshold;
        imageThreshold->SetInputData(inputComp->getImageData());
        imageThreshold->ThresholdBetween(getParameterValue("Low Threshold").value<double>(), getParameterValue("High Threshold").value<double>());
        switch (getParameterValue("Replace Values").value<int>()) {
            case 0: // Replace In Values
                imageThreshold->SetInValue(getParameterValue("In Value").value<double>());
                break;
            case 1: // Replace Out Values
                imageThreshold->SetOutValue(getParameterValue("Out Value").value<double>());
                break;
            case 2: // Replace Both
                imageThreshold->SetInValue(getParameterValue("In Value").value<double>());
                imageThreshold->SetOutValue(getParameterValue("Out Value").value<double>());
                break;
        }
        imageThreshold->Update();

        // Create the output component
        ImageComponent* outputComp = new ImageComponent(imageThreshold->GetOutput(), inputComp->getName() + " [" + getParameterValueAsString("Low Threshold") + "." + ((imageThreshold->GetReplaceIn() != 0) ? "*" : "") + "." + getParameterValueAsString("High Threshold") + "]" + ((imageThreshold->GetReplaceOut() != 0) ? "*" : ""));

        // consider frame policy on new image
        outputComp->setFrameFrom(inputComp);
    }

    // refresh and restore the normal cursor and progress bar
    refreshApplication();
    Application::resetProgressBar();
    Application::showStatusBarMessage("");
    QApplication::restoreOverrideCursor();

    return SUCCESS;
}

// -------------------- targetDefined --------------------
void ThresholdVTK::targetDefined() {
    // This method updates the range of the parameters

    //-- Compute the maximum and the minimum possible value for the selected images
    double min = VTK_DOUBLE_MAX;
    double max = VTK_DOUBLE_MIN;

    for (Component* comp : getTargets()) {
        vtkSmartPointer<vtkImageData> inputImage = dynamic_cast<ImageComponent*>(comp)->getImageData();
        double* imgRange = inputImage->GetScalarRange();

        if (min > imgRange[0]) {
            min = imgRange[0];
        }

        if (max < imgRange[1]) {
            max = imgRange[1];
        }
    }
    double step = (max - min) / 255.0;

    //-- Apply min/max values to the threshold properties
    setParameterValue("Low Threshold", (max - min) / 2.0);
    setParameterValue("High Threshold", max);
    setParameterValue("In Value", max);
    setParameterValue("Out Value", min);

    // -- Set the range of all parameters
    QStringList parameterNames = {"Low Threshold", "High Threshold", "In Value", "Out Value"};
    for (auto paramName : parameterNames) {
        camitk::Property* parameterToUpdate = getProperty(paramName);
        if (parameterToUpdate != nullptr) {
            parameterToUpdate->setAttribute("minimum", min);
            parameterToUpdate->setAttribute("maximum", max);
            parameterToUpdate->setAttribute("singleStep", (step < 1.0) ? 1 : step);
        }
    }
}

// -------------------- parameterChanged --------------------
void ThresholdVTK::parameterChanged(QString parameterName) {
}

// -------------------- init --------------------
void ThresholdVTK::init() {
}
