<commit_before>//
//  ofxRemoteUI.cpp
//  emptyExample
//
//  Created by <NAME> on 09/01/13.
//
//

#include "ofxRemoteUI.h"
#include <iostream>
#include <stdlib.h>
#include "uriencode.h"
#include <sstream>

#if !defined(__APPLE__) && !defined(TARGET_WIN32)
    #ifndef __linux__
        #define __linux__
    #endif
#endif

#if defined(__APPLE__) || defined(__linux__)
#include <arpa/inet.h>
#include <net/if.h>
#include <ifaddrs.h>
#endif

#ifdef TARGET_WIN32
#include <windows.h>
#include <iphlpapi.h>
#include <WinSock2.h>
#pragma comment(lib, "iphlpapi.lib")
#endif

void split(vector<string> &tokens, const string &text, char separator) {
	unsigned long start = 0, end = 0;
	while ((end = text.find(separator, start)) != string::npos) {
		tokens.push_back(text.substr(start, end - start));
		start = end + 1;
	}
	tokens.push_back(text.substr(start));
}


bool ofxRemoteUI::ready(){
	return readyToSend;
}

void ofxRemoteUI::setVerbose(bool b){
	verbose_ = b;
}


float ofxRemoteUI::connectionLag(){
	return avgTimeSinceLastReply;
}


vector<string> ofxRemoteUI::getPresetsList(){
	return presetNames;
}


void ofxRemoteUI::printAllParamsDebug(){
	if(orderedKeys.size() == 0) return;
	cout << "#### FULL PARAM LIST ################################" << endl;
	for(int i = 0; i < orderedKeys.size(); i++){
		string key = orderedKeys[i];
		RemoteUIParam thisP = params[key];
		cout << "   index: " << i << "  list: " << key << " > "; thisP.print();
	}
	cout << "####################################################" << endl;
}

void ofxRemoteUI::addParamToDB(RemoteUIParam p, string thisParamName){

	//see if we already had it, if we didnt, set its add order #
	unordered_map<string, RemoteUIParam>::iterator it = params.find(thisParamName);
	if ( it == params.end() ){	//not found!

		params[thisParamName] = p;
		orderedKeys[ (int)orderedKeys.size() ] = thisParamName;
		paramsFromCode[thisParamName] = p; //cos this didnt exist before, we store it as "from code"

	}else{
		params[thisParamName] = p;
		RUI_LOG_WARNING << "already have a Param with that name on the DB : " << thisParamName << "!!";
	}
}


void ofxRemoteUI::clearOscReceiverMsgQueue(){
	ofxOscMessage tempM;
	//int c = 0;
	//delete all pending messages
	while (oscReceiver.getNextMessage(&tempM)) {
		//cout << "clearOscReceiverMsgQueue " << c << endl;
		//c++;
	}
}


vector<string> ofxRemoteUI::getChangedParamsList(){
	std::vector<string> result (paramsChangedSinceLastCheck.begin(), paramsChangedSinceLastCheck.end());
	paramsChangedSinceLastCheck.clear();
	return result;
}


DecodedMessage ofxRemoteUI::decode(ofxOscMessage m){

	string msgAddress = m.getAddress();
	string action = msgAddress.substr(0, 4);

	//cout <<"Decode: "<< msgAddress << " action >> " << action << endl;
	DecodedMessage dm;

	//this is the lazynes maximus!
	if (msgAddress.length() >= 3) {
		if (action == "HELO") dm.action = HELO_ACTION;
		else if (action == "REQU") dm.action = REQUEST_ACTION;
		else if (action == "SEND") dm.action = SEND_PARAM_ACTION;
		else if (action == "CIAO") dm.action = CIAO_ACTION;
		else if (action == "TEST") dm.action = TEST_ACTION;
		else if (action == "PREL") dm.action = PRESET_LIST_ACTION;
		else if (action == "DELP") dm.action = DELETE_PRESET_ACTION;
		else if (action == "SAVP") dm.action = SAVE_PRESET_ACTION;
		else if (action == "SETP") dm.action = SET_PRESET_ACTION;
		else if (action == "RESX") dm.action = RESET_TO_XML_ACTION;
		else if (action == "RESD") dm.action = RESET_TO_DEFAULTS_ACTION;
		else if (action == "SAVE") dm.action = SAVE_CURRENT_STATE_ACTION;
		else if (action == "MISP") dm.action = GET_MISSING_PARAMS_IN_PRESET;
		//groups (note lower case p, l)
		else if (action == "DELp") dm.action = DELETE_GROUP_PRESET_ACTION;
		else if (action == "SAVp") dm.action = SAVE_GROUP_PRESET_ACTION;
		else if (action == "SETp") dm.action = SET_GROUP_PRESET_ACTION;
		else if (action == "LOG_") dm.action = SEND_LOG_LINE_ACTION;
	}

	if (msgAddress.length() >= 8) {
		string arg1 = msgAddress.substr(5, 3);
		//cout << "Decode"  << msgAddress << " arg1 >> " << arg1 << endl;
		dm.argument = NULL_ARG;

		if (arg1 == "FLT") dm.argument = FLT_ARG;
		else if (arg1 == "INT") dm.argument = INT_ARG;
		else if (arg1 == "BOL") dm.argument = BOL_ARG;
		else if (arg1 == "STR") dm.argument = STR_ARG;
		else if (arg1 == "ENU") dm.argument = ENUM_ARG;
		else if (arg1 == "COL") dm.argument = COLOR_ARG;
		else if (arg1 == "SPA") dm.argument = SPACER_ARG;
	}else{
		//must be a LOG_ action
	}

	if (msgAddress.length() >= 9) {
		string paramName = msgAddress.substr(9, msgAddress.length() - 9);
		dm.paramName = paramName;
	}else{
		//must be a LOG_ action
	}

	return dm;
}


string ofxRemoteUI::getMyIP(string userChosenInteface){

	//from https://github.com/jvcleave/LocalAddressGrabber/blob/master/src/LocalAddressGrabber.h
	//and http://stackoverflow.com/questions/17288908/get-network-interface-name-from-ipv4-address
	string output = RUI_LOCAL_IP_ADDRESS;
	RUI_LOG_NOTICE << "establishing local interface and IP @";

#if defined(__APPLE__) || defined(__linux__)
	struct ifaddrs *myaddrs;
	struct ifaddrs *ifa;
	struct sockaddr_in *s4;
	int status;
	char buf[64];

	status = getifaddrs(&myaddrs);
	if (status != 0){
		perror("getifaddrs");
	}

	for (ifa = myaddrs; ifa != NULL; ifa = ifa->ifa_next){
		if (ifa->ifa_addr == NULL) continue;
		if ((ifa->ifa_flags & IFF_UP) == 0) continue;

		if (ifa->ifa_addr->sa_family == AF_INET){
			s4 = (struct sockaddr_in *)(ifa->ifa_addr);
			if (inet_ntop(ifa->ifa_addr->sa_family, (void *)&(s4->sin_addr), buf, sizeof(buf)) == NULL){
				printf("%s: inet_ntop failed!\n", ifa->ifa_name);
			}else{
				string interface = string(ifa->ifa_name);
				if(verbose_) RUI_LOG_VERBOSE << "found interface: " << interface ;
				if( interface.length() > 2 || interface == userSuppliedNetInterface ){
					if (userSuppliedNetInterface.length() > 0){
						if (interface == userSuppliedNetInterface){
							output = string(buf);
							if(verbose_) RUI_LOG_VERBOSE << "using user chosen interface: " << interface;
							break;
						}
					}else{
                        if ((interface[0] == 'e' && interface[1] == 'n') || (interface[0] == 'e' && interface[1] == 't')){
							if(strlen(buf) > 2){
								bool is169 = buf[0] == '1' && buf[1] == '6' && buf[2] == '9';
								if(!is169){ //avoid 169.x.x.x addresses
									output = string(buf);
									if(verbose_) RUI_LOG_VERBOSE << "using interface: " << interface;
									break;
								}
							}
						}
					}
				}
			}
		}
	}
	freeifaddrs(myaddrs);
	if (userSuppliedNetInterface.length() > 0){
		if (output == RUI_LOCAL_IP_ADDRESS){
			RUI_LOG_ERROR << "could not find the user supplied net interface: " << userSuppliedNetInterface;
			RUI_LOG_ERROR << "automatic advertising will not work! ";
		}
	}
#endif

#ifdef TARGET_WIN32
	ULONG buflen = sizeof(IP_ADAPTER_INFO);
	IP_ADAPTER_INFO *pAdapterInfo = (IP_ADAPTER_INFO *)malloc(buflen);

	if (GetAdaptersInfo(pAdapterInfo, &buflen) == ERROR_BUFFER_OVERFLOW) {
		free(pAdapterInfo);
		pAdapterInfo = (IP_ADAPTER_INFO *)malloc(buflen);
	}

	if (GetAdaptersInfo(pAdapterInfo, &buflen) == NO_ERROR) {
		//this is crappy, we get the first non 0.0.0.0 interface (no idea which order they come in) TODO!
		for (IP_ADAPTER_INFO *pAdapter = pAdapterInfo; pAdapter; pAdapter = pAdapter->Next) {
			printf("%s (%s)\n", pAdapter->IpAddressList.IpAddress.String, pAdapter->Description);
			string ip = pAdapter->IpAddressList.IpAddress.String;
			if (ip != "0.0.0.0"){
				output = ip;
				break;
			}
		}
	}
	if (pAdapterInfo) free(pAdapterInfo);
#endif
	return output;
}

#ifdef TARGET_WIN32
void GetHostName(std::string& host_name){
    WSAData wsa_data;
    int ret_code;
    char buf[MAX_PATH];
    WSAStartup(MAKEWORD(1, 1), &wsa_data);
    ret_code = gethostname(buf, MAX_PATH);

    if (ret_code == SOCKET_ERROR)
    	host_name = RUI_LOCAL_IP_ADDRESS;
	else
		host_name = buf;
    WSACleanup();
}
#endif

void ofxRemoteUI::updateParamFromDecodedMessage(ofxOscMessage m, DecodedMessage dm){

	string paramName = dm.paramName;
	RemoteUIParam original;
	bool newParam = true;
	unordered_map<string, RemoteUIParam>::iterator it = params.find(paramName);
	if ( it != params.end() ){	//found the param, we already had it
		original = params[paramName];
		newParam = false;
	}

	RemoteUIParam p = original;
	int arg = 0;

	switch (dm.argument) {
		case FLT_ARG:
			p.type = REMOTEUI_PARAM_FLOAT;
 			p.floatVal = m.getArgAsFloat(arg); arg++;
			p.minFloat = m.getArgAsFloat(arg); arg++;
			p.maxFloat = m.getArgAsFloat(arg); arg++;
			if (p.floatValAddr){
				*p.floatValAddr = p.floatVal;
			}break;

		case INT_ARG:
			p.type = REMOTEUI_PARAM_INT;
			p.intVal = m.getArgAsInt32(arg); arg++;
			p.minInt = m.getArgAsInt32(arg); arg++;
			p.maxInt = m.getArgAsInt32(arg); arg++;
			if (p.intValAddr){
				*p.intValAddr = p.intVal;
			}break;

		case COLOR_ARG:
			p.type = REMOTEUI_PARAM_COLOR;
			p.redVal = (int)m.getArgAsInt32(arg); arg++;
			p.greenVal = (int)m.getArgAsInt32(arg); arg++;
			p.blueVal = (int)m.getArgAsInt32(arg); arg++;
			p.alphaVal = (int)m.getArgAsInt32(arg); arg++;
			if (p.redValAddr){
				*p.redValAddr = p.redVal;
				*(p.redValAddr+1) = p.greenVal;
				*(p.redValAddr+2) = p.blueVal;
				*(p.redValAddr+3) = p.alphaVal;
			}break;

		case ENUM_ARG:{
			p.type = REMOTEUI_PARAM_ENUM;
			p.intVal = m.getArgAsInt32(arg); arg++;
			p.minInt = m.getArgAsInt32(arg); arg++;
			p.maxInt = m.getArgAsInt32(arg); arg++;
			if (p.intValAddr){
				*p.intValAddr = p.intVal;
			}
			int n = m.getNumArgs() - 5 - 3; // 3 >> the int vals, 5 >> 4 colors + 1 group
			int i = 0;
			p.enumList.clear();
			for (i = 0; i < n; i++) {
				p.enumList.push_back( m.getArgAsString(arg + i) );
			}
			arg = arg + i;
		}break;

		case BOL_ARG:
			p.type = REMOTEUI_PARAM_BOOL;
			p.boolVal = m.getArgAsInt32(arg) == 0 ? false : true; arg++;
			if (p.boolValAddr){
				*p.boolValAddr = p.boolVal;
			}break;

		case STR_ARG:
			p.type = REMOTEUI_PARAM_STRING;
			p.stringVal = m.getArgAsString(arg); arg++;
			if (p.stringValAddr){
				*p.stringValAddr = p.stringVal;
			}break;

		case SPACER_ARG:
			p.type = REMOTEUI_PARAM_SPACER;
			p.stringVal = m.getArgAsString(arg); arg++;
			break;


		case NULL_ARG: RUI_LOG_ERROR << "updateParamFromDecodedMessage NULL type!"; break;
		default: RUI_LOG_ERROR << "updateParamFromDecodedMessage unknown type!"; break;
	}

	p.r = m.getArgAsInt32(arg); arg++;
	p.g = m.getArgAsInt32(arg); arg++;
	p.b = m.getArgAsInt32(arg); arg++;
	p.a = m.getArgAsInt32(arg); arg++;
	p.group = m.getArgAsString(arg); arg++;

	if ( !p.isEqualTo(original)  || newParam ){ // if the udpdate changed the param, keep track of it
		paramsChangedSinceLastCheck.insert(paramName);
	}

	//here we update our param db
	//params[paramName] = p;
	if(newParam)
		addParamToDB(p, paramName);
	else
		params[paramName] = p;
}



vector<string> ofxRemoteUI::getAllParamNamesList(){

	vector<string>paramsList;
	//get list of params in add order
	for( map<int,string>::iterator ii = orderedKeys.begin(); ii != orderedKeys.end(); ++ii ){
		string paramName = (*ii).second;
		paramsList.push_back(paramName);<commit_msg>changes to add basic TouchOSC compatibility<commit_after>//
//  ofxRemoteUI.cpp
//  emptyExample
//
//  Created by <NAME> on 09/01/13.
//
//

#include "ofxRemoteUI.h"
#include <iostream>
#include <stdlib.h>
#include "uriencode.h"
#include <sstream>

#if !defined(__APPLE__) && !defined(TARGET_WIN32)
    #ifndef __linux__
        #define __linux__
    #endif
#endif

#if defined(__APPLE__) || defined(__linux__)
#include <arpa/inet.h>
#include <net/if.h>
#include <ifaddrs.h>
#endif

#ifdef TARGET_WIN32
#include <windows.h>
#include <iphlpapi.h>
#include <WinSock2.h>
#pragma comment(lib, "iphlpapi.lib")
#endif

void split(vector<string> &tokens, const string &text, char separator) {
	unsigned long start = 0, end = 0;
	while ((end = text.find(separator, start)) != string::npos) {
		tokens.push_back(text.substr(start, end - start));
		start = end + 1;
	}
	tokens.push_back(text.substr(start));
}


bool ofxRemoteUI::ready(){
	return readyToSend;
}

void ofxRemoteUI::setVerbose(bool b){
	verbose_ = b;
}


float ofxRemoteUI::connectionLag(){
	return avgTimeSinceLastReply;
}


vector<string> ofxRemoteUI::getPresetsList(){
	return presetNames;
}


void ofxRemoteUI::printAllParamsDebug(){
	if(orderedKeys.size() == 0) return;
	cout << "#### FULL PARAM LIST ################################" << endl;
	for(int i = 0; i < orderedKeys.size(); i++){
		string key = orderedKeys[i];
		RemoteUIParam thisP = params[key];
		cout << "   index: " << i << "  list: " << key << " > "; thisP.print();
	}
	cout << "####################################################" << endl;
}

void ofxRemoteUI::addParamToDB(RemoteUIParam p, string thisParamName){

	//see if we already had it, if we didnt, set its add order #
	unordered_map<string, RemoteUIParam>::iterator it = params.find(thisParamName);
	if ( it == params.end() ){	//not found!

		params[thisParamName] = p;
		orderedKeys[ (int)orderedKeys.size() ] = thisParamName;
		paramsFromCode[thisParamName] = p; //cos this didnt exist before, we store it as "from code"

	}else{
		params[thisParamName] = p;
		RUI_LOG_WARNING << "already have a Param with that name on the DB : " << thisParamName << "!!";
	}
}


void ofxRemoteUI::clearOscReceiverMsgQueue(){
	ofxOscMessage tempM;
	//int c = 0;
	//delete all pending messages
	while (oscReceiver.getNextMessage(&tempM)) {
		//cout << "clearOscReceiverMsgQueue " << c << endl;
		//c++;
	}
}


vector<string> ofxRemoteUI::getChangedParamsList(){
	std::vector<string> result (paramsChangedSinceLastCheck.begin(), paramsChangedSinceLastCheck.end());
	paramsChangedSinceLastCheck.clear();
	return result;
}


DecodedMessage ofxRemoteUI::decode(ofxOscMessage m){

	string msgAddress = m.getAddress();
	if(msgAddress.size() > 0){
		if(msgAddress[0] == '/'){
			msgAddress = msgAddress.substr(1, msgAddress.size() - 1);
		}
	}
	string action = msgAddress.substr(0, 4);

	//cout <<"Decode: "<< msgAddress << " action >> " << action << endl;
	DecodedMessage dm;

	//this is the lazynes maximus!
	if (msgAddress.length() >= 3) {
		if (action == "HELO") dm.action = HELO_ACTION;
		else if (action == "REQU") dm.action = REQUEST_ACTION;
		else if (action == "SEND") dm.action = SEND_PARAM_ACTION;
		else if (action == "CIAO") dm.action = CIAO_ACTION;
		else if (action == "TEST") dm.action = TEST_ACTION;
		else if (action == "PREL") dm.action = PRESET_LIST_ACTION;
		else if (action == "DELP") dm.action = DELETE_PRESET_ACTION;
		else if (action == "SAVP") dm.action = SAVE_PRESET_ACTION;
		else if (action == "SETP") dm.action = SET_PRESET_ACTION;
		else if (action == "RESX") dm.action = RESET_TO_XML_ACTION;
		else if (action == "RESD") dm.action = RESET_TO_DEFAULTS_ACTION;
		else if (action == "SAVE") dm.action = SAVE_CURRENT_STATE_ACTION;
		else if (action == "MISP") dm.action = GET_MISSING_PARAMS_IN_PRESET;
		//groups (note lower case p, l)
		else if (action == "DELp") dm.action = DELETE_GROUP_PRESET_ACTION;
		else if (action == "SAVp") dm.action = SAVE_GROUP_PRESET_ACTION;
		else if (action == "SETp") dm.action = SET_GROUP_PRESET_ACTION;
		else if (action == "LOG_") dm.action = SEND_LOG_LINE_ACTION;
	}

	if (msgAddress.length() >= 8) {
		string arg1 = msgAddress.substr(5, 3);
		//cout << "Decode"  << msgAddress << " arg1 >> " << arg1 << endl;
		dm.argument = NULL_ARG;

		if (arg1 == "FLT") dm.argument = FLT_ARG;
		else if (arg1 == "INT") dm.argument = INT_ARG;
		else if (arg1 == "BOL") dm.argument = BOL_ARG;
		else if (arg1 == "STR") dm.argument = STR_ARG;
		else if (arg1 == "ENU") dm.argument = ENUM_ARG;
		else if (arg1 == "COL") dm.argument = COLOR_ARG;
		else if (arg1 == "SPA") dm.argument = SPACER_ARG;
	}else{
		//must be a LOG_ action
	}

	if (msgAddress.length() >= 9) {
		string paramName = msgAddress.substr(9, msgAddress.length() - 9);
		dm.paramName = paramName;
	}else{
		//must be a LOG_ action
	}

	return dm;
}


string ofxRemoteUI::getMyIP(string userChosenInteface){

	//from https://github.com/jvcleave/LocalAddressGrabber/blob/master/src/LocalAddressGrabber.h
	//and http://stackoverflow.com/questions/17288908/get-network-interface-name-from-ipv4-address
	string output = RUI_LOCAL_IP_ADDRESS;
	RUI_LOG_NOTICE << "establishing local interface and IP @";

#if defined(__APPLE__) || defined(__linux__)
	struct ifaddrs *myaddrs;
	struct ifaddrs *ifa;
	struct sockaddr_in *s4;
	int status;
	char buf[64];

	status = getifaddrs(&myaddrs);
	if (status != 0){
		perror("getifaddrs");
	}

	for (ifa = myaddrs; ifa != NULL; ifa = ifa->ifa_next){
		if (ifa->ifa_addr == NULL) continue;
		if ((ifa->ifa_flags & IFF_UP) == 0) continue;

		if (ifa->ifa_addr->sa_family == AF_INET){
			s4 = (struct sockaddr_in *)(ifa->ifa_addr);
			if (inet_ntop(ifa->ifa_addr->sa_family, (void *)&(s4->sin_addr), buf, sizeof(buf)) == NULL){
				printf("%s: inet_ntop failed!\n", ifa->ifa_name);
			}else{
				string interface = string(ifa->ifa_name);
				if(verbose_) RUI_LOG_VERBOSE << "found interface: " << interface ;
				if( interface.length() > 2 || interface == userSuppliedNetInterface ){
					if (userSuppliedNetInterface.length() > 0){
						if (interface == userSuppliedNetInterface){
							output = string(buf);
							if(verbose_) RUI_LOG_VERBOSE << "using user chosen interface: " << interface;
							break;
						}
					}else{
                        if ((interface[0] == 'e' && interface[1] == 'n') || (interface[0] == 'e' && interface[1] == 't')){
							if(strlen(buf) > 2){
								bool is169 = buf[0] == '1' && buf[1] == '6' && buf[2] == '9';
								if(!is169){ //avoid 169.x.x.x addresses
									output = string(buf);
									if(verbose_) RUI_LOG_VERBOSE << "using interface: " << interface;
									break;
								}
							}
						}
					}
				}
			}
		}
	}
	freeifaddrs(myaddrs);
	if (userSuppliedNetInterface.length() > 0){
		if (output == RUI_LOCAL_IP_ADDRESS){
			RUI_LOG_ERROR << "could not find the user supplied net interface: " << userSuppliedNetInterface;
			RUI_LOG_ERROR << "automatic advertising will not work! ";
		}
	}
#endif

#ifdef TARGET_WIN32
	ULONG buflen = sizeof(IP_ADAPTER_INFO);
	IP_ADAPTER_INFO *pAdapterInfo = (IP_ADAPTER_INFO *)malloc(buflen);

	if (GetAdaptersInfo(pAdapterInfo, &buflen) == ERROR_BUFFER_OVERFLOW) {
		free(pAdapterInfo);
		pAdapterInfo = (IP_ADAPTER_INFO *)malloc(buflen);
	}

	if (GetAdaptersInfo(pAdapterInfo, &buflen) == NO_ERROR) {
		//this is crappy, we get the first non 0.0.0.0 interface (no idea which order they come in) TODO!
		for (IP_ADAPTER_INFO *pAdapter = pAdapterInfo; pAdapter; pAdapter = pAdapter->Next) {
			printf("%s (%s)\n", pAdapter->IpAddressList.IpAddress.String, pAdapter->Description);
			string ip = pAdapter->IpAddressList.IpAddress.String;
			if (ip != "0.0.0.0"){
				output = ip;
				break;
			}
		}
	}
	if (pAdapterInfo) free(pAdapterInfo);
#endif
	return output;
}

#ifdef TARGET_WIN32
void GetHostName(std::string& host_name){
    WSAData wsa_data;
    int ret_code;
    char buf[MAX_PATH];
    WSAStartup(MAKEWORD(1, 1), &wsa_data);
    ret_code = gethostname(buf, MAX_PATH);

    if (ret_code == SOCKET_ERROR)
    	host_name = RUI_LOCAL_IP_ADDRESS;
	else
		host_name = buf;
    WSACleanup();
}
#endif

void ofxRemoteUI::updateParamFromDecodedMessage(ofxOscMessage m, DecodedMessage dm){

	string paramName = dm.paramName;
	RemoteUIParam original;
	bool newParam = true;
	unordered_map<string, RemoteUIParam>::iterator it = params.find(paramName);
	if ( it != params.end() ){	//found the param, we already had it
		original = params[paramName];
		newParam = false;
	}

	RemoteUIParam p = original;
	int arg = 0;

	switch (dm.argument) {
		case FLT_ARG:
			p.type = REMOTEUI_PARAM_FLOAT;
 			p.floatVal = m.getArgAsFloat(arg); arg++;
			if(m.getNumArgs() > 1){
				p.minFloat = m.getArgAsFloat(arg); arg++;
				p.maxFloat = m.getArgAsFloat(arg); arg++;
			}
			if (p.floatValAddr){
				*p.floatValAddr = p.floatVal;
			}break;

		case INT_ARG:
			p.type = REMOTEUI_PARAM_INT;
			p.intVal = m.getArgAsInt32(arg); arg++;
			p.minInt = m.getArgAsInt32(arg); arg++;
			p.maxInt = m.getArgAsInt32(arg); arg++;
			if (p.intValAddr){
				*p.intValAddr = p.intVal;
			}break;

		case COLOR_ARG:
			p.type = REMOTEUI_PARAM_COLOR;
			p.redVal = (int)m.getArgAsInt32(arg); arg++;
			p.greenVal = (int)m.getArgAsInt32(arg); arg++;
			p.blueVal = (int)m.getArgAsInt32(arg); arg++;
			p.alphaVal = (int)m.getArgAsInt32(arg); arg++;
			if (p.redValAddr){
				*p.redValAddr = p.redVal;
				*(p.redValAddr+1) = p.greenVal;
				*(p.redValAddr+2) = p.blueVal;
				*(p.redValAddr+3) = p.alphaVal;
			}break;

		case ENUM_ARG:{
			p.type = REMOTEUI_PARAM_ENUM;
			p.intVal = m.getArgAsInt32(arg); arg++;
			p.minInt = m.getArgAsInt32(arg); arg++;
			p.maxInt = m.getArgAsInt32(arg); arg++;
			if (p.intValAddr){
				*p.intValAddr = p.intVal;
			}
			int n = m.getNumArgs() - 5 - 3; // 3 >> the int vals, 5 >> 4 colors + 1 group
			int i = 0;
			p.enumList.clear();
			for (i = 0; i < n; i++) {
				p.enumList.push_back( m.getArgAsString(arg + i) );
			}
			arg = arg + i;
		}break;

		case BOL_ARG:
			p.type = REMOTEUI_PARAM_BOOL;
			p.boolVal = m.getArgAsInt32(arg) == 0 ? false : true; arg++;
			if (p.boolValAddr){
				*p.boolValAddr = p.boolVal;
			}break;

		case STR_ARG:
			p.type = REMOTEUI_PARAM_STRING;
			p.stringVal = m.getArgAsString(arg); arg++;
			if (p.stringValAddr){
				*p.stringValAddr = p.stringVal;
			}break;

		case SPACER_ARG:
			p.type = REMOTEUI_PARAM_SPACER;
			p.stringVal = m.getArgAsString(arg); arg++;
			break;


		case NULL_ARG: RUI_LOG_ERROR << "updateParamFromDecodedMessage NULL type!"; break;
		default: RUI_LOG_ERROR << "updateParamFromDecodedMessage unknown type!"; break;
	}

	if(m.getNumArgs() > 1){
		p.r = m.getArgAsInt32(arg); arg++;
		p.g = m.getArgAsInt32(arg); arg++;
		p.b = m.getArgAsInt32(arg); arg++;
		p.a = m.getArgAsInt32(arg); arg++;
		p.group = m.getArgAsString(arg); arg++;
	}

	if ( !p.isEqualTo(original)  || newParam ){ // if the udpdate changed the param, keep track of it
		paramsChangedSinceLastCheck.insert(paramName);
	}

	//here we update our param db
	//params[paramName] = p;
	if(newParam)
		addParamToDB(p, paramName);
	else
		params[paramName] = p;
}



vector<string> ofxRemoteUI::getAllParamNamesList(){

	vector<string>paramsList;
	//get list of params in add order
	for( map<int,string>::iterator ii = orderedKeys.begin(); ii != orderedKeys.end(); ++ii ){
		string paramName = (*ii).second;
		paramsList.push_back(paramName);
{'fraction_non_alphanumeric': 0.1633476737481705, 'fraction_numerical': 0.0119749855856655, 'mean_word_length': 3.919921448832642, 'pattern_counts': {'":': 0, '<': 193, '<?xml version=': 0, '>': 106, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 4, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4583774', 'n_tokens_mistral': 9408, 'n_tokens_neox': 8408, 'n_words': 1883}