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

    PluginEditor.h
    Created: 4 Nov 2025 6:20:46pm
    Author:  mickl

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

#pragma once
#include <JuceHeader.h>
#include "PluginProcessor.h"
extern const String localDevServerAddress;

std::optional<WebBrowserComponent::Resource> getResource(const String& url);

//==============================================================================
class SinglePageBrowser : public WebBrowserComponent
{
public:
	using WebBrowserComponent::WebBrowserComponent;

	// Prevent page loads from navigating away from our single page web app
	bool pageAboutToLoad(const String& newURL) override;
};

//==============================================================================
class WebViewPluginAudioProcessorEditor : public AudioProcessorEditor, private Timer
{
public:
	explicit WebViewPluginAudioProcessorEditor(WebViewPluginAudioProcessor&);
	~WebViewPluginAudioProcessorEditor() {
		delete webComponent;
		for (auto& attatchments : slider_attatchments) {
			delete attatchments;
		}
		for (auto& relays : slider_relays) {
			delete relays;
		}

		for (auto& attatchments : toggle_attatchments) {
			delete attatchments;
		}
		for (auto& relays : toggle_relays) {
			delete relays;
		}
	}

	std::optional<WebBrowserComponent::Resource> getResource(const String& url);

	//==============================================================================
	void paint(Graphics&) override;
	void resized() override;

	int getControlParameterIndex(Component&) override
	{
		return controlParameterIndexReceiver.getControlParameterIndex();
	}

	void timerCallback() override
	{
		static constexpr size_t numFramesBuffered = 5;

		SpinLock::ScopedLockType lock{ processorRef.midiLock };

		static int64 callbackCounter = 0;
		processorRef.new_midi = false;
		juce::Array<var> notes;
		int voice_num = 0;
		for (auto& voice : processorRef.shifter.voices) {
			if (voice.onoff_) {
				auto obj = new DynamicObject();
				obj->setProperty("voice", voice_num);
				obj->setProperty("midi", voice.GetMidiNote());
				notes.add(var(obj));
			}
			voice_num++;
		}

		DynamicObject::Ptr d(new DynamicObject());
		d->setProperty("notes", notes);
		d->setProperty("input_pitch", processorRef.shifter.getInputPitch());
		d->setProperty("output_pitch", processorRef.shifter.getOutputPitch());
		webComponent->emitEventIfBrowserIsVisible("midNoteData", d.get());
	}

private:
	WebViewPluginAudioProcessor& processorRef;
	std::vector<WebSliderRelay*> slider_relays;
	std::vector< WebSliderParameterAttachment*> slider_attatchments;

	std::vector<WebToggleButtonRelay*> toggle_relays;
	std::vector< WebToggleButtonParameterAttachment*> toggle_attatchments;

	WebControlParameterIndexReceiver controlParameterIndexReceiver;

	SinglePageBrowser* webComponent = nullptr;

	std::deque<Array<var>> spectrumDataFrames;

	JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(WebViewPluginAudioProcessorEditor)
};