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

    OSCThread.cpp
    Created: 11 Aug 2013 9:48:42am
    Author:  Niall

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

#include "OSCThread.h"

//------------------------------------------------------------------------------
OSCThread::OSCThread(int port):
Thread("EXCOSC OSC Thread")
{
	listenSocket.setPort((int16_t)port);
	listenSocket.setAddress("127.0.0.1");
	listenSocket.bindSocket();

	startThread();
}

//------------------------------------------------------------------------------
OSCThread::~OSCThread()
{
	stopThread(1000);
}

//------------------------------------------------------------------------------
void OSCThread::run()
{
	int i;
	char *data;
	int32_t dataSize;

	while(!threadShouldExit())
	{
		if(destinations.size() > 0)
		{
			GenericScopedLock<CriticalSection> lock(critSec);

			data = listenSocket.getData(dataSize);

			if(dataSize > 0)
			{
				for(i=0;i<destinations.size();++i)
					destinations[i]->sendData(data, dataSize);
			}
		}
		else
			wait(50);
	}
}

//------------------------------------------------------------------------------
void OSCThread::setListenPort(int port)
{
	GenericScopedLock<CriticalSection> lock(critSec);

	listenSocket.setPort((int16_t)port);
	listenSocket.bindSocket();
}

//------------------------------------------------------------------------------
void OSCThread::addSendDestination(const String& address, int port)
{
	GenericScopedLock<CriticalSection> lock(critSec);

	destinations.add(new UDPSocket(address.toStdString(), (int16_t)port));
	notify();
}

//------------------------------------------------------------------------------
void OSCThread::removeSendDestination(const String& address, int port)
{
	int i;

	for(i=0;i<destinations.size();++i)
	{
		if((destinations[i]->getSendAddress() == address) &&
		   (destinations[i]->getPort() == port))
		{
			GenericScopedLock<CriticalSection> lock(critSec);

			destinations.remove(i);

			break;
		}
	}
}

//------------------------------------------------------------------------------
void OSCThread::setSendPort(int index, int port)
{
	GenericScopedLock<CriticalSection> lock(critSec);

	destinations[index]->setPort((int16_t)port);
}

//------------------------------------------------------------------------------
void OSCThread::setSendAddres(int index, const String& address)
{
	GenericScopedLock<CriticalSection> lock(critSec);

	destinations[index]->setAddress(address.toStdString());
}
