
#ifndef _MIDI_PRODUCER_H
#define _MIDI_PRODUCER_H

#include <Locker.h>
#include <MidiEndpoint.h>

class BList;

class BMidiProducer : public BMidiEndpoint
{
public:

	status_t Connect(BMidiConsumer* cons);
	status_t Disconnect(BMidiConsumer* cons);
	bool IsConnected(BMidiConsumer* cons) const;
	BList* Connections() const;

private:

	friend class BMidiLocalProducer;
	friend class BMidiRoster;
	friend class BMidiRosterLooper;
	
	BMidiProducer(const char* name = NULL);	
	virtual ~BMidiProducer();

	virtual void _Reserved1();
	virtual void _Reserved2();
	virtual void _Reserved3();
	virtual void _Reserved4();
	virtual void _Reserved5();
	virtual void _Reserved6();
	virtual void _Reserved7();
	virtual void _Reserved8();		

	status_t SendConnectRequest(BMidiConsumer*, bool);
	void ConnectionMade(BMidiConsumer*);
	bool ConnectionBroken(BMidiConsumer*);

	int32 CountConsumers() const;
	BMidiConsumer* ConsumerAt(int32) const;

	bool LockProducer() const;
	void UnlockProducer() const;

	BList* connections;
	BLocker* locker;

	uint32 _reserved[10];
};

class BMidiLocalProducer : public BMidiProducer
{
public:

	BMidiLocalProducer(const char* name = NULL);	
	
	virtual void Connected(BMidiConsumer* cons);
	virtual void Disconnected(BMidiConsumer* cons);
	
	void SprayData(
		void* data, size_t length, bool atomic = false, 
		bigtime_t time = 0) const;
	
	void SprayNoteOff(
		uchar channel, uchar note, uchar velocity, 
		bigtime_t time = 0) const;

	void SprayNoteOn(
		uchar channel, uchar note, uchar velocity, 
		bigtime_t time = 0) const;

	void SprayKeyPressure(
		uchar channel, uchar note, uchar pressure, 
		bigtime_t time = 0) const;

	void SprayControlChange(
		uchar channel, uchar controlNumber, uchar controlValue, 
		bigtime_t time = 0) const;

	void SprayProgramChange(
		uchar channel, uchar programNumber, bigtime_t time = 0) const;

	void SprayChannelPressure(
		uchar channel, uchar pressure, bigtime_t time = 0) const;

	void SprayPitchBend(
		uchar channel, uchar lsb, uchar msb, bigtime_t time = 0) const;

	void SpraySystemExclusive(
		void* data, size_t length, bigtime_t time = 0) const;

	void SpraySystemCommon(
		uchar status, uchar data1, uchar data2, bigtime_t time = 0) const;

	void SpraySystemRealTime(
		uchar status, bigtime_t time = 0) const; 

	void SprayTempoChange(
		int32 beatsPerMinute, bigtime_t time = 0) const;	
	
protected:

	~BMidiLocalProducer();
	
private:

	void SprayEvent(
		const void* data, size_t length, bool atomic, bigtime_t time,
		bool sysex = false) const;
	
	virtual void _Reserved1();
	virtual void _Reserved2();
	virtual void _Reserved3();
	virtual void _Reserved4();
	virtual void _Reserved5();
	virtual void _Reserved6();
	virtual void _Reserved7();
	virtual void _Reserved8();

	uint32 _reserved[2];		
};

#endif // _MIDI_PRODUCER_H
