#ifndef TESTHOST_PLUGINHOST_H_INCLUDED
#define TESTHOST_PLUGINHOST_H_INCLUDED

#include <JuceHeader.h>

/** Loads and drives a single plugin instance, offline (no audio device).

	Deliberately format-agnostic: it talks only to AudioPluginFormatManager /
	AudioPluginInstance / AudioProcessor, never to a specific format's SDK
	structs. Adding another format later (VST3, LADSPA, eventually LV2) is
	just another addFormat() call in the constructor - nothing here changes.

	Also deliberately makes no assumption about the plugin's channel layout:
	an instrument (0 inputs) and an effect (N inputs) are handled identically
	by always asking the loaded AudioProcessor for its actual channel counts.
*/
class PluginHost
{
public:
	PluginHost();
	~PluginHost();

	/** Scans pluginPath against every registered format and instantiates the
		first match. Returns false (with a message printed to stderr) if no
		registered format recognises the file, or if instantiation fails.
	*/
	bool load (const String &pluginPath, double sampleRate, int blockSize);

	void releaseResources();

	int getNumInputChannels() const;
	int getNumOutputChannels() const;

	/** Runs one block through the plugin. buffer must already be sized to
		at least max(getNumInputChannels(), getNumOutputChannels()) channels
		by numSamples samples; input channels should already be filled
		(AudioInputSource's job), output channels are overwritten in place.
	*/
	void process (AudioSampleBuffer &buffer, MidiBuffer &midiMessages);

	int getNumParameters() const;
	float getParameter (int index) const;
	void setParameter (int index, float value);

	// Patch (single program) state.
	void getCurrentProgramStateInformation (MemoryBlock &destData);
	void setCurrentProgramStateInformation (const void *data, int sizeInBytes);

	// Bank (full plugin) state.
	void getStateInformation (MemoryBlock &destData);
	void setStateInformation (const void *data, int sizeInBytes);

	AudioPluginInstance *getInstance() const { return plugin; }

private:
	AudioPluginFormatManager formatManager;
	ScopedPointer<AudioPluginInstance> plugin;

	JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (PluginHost)
};

#endif // TESTHOST_PLUGINHOST_H_INCLUDED
