#include "PluginHost.h"
#include <cstdio>

PluginHost::PluginHost()
{
	// VST2 today. Adding VST3PluginFormat/LADSPAPluginFormat (or, later, an
	// LV2 format) is just another addFormat() call here - load()/process()/
	// the parameter and state APIs below never need to change.
	formatManager.addFormat (new VSTPluginFormat());
}

PluginHost::~PluginHost()
{
	releaseResources();
}

bool PluginHost::load (const String &pluginPath, double sampleRate, int blockSize)
{
	for (int i = 0; i < formatManager.getNumFormats(); ++i)
	{
		AudioPluginFormat *format = formatManager.getFormat (i);

		OwnedArray<PluginDescription> found;
		format->findAllTypesForFile (found, pluginPath);

		if (found.size() == 0)
			continue;

		String error;
		plugin = formatManager.createPluginInstance (*found[0], sampleRate, blockSize, error);

		if (plugin == nullptr)
		{
			fprintf (stderr, "testhost: %s recognised '%s' but failed to load it: %s\n",
				format->getName().toRawUTF8(), pluginPath.toRawUTF8(), error.toRawUTF8());
			return false;
		}

		plugin->prepareToPlay (sampleRate, blockSize);
		return true;
	}

	fprintf (stderr, "testhost: no registered plugin format recognised '%s'\n", pluginPath.toRawUTF8());
	return false;
}

void PluginHost::releaseResources()
{
	if (plugin != nullptr)
		plugin->releaseResources();
}

int PluginHost::getNumInputChannels() const
{
	return plugin != nullptr ? plugin->getNumInputChannels() : 0;
}

int PluginHost::getNumOutputChannels() const
{
	return plugin != nullptr ? plugin->getNumOutputChannels() : 0;
}

void PluginHost::process (AudioSampleBuffer &buffer, MidiBuffer &midiMessages)
{
	jassert (plugin != nullptr);
	plugin->processBlock (buffer, midiMessages);
}

int PluginHost::getNumParameters() const
{
	return plugin != nullptr ? plugin->getNumParameters() : 0;
}

float PluginHost::getParameter (int index) const
{
	return plugin != nullptr ? plugin->getParameter (index) : 0.0f;
}

void PluginHost::setParameter (int index, float value)
{
	if (plugin != nullptr)
		plugin->setParameter (index, value);
}

void PluginHost::getCurrentProgramStateInformation (MemoryBlock &destData)
{
	if (plugin != nullptr)
		plugin->getCurrentProgramStateInformation (destData);
}

void PluginHost::setCurrentProgramStateInformation (const void *data, int sizeInBytes)
{
	if (plugin != nullptr)
		plugin->setCurrentProgramStateInformation (data, sizeInBytes);
}

void PluginHost::getStateInformation (MemoryBlock &destData)
{
	if (plugin != nullptr)
		plugin->getStateInformation (destData);
}

void PluginHost::setStateInformation (const void *data, int sizeInBytes)
{
	if (plugin != nullptr)
		plugin->setStateInformation (data, sizeInBytes);
}
