#include <Bela.h>
#include <OSCServer.h>
#include <OSCClient.h>

OSCServer oscServer;
OSCClient oscClient;

// this example is designed to be run alongside resources/osc/osc.js

// parse messages recieved by OSC Server
// msg is Message class of oscpkt: http://gruntthepeon.free.fr/oscpkt/
void parseMessage(oscpkt::Message msg){
    
    rt_printf("recieved message to: %s\n", msg.addressPattern().c_str());
    
    int intArg;
    float floatArg;
    if (msg.match("/osc-test").popInt32(intArg).popFloat(floatArg).isOkNoMoreArgs()){
        rt_printf("recieved int %i and float %f\n", intArg, floatArg);
    }
    
}

bool setup(BelaContext *context, void *userData)
{
    // setup the OSC server to recieve on port 7562
    oscServer.setup(7562);
    // setup the OSC client to send on port 7563
    oscClient.setup(7563);
    
    // the following code sends an OSC message to address /osc-setup
    // then waits 1 second for a reply on /osc-setup-reply
    bool handshakeRecieved = false;
    oscClient.sendMessageNow(oscClient.newMessage.to("/osc-setup").end());
    oscServer.recieveMessageNow(1000);
    while (oscServer.messageWaiting()){
        if (oscServer.popMessage().match("/osc-setup-reply")){
            handshakeRecieved = true;
        }
    }
    
    if (handshakeRecieved){
        rt_printf("handshake recieved!\n");
    } else {
        rt_printf("timeout!\n");
    }
    
	return true;
}

void render(BelaContext *context, void *userData)
{
    // recieve OSC messages, parse them, and send back an acknowledgment
    while (oscServer.messageWaiting()){
        parseMessage(oscServer.popMessage());
        oscClient.queueMessage(oscClient.newMessage.to("/osc-acknowledge").add(5).add(4.2f).add(std::string("OSC message recieved")).end());
    }
}

void cleanup(BelaContext *context, void *userData)
{

}
