/*
  ==============================================================================

    CMLSDelay.cpp
    Created: 3 May 2025 5:39:35pm
    Author:  Luigi

  ==============================================================================
*/

#include "CMLSDelay.h"
#include <windows.h>

CMLSDelay::CMLSDelay() {
	//feedbackRange = new juce::NormalisableRange<float>(MIN_FEEDBACK, MAX_FEEDBACK);

	this->delayLength = 0.0f;
	this->feedback = 0.0f;
	this->amount = 0.0f;
	this->dryWetProp = 0.0f;
}

CMLSDelay::~CMLSDelay() {}

void CMLSDelay::reset() {
	this->delayLine.reset();
	this->mixer.reset();
}

void CMLSDelay::prepare(const juce::dsp::ProcessSpec& spec) {
	this->maximumDelaySamples = spec.sampleRate * MAX_DELAY_LENGTH;
	this->delayRange = new juce::NormalisableRange<float>(0, this->maximumDelaySamples);
	this->delaySmoothing = new juce::SmoothedValue<float, juce::ValueSmoothingTypes::Linear>(this->delayLength);

	this->delayLine.prepare(spec);
	this->delayLine.setMaximumDelayInSamples(this->maximumDelaySamples);

	this->mixer.prepare(spec);
	this->mixer.setMixingRule(juce::dsp::DryWetMixingRule::linear);
}

void CMLSDelay::process(const juce::dsp::ProcessContextReplacing<float>& context) {
	auto audioBlock = context.getOutputBlock();
	auto numChannels = audioBlock.getNumChannels();
	const auto numSamples = audioBlock.getNumSamples();

	this->mixer.pushDrySamples(context.getInputBlock());

	for (int channel = 0; channel < numChannels; ++channel)
	{
		for (int i = 0; i < numSamples; i++)
		{
			this->delayLine.pushSample(channel, context.getInputBlock().getSample(channel, i));
			audioBlock.setSample(
				channel,
				i,
				this->delayLine.popSample(channel, this->delayLine.getDelay())
			);
		}
	}

	this->lastDelayInSamples = this->delayLine.getDelay();

	// Adding wet (elaborated) signal
	this->mixer.mixWetSamples(audioBlock);
}

void CMLSDelay::setDryWet(float value) {
	this->dryWetProp = value;
	this->mixer.setWetMixProportion(this->dryWetProp);
}

void CMLSDelay::setAmount(float value) {
	this->delayLength = this->delayRange->convertFrom0to1(value);
	this->delayLine.setDelay(this->delayLength);
	std::string test = std::to_string(this->delayLength) + "\n";
	OutputDebugString(test.c_str());
	
}

const float CMLSDelay::getDryWet() {
	return this->dryWetProp;
}

const float CMLSDelay::getAmount() {
	return this->amount;
}