//	OSCDispatcher.h - Class to dispatch OSC note on/off events.
//  ----------------------------------------------------------------------------
//	This file is part of 'NiallsAVLib', base code for any kind of audiovisual
//	apps.
//	Copyright (C) 2012  Niall Moody
//	
//	This program is free software: you can redistribute it and/or modify
//	it under the terms of the GNU General Public License as published by
//	the Free Software Foundation, either version 3 of the License, or
//	(at your option) any later version.
//
//	This program is distributed in the hope that it will be useful,
//	but WITHOUT ANY WARRANTY; without even the implied warranty of
//	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//	GNU General Public License for more details.
//
//	You should have received a copy of the GNU General Public License
//	along with this program.  If not, see <http://www.gnu.org/licenses/>.
//	----------------------------------------------------------------------------

#ifndef OSCDISPATCHER_H_
#define OSCDISPATCHER_H_

#include "NiallsSocketLib/UDPSocket.h"

#include <stdint.h>
#include <vector>
#include <string>

///	Class to dispatch OSC note on/off events.
class OSCDispatcher
{
  public:
	///	Constructor.
	OSCDispatcher();
	///	Destructor.
	~OSCDispatcher();

	///	Called to update the dispatcher's internal counter (for sending note offs).
	/*!
		\param ticks The number of milliseconds which have elapsed since the
		program was started.
	 */
	void update(uint32_t ticks);

	///	Sets the address to send the events to.
	void setDestAddress(const std::wstring& addr);
	///	Sets the port to send the events to.
	void setDestPort(int val);

	///	Sends a note on event to the specified address.
	/*!
		\param address The OSC address to send the event to.
		\param note The MIDI note number to send.
		\param length The length of time (in seconds) to wait before sending a
		note off event.

		After length time has elapsed, the dispatcher will send a matching note
		off event.
	 */
	void sendNote(const std::wstring& address, int note, float length = 0.5f);
  private:
	///	Helper method. Sends an OSC message with the passed-in data.
	void sendMessage(const std::string& address,
					 int statusByte,
					 int dataByte0,
					 int dataByte1);

	///	Struct used to hold data for sending note offs.
	struct NoteData
	{
		///	The OSC address to send to.
		std::string address;
		///	The MIDI note value.
		int note;
		///	The time remaining (in seconds) before the note off message should be sent.
		float remainingTime;
	};

	///	The socket we use to send OSC messages.
	UDPSocket socket;

	///	Any events waiting on a note off.
	std::vector<NoteData> noteOffs;

	///	Counter used to ensure we don't send a ton of OSC messages in a single frame.
	int frameCount;
	///	Counter used to determine how much time has elapsed since the last call.
	uint32_t lastTicks;
};

#endif
