char *daemon_render_node_to_json(struct razer_fx_render_node *render_node)
{
	char *rn_json = str_CreateEmpty();
	rn_json = str_CatFree(rn_json,"\n {\n");
	rn_json = str_CatFree(rn_json," \"id\" : ");
	char *id_string = str_FromLong(render_node->id);
	rn_json = str_CatFree(rn_json,id_string);
	rn_json = str_CatFree(rn_json," ,\n");
	free(id_string);
	rn_json = str_CatFree(rn_json," \"name\": \"");
	rn_json = str_CatFree(rn_json,render_node->name);
	rn_json = str_CatFree(rn_json,"\" ,\ndescription\": \"");
	rn_json = str_CatFree(rn_json,render_node->description);
	/*effect_json = str_CatFree(effect_json,"\" ,\n \"subs_num\" : ");
	char *parameters_num_string = str_FromLong(effect->parameters->num);
	effect_json = str_CatFree(effect_json,parameters_num_string);
	effect_json = str_CatFree(effect_json," ,\n");
	free(parameters_num_string);
	effect_json = str_CatFree(effect_json," \"parameters\" :  [\n");
	for(int i = 0;i<effect->parameters->num;i++)
	{
		struct razer_parameter *parameter = effect->parameters->items[i];
		char *parameter_json = daemon_parameter_to_json(parameter);
		effect_json = str_CatFree(effect_json,parameter_json);
		free(parameter_json);
	}*/
	rn_json = str_CatFree(rn_json,"\"\n },\n");
	return(rn_json);
}
struct razer_chroma *razer_open(void)
{
	struct razer_chroma *chroma =(struct razer_chroma*)malloc(sizeof(struct razer_chroma));
	#ifdef USE_DEBUGGING
		printf("opening chroma lib\n");
	#endif
	chroma->sys_mouse_event_path = str_Copy(razer_sys_mouse_event_default_path);
	chroma->sys_keyboard_event_path = str_Copy(razer_sys_keyboard_event_default_path);
	chroma->custom_mode_file = NULL;
	chroma->update_keys_file = NULL;
	chroma->keyboard_input_file = 0;
	chroma->mouse_input_file = 0;
	chroma->device_path = razer_get_device_path();
	if(!chroma->device_path)
	{
		#ifdef USE_DEBUGGING
			printf("error no compatible device found\n");
		#endif
		return(NULL);
	}
	#ifdef USE_VERBOSE_DEBUGGING
		printf("found device at path:%s\n",chroma->device_path);
	#endif

	chroma->keys = (struct razer_keys*)malloc(sizeof(struct razer_keys));
	razer_init_keys(chroma->keys);
	chroma->custom_mode_filename = str_CreateEmpty();
	chroma->custom_mode_filename = str_CatFree(chroma->custom_mode_filename,chroma->device_path);
	chroma->custom_mode_filename = str_CatFree(chroma->custom_mode_filename,razer_custom_mode_pathname);

	chroma->update_keys_filename = str_CreateEmpty();
	chroma->update_keys_filename = str_CatFree(chroma->update_keys_filename,chroma->device_path);
	chroma->update_keys_filename = str_CatFree(chroma->update_keys_filename,razer_update_keys_pathname);
	
	chroma->input_handler = NULL;
	chroma->last_key_pos.x = -1;
	chroma->last_key_pos.y = -1;
	chroma->key_pos.x = -1;
	chroma->key_pos.y = -1;
	return(chroma);
}
void dc_render_node_sub_add(struct razer_daemon_controller *controller,int render_node_uid,int sub_render_node_uid)
{
	DBusMessage *msg;
	DBusMessageIter args;
	char *path = str_CreateEmpty();
	path = str_CatFree(path,"/");
	char *suid = str_FromLong(render_node_uid);
	path = str_CatFree(path,suid);
	free(suid);
	msg = dbus_message_new_method_call("org.voyagerproject.razer.daemon",path,"org.voyagerproject.razer.daemon.render_node.sub","add");
	if(!msg)
		dc_error_close(controller,"Error creating Message\n");
	dbus_message_iter_init_append(msg,&args);
	if(!dbus_message_iter_append_basic(&args,DBUS_TYPE_INT32,&sub_render_node_uid))
		dc_error_close(controller,"Out of memory!\n"); 
	if(!dbus_connection_send_with_reply(controller->dbus,msg,&controller->pending,-1))
		dc_error_close(controller,"Out of memory!\n"); 
	if(!controller->pending)
		dc_error_close(controller,"No pending call\n"); 
	dbus_connection_flush(controller->dbus);
	dbus_message_unref(msg);
	free(path);
}
int dc_render_node_parent_get(struct razer_daemon_controller *controller,int render_node_uid)
{
	DBusMessage *msg;
	DBusMessageIter args;
	char *path = str_CreateEmpty();
	path = str_CatFree(path,"/");
	char *suid = str_FromLong(render_node_uid);
	path = str_CatFree(path,suid);
	free(suid);
	msg = dbus_message_new_method_call("org.voyagerproject.razer.daemon",path,"org.voyagerproject.razer.daemon.render_node.parent","get");
	if(!msg)
		dc_error_close(controller,"Error creating Message\n");
	if(!dbus_connection_send_with_reply(controller->dbus,msg,&controller->pending,-1))
		dc_error_close(controller,"Out of memory!\n"); 
	if(!controller->pending)
		dc_error_close(controller,"No pending call\n"); 
	dbus_connection_flush(controller->dbus);
	dbus_message_unref(msg);

	int parent_uid = -1;

	dbus_pending_call_block(controller->pending);
	msg = dbus_pending_call_steal_reply(controller->pending);
	if(!msg)
		dc_error_close(controller,"Empty reply\n"); 
	dbus_pending_call_unref(controller->pending);
	if(!dbus_message_iter_init(msg,&args))
		dc_error_close(controller,"Message has no arguments!\n"); 
	else if(dbus_message_iter_get_arg_type(&args) != DBUS_TYPE_INT32) 
		dc_error_close(controller,"Argument is not an int!\n"); 
	else
		dbus_message_iter_get_basic(&args,&parent_uid);
	dbus_message_unref(msg);   
	free(path);//TODO gets not freed on error
	return(parent_uid);
}
void dc_render_node_opacity_set(struct razer_daemon_controller *controller,int render_node_uid,float opacity)
{
	DBusMessage *msg;
	DBusMessageIter args;
	char *path = str_CreateEmpty();
	path = str_CatFree(path,"/");
	char *suid = str_FromLong(render_node_uid);
	path = str_CatFree(path,suid);
	free(suid);
	double opc = (double)opacity;
	msg = dbus_message_new_method_call("org.voyagerproject.razer.daemon",path,"org.voyagerproject.razer.daemon.render_node.opacity","set");
	if(!msg)
		dc_error_close(controller,"Error creating Message\n");
	dbus_message_iter_init_append(msg,&args);
	if(!dbus_message_iter_append_basic(&args,DBUS_TYPE_DOUBLE,&opc))
		dc_error_close(controller,"Out of memory!\n"); 
	if(!dbus_connection_send_with_reply(controller->dbus,msg,&controller->pending,-1))
		dc_error_close(controller,"Out of memory!\n"); 
	if(!controller->pending)
		dc_error_close(controller,"No pending call\n"); 
	dbus_connection_flush(controller->dbus);
	dbus_message_unref(msg);
	free(path);//TODO gets not freed on error
}
		case RAZER_PARAMETER_TYPE_RGB_ARRAY:
			return("RGB Array");
		case RAZER_PARAMETER_TYPE_POS_ARRAY:
			return("Position Array");
		default:
			return("Unknown Type");
	}
}




char *daemon_parameter_to_json(struct razer_parameter *parameter, int final)
{
	char *parameter_json = str_CreateEmpty();
	parameter_json = str_CatFree(parameter_json,"{\n \"key\": \"");
	parameter_json = str_CatFree(parameter_json,parameter->key);
	parameter_json = str_CatFree(parameter_json,"\",\n");
	parameter_json = str_CatFree(parameter_json," \"id\" : ");
	char *id_string = str_FromLong(parameter->id);
	parameter_json = str_CatFree(parameter_json,id_string);
	parameter_json = str_CatFree(parameter_json," ,\n");
	free(id_string);
	parameter_json = str_CatFree(parameter_json," \"type\" : \"");
	//char *type_string = str_FromLong(parameter->type);
	//parameter_json = str_CatFree(parameter_json,type_string);
	parameter_json = str_CatFree(parameter_json,daemon_parameter_type_to_string(parameter));
	parameter_json = str_CatFree(parameter_json,"\" ,\n");
	//free(type_string);
	parameter_json = str_CatFree(parameter_json," \"private\" : ");
	if(parameter->private)
char *daemon_parameter_to_json(struct razer_parameter *parameter)
{
	char *parameter_json = str_CreateEmpty();
	parameter_json = str_CatFree(parameter_json,"{\n \"key\": \"");
	parameter_json = str_CatFree(parameter_json,parameter->key);
	parameter_json = str_CatFree(parameter_json,"\",\n");
	parameter_json = str_CatFree(parameter_json," \"id\" : ");
	char *id_string = str_FromLong(parameter->id);
	parameter_json = str_CatFree(parameter_json,id_string);
	parameter_json = str_CatFree(parameter_json," ,\n");
	free(id_string);
	parameter_json = str_CatFree(parameter_json," \"type\" : ");
	char *type_string = str_FromLong(parameter->type);
	parameter_json = str_CatFree(parameter_json,type_string);
	parameter_json = str_CatFree(parameter_json," ,\n");
	free(type_string);
	parameter_json = str_CatFree(parameter_json," \"value\" : ");
	switch(parameter->type)
	{
		case RAZER_PARAMETER_TYPE_STRING:
			{
				parameter_json = str_CatFree(parameter_json,"\"");
				parameter_json = str_CatFree(parameter_json,daemon_get_parameter_string(parameter));
				parameter_json = str_CatFree(parameter_json,"\" ,\n");
			}
			break;
		case RAZER_PARAMETER_TYPE_INT:
			{
				char *int_string = str_FromLong(daemon_get_parameter_int(parameter));
				parameter_json = str_CatFree(parameter_json,int_string);
				free(int_string);
				parameter_json = str_CatFree(parameter_json," ,\n");
			}
			break;
		case RAZER_PARAMETER_TYPE_UINT:
			{
				char *int_string = str_FromLong(daemon_get_parameter_int(parameter));
				parameter_json = str_CatFree(parameter_json,int_string);
				free(int_string);
				parameter_json = str_CatFree(parameter_json," ,\n");
			}
			break;
		case RAZER_PARAMETER_TYPE_FLOAT:
			{
				char *float_string = str_FromDouble(daemon_get_parameter_float(parameter));
				parameter_json = str_CatFree(parameter_json,float_string);
				free(float_string);
				parameter_json = str_CatFree(parameter_json," ,\n");
			}
			break;
		case RAZER_PARAMETER_TYPE_RGB:
			{
				parameter_json = str_CatFree(parameter_json,"[");
				struct razer_rgb *color = daemon_get_parameter_rgb(parameter);
				char *r_string = str_FromLong(color->r);
				parameter_json = str_CatFree(parameter_json,r_string);
				parameter_json = str_CatFree(parameter_json," ,");
				free(r_string);
				char *g_string = str_FromLong(color->g);
				parameter_json = str_CatFree(parameter_json,g_string);
				parameter_json = str_CatFree(parameter_json," ,");
				free(g_string);
				char *b_string = str_FromLong(color->b);
				parameter_json = str_CatFree(parameter_json,b_string);
				free(b_string);
				parameter_json = str_CatFree(parameter_json,"] ,\n");
			}
			break;
		case RAZER_PARAMETER_TYPE_POS:
			{
				parameter_json = str_CatFree(parameter_json,"[");
				struct razer_pos *pos = daemon_get_parameter_pos(parameter);
				char *x_string = str_FromLong(pos->x);
				parameter_json = str_CatFree(parameter_json,x_string);
				parameter_json = str_CatFree(parameter_json," ,");
				free(x_string);
				char *y_string = str_FromLong(pos->y);
				parameter_json = str_CatFree(parameter_json,y_string);
				free(y_string);
				parameter_json = str_CatFree(parameter_json,"] ,\n");
			}
			break;
		case RAZER_PARAMETER_TYPE_RENDER_NODE:
			{
				struct razer_fx_render_node *render_node = daemon_get_parameter_render_node(parameter);
				char *render_node_string = str_FromLong(render_node->id);
				parameter_json = str_CatFree(parameter_json,render_node_string);
				free(render_node_string);
				parameter_json = str_CatFree(parameter_json," ,\n");
			}
			break;
		case RAZER_PARAMETER_TYPE_FLOAT_RANGE:
			{
				parameter_json = str_CatFree(parameter_json,"[");
				struct razer_float_range *range = daemon_get_parameter_float_range(parameter);
				char *min_string = str_FromDouble(range->min);
				parameter_json = str_CatFree(parameter_json,min_string);
				parameter_json = str_CatFree(parameter_json," ,");
				free(min_string);
				char *max_string = str_FromDouble(range->max);
				parameter_json = str_CatFree(parameter_json,max_string);
				free(max_string);
				parameter_json = str_CatFree(parameter_json,"] ,\n");
			}
			break;
		case RAZER_PARAMETER_TYPE_INT_RANGE:
			{
				parameter_json = str_CatFree(parameter_json,"[");
				struct razer_int_range *range = daemon_get_parameter_int_range(parameter);
				char *min_string = str_FromLong(range->min);
				parameter_json = str_CatFree(parameter_json,min_string);
				parameter_json = str_CatFree(parameter_json," ,");
				free(min_string);
				char *max_string = str_FromLong(range->max);
				parameter_json = str_CatFree(parameter_json,max_string);
				free(max_string);
				parameter_json = str_CatFree(parameter_json,"] ,\n");
			}
			break;
		case RAZER_PARAMETER_TYPE_UINT_RANGE:
			{
				parameter_json = str_CatFree(parameter_json,"[");
				struct razer_uint_range *range = daemon_get_parameter_uint_range(parameter);
				char *min_string = str_FromLong(range->min);
				parameter_json = str_CatFree(parameter_json,min_string);
				parameter_json = str_CatFree(parameter_json," ,");
				free(min_string);
				char *max_string = str_FromLong(range->max);
				parameter_json = str_CatFree(parameter_json,max_string);
				free(max_string);
				parameter_json = str_CatFree(parameter_json,"] ,\n");
			}
			break;
		case RAZER_PARAMETER_TYPE_RGB_RANGE:
			{
				parameter_json = str_CatFree(parameter_json,"[");
				struct razer_rgb_range *range = daemon_get_parameter_rgb_range(parameter);
				struct razer_rgb *min = range->min;
				parameter_json = str_CatFree(parameter_json,"{\n\"R\" : ");
				char *min_r_string = str_FromLong(min->r);
				parameter_json = str_CatFree(parameter_json,min_r_string);
				parameter_json = str_CatFree(parameter_json," ,\n\"G\" : ");
				free(min_r_string);
				char *min_g_string = str_FromLong(min->g);
				parameter_json = str_CatFree(parameter_json,min_g_string);
				parameter_json = str_CatFree(parameter_json," ,\n\"B\" : ");
				free(min_g_string);
				char *min_b_string = str_FromLong(min->b);
				parameter_json = str_CatFree(parameter_json,min_b_string);
				free(min_b_string);
				parameter_json = str_CatFree(parameter_json,"} ,\n");
				parameter_json = str_CatFree(parameter_json," ,");
				parameter_json = str_CatFree(parameter_json,"{");
				struct razer_rgb *max = range->max;
				parameter_json = str_CatFree(parameter_json,"{\n\"R\" : ");
				char *max_r_string = str_FromLong(max->r);
				parameter_json = str_CatFree(parameter_json,max_r_string);
				parameter_json = str_CatFree(parameter_json," ,\n\"G\" : ");
				free(max_r_string);
				char *max_g_string = str_FromLong(max->g);
				parameter_json = str_CatFree(parameter_json,max_g_string);
				parameter_json = str_CatFree(parameter_json," ,\n\"B\" : ");
				free(max_g_string);
				char *max_b_string = str_FromLong(max->b);
				parameter_json = str_CatFree(parameter_json,max_b_string);
				free(max_b_string);
				parameter_json = str_CatFree(parameter_json,"} ,\n");
				parameter_json = str_CatFree(parameter_json,"] ,\n");
			}
			break;
		case RAZER_PARAMETER_TYPE_POS_RANGE:
			{
				parameter_json = str_CatFree(parameter_json,"[");
				struct razer_pos_range *range = daemon_get_parameter_pos_range(parameter);
				struct razer_pos *min = range->min;
				parameter_json = str_CatFree(parameter_json,"{\n\"X\" : ");
				char *min_x_string = str_FromLong(min->x);
				parameter_json = str_CatFree(parameter_json,min_x_string);
				parameter_json = str_CatFree(parameter_json," ,\n\"Y\" : ");
				free(min_x_string);
				char *min_y_string = str_FromLong(min->y);
				parameter_json = str_CatFree(parameter_json,min_y_string);
				free(min_y_string);
				parameter_json = str_CatFree(parameter_json,"} ,\n");
				parameter_json = str_CatFree(parameter_json," ,");
				parameter_json = str_CatFree(parameter_json,"{");
				struct razer_pos *max = range->max;
				parameter_json = str_CatFree(parameter_json,"{\n\"X\" : ");
				char *max_x_string = str_FromLong(max->x);
				parameter_json = str_CatFree(parameter_json,max_x_string);
				parameter_json = str_CatFree(parameter_json," ,\n\"Y\" : ");
				free(max_x_string);
				char *max_y_string = str_FromLong(max->y);
				parameter_json = str_CatFree(parameter_json,max_y_string);
				free(max_y_string);
				parameter_json = str_CatFree(parameter_json,"} ,\n");
				parameter_json = str_CatFree(parameter_json,"] ,\n");
			}
			break;
		/*case RAZER_PARAMETER_TYPE_INT_ARRAY:
		case RAZER_PARAMETER_TYPE_UINT_ARRAY:
		case RAZER_PARAMETER_TYPE_FLOAT_ARRAY:
		case RAZER_PARAMETER_TYPE_RGB_ARRAY:
		case RAZER_PARAMETER_TYPE_POS_ARRAY:
		*/
	}

	parameter_json = str_CatFree(parameter_json," \"description\": \"");
	parameter_json = str_CatFree(parameter_json,parameter->description);
	parameter_json = str_CatFree(parameter_json,"\" },\n");
	return(parameter_json);
}
char *daemon_parameter_array_to_json(struct razer_parameter *parameter,int array_index)
{
	char *parameter_json = str_CreateEmpty();
	parameter_json = str_CatFree(parameter_json,"{\n \"item\": \"");
	parameter_json = str_CatFree(parameter_json,parameter->key);
	parameter_json = str_CatFree(parameter_json,"\",\n");
	parameter_json = str_CatFree(parameter_json," \"id\" : ");
	char *id_string = str_FromLong(array_index);
	parameter_json = str_CatFree(parameter_json,id_string);
	parameter_json = str_CatFree(parameter_json," ,\n");
	free(id_string);
	parameter_json = str_CatFree(parameter_json," \"value\" : ");
	struct razer_array_header *header = (struct razer_array_header*)parameter->value;
	if(array_index<0 || array_index >= header->size)
	{
		parameter_json = str_CatFree(parameter_json," null \n},\n");
		return(parameter_json);
	}
	switch(parameter->type)
	{
		case RAZER_PARAMETER_TYPE_POS_ARRAY:
			{
				struct razer_pos *pos = ((struct razer_pos_array*)parameter->value)->values[array_index];
				parameter_json = str_CatFree(parameter_json,"[");
				char *x_string = str_FromLong(pos->x);
				parameter_json = str_CatFree(parameter_json,x_string);
				parameter_json = str_CatFree(parameter_json," ,");
				free(x_string);
				char *y_string = str_FromLong(pos->y);
				parameter_json = str_CatFree(parameter_json,y_string);
				parameter_json = str_CatFree(parameter_json," ,");
				free(y_string);
				parameter_json = str_CatFree(parameter_json,"] ,\n");
			}
			break;
		case RAZER_PARAMETER_TYPE_UINT_ARRAY:
			{
				unsigned long value = ((struct razer_uint_array*)parameter->value)->values[array_index];
				char *uint_string = str_FromLong(value);
				parameter_json = str_CatFree(parameter_json,uint_string);
				free(uint_string);
				parameter_json = str_CatFree(parameter_json," ,\n");
			}
			break;
		case RAZER_PARAMETER_TYPE_INT_ARRAY:
			{
				long value = ((struct razer_int_array*)parameter->value)->values[array_index];
				char *int_string = str_FromLong(value);
				parameter_json = str_CatFree(parameter_json,int_string);
				free(int_string);
				parameter_json = str_CatFree(parameter_json," ,\n");
			}
			break;
		case RAZER_PARAMETER_TYPE_FLOAT_ARRAY:
			{
				float value = ((struct razer_float_array*)parameter->value)->values[array_index];
				char *float_string = str_FromDouble((double)value);
				parameter_json = str_CatFree(parameter_json,float_string);
				parameter_json = str_CatFree(parameter_json," ,\n");
				free(float_string);
			}
			break;
		case RAZER_PARAMETER_TYPE_RGB_ARRAY:
			{
				parameter_json = str_CatFree(parameter_json,"[");
				struct razer_rgb *color = ((struct razer_rgb_array*)parameter->value)->values[array_index];
				char *r_string = str_FromLong(color->r);
				parameter_json = str_CatFree(parameter_json,r_string);
				parameter_json = str_CatFree(parameter_json," ,");
				free(r_string);
				char *g_string = str_FromLong(color->g);
				parameter_json = str_CatFree(parameter_json,g_string);
				parameter_json = str_CatFree(parameter_json," ,");
				free(g_string);
				char *b_string = str_FromLong(color->b);
				parameter_json = str_CatFree(parameter_json,b_string);
				free(b_string);
				parameter_json = str_CatFree(parameter_json,"] ,\n");
			}
			break;
	}

	parameter_json = str_CatFree(parameter_json," },\n");
	return(parameter_json);
}