

#include <modules/basegl/processors/volumeprocessing/vectormagnitudeprocessor.h>
#include <inviwo/core/datastructures/volume/volumeram.h>
#include <modules/base/algorithm/dataminmax.h>

namespace inviwo {
const ProcessorInfo VectorMagnitudeProcessor::processorInfo_{
    "org.inviwo.VectorMagnitude",  // Class identifier
    "Vector Magnitude",            // Display name
    "Volume Operation",            // Category
    CodeState::Stable,             // Code state
    Tags::GL,                      // Tags
};
const ProcessorInfo VectorMagnitudeProcessor::getProcessorInfo() const { return processorInfo_; }

VectorMagnitudeProcessor::VectorMagnitudeProcessor()
    : VolumeGLProcessor("vectormagnitudeprocessor.frag") {
    this->dataFormat_ = DataFloat32::get();
}

VectorMagnitudeProcessor::~VectorMagnitudeProcessor() = default;

void VectorMagnitudeProcessor::preProcess(TextureUnitContainer &) {
    int numChannels = 3;
    if (inport_.hasData()) {
        numChannels = static_cast<int>(inport_.getData()->getDataFormat()->getComponents());
    }

    shader_.setUniform("numInputChannels_", numChannels);
}

void VectorMagnitudeProcessor::postProcess() {

    auto minMax =
        util::volumeMinMax(volume_->getRepresentation<VolumeRAM>(), IgnoreSpecialValues::Yes);
    double minV, maxV;
    minV = minMax.first.x;
    maxV = minMax.second.x;
    for (int i = 0; i < 3; i++) {
        minV = std::min(minV, minMax.first[i]);
        maxV = std::max(maxV, minMax.second[i]);
    }

    volume_->dataMap_.dataRange = dvec2(0, std::abs(maxV));
    volume_->dataMap_.valueRange = dvec2(minV, maxV);
}

}  // namespace inviwo
