/*
 *			GPAC - Multimedia Framework C SDK
 *
 *			Authors: Jean Le Feuvre
 *			Copyright (c) Telecom ParisTech 2000-2026
 *					All rights reserved
 *
 *  This file is part of GPAC / Scene Compositor sub-project
 *
 *  GPAC is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU Lesser General Public License as published by
 *  the Free Software Foundation; either version 2, or (at your option)
 *  any later version.
 *
 *  GPAC 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 Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; see the file COPYING.  If not, write to
 *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 */

#include <gpac/internal/compositor_dev.h>
#include <gpac/modules/codec.h>
#include <gpac/utf.h>
#include <gpac/nodes_x3d.h>
#include <gpac/constants.h>

#if !defined(GPAC_DISABLE_VRML) && !defined(GPAC_DISABLE_COMPOSITOR)

enum
{
	IS_KeySensor = 1,
	IS_StringSensor,
	IS_Mouse,
	IS_HTKSensor,
};

typedef struct
{
	/*object for this input stream*/
	GF_ObjectManager *odm;

	/*list of attached nodes*/
	GF_List *is_nodes;
	/*stream ID*/
	u16 ES_ID;
	/*uncompressed data frame*/
	GF_List *ddf;

	GF_InputSensorDevice *io_dev;

	u32 type;

	/*string sensor sep char */
	s16 termChar, delChar;
	/*current typed text in UTF-8*/
	unsigned short enteredText[5000];
	u32 text_len;
} GF_InputSensorCtx;


void gf_isdec_del(GF_BaseDecoder *plug);

static GF_Err IS_ProcessData(GF_InputSensorCtx *is_ctx, const char *inBuffer, u32 inBufferLength);

typedef struct
{
	/*stream context*/
	u16 ES_ID;
	Bool registered;
	GF_MediaObject *mo;
	M_InputSensor *is;
} ISStack;



typedef struct
{
	u16 enteredText[5000];
	u32 text_len;
	GF_Compositor *compositor;
} StringSensorStack;



/*
				input sensor decoder(s) handling
*/


static void add_field(GF_InputSensorCtx *priv, u32 fieldType, const char *fieldName)
{
	GF_FieldInfo *field = (GF_FieldInfo *) gf_malloc(sizeof(GF_FieldInfo));
	memset(field, 0, sizeof(GF_FieldInfo));
	field->fieldType = fieldType;
	field->far_ptr = gf_sg_vrml_field_pointer_new(fieldType);
	field->name = (const char *) fieldName;
	field->fieldIndex = gf_list_count(priv->ddf);
	gf_list_add(priv->ddf, field);
}

static void isdev_add_field(GF_InputSensorDevice *dev, u32 fieldType, const char *fieldName)
{
	if (dev) {
		GF_InputSensorCtx *is = (GF_InputSensorCtx *)dev->input_stream_context;
		add_field(is, fieldType, fieldName);
	}
}

static void isdev_dispatch_frame(struct __input_device *dev, const u8 *data, u32 data_len)
{
	u32 i;
	GF_InputSensorCtx *is_ctx;
	GF_InputSensorCtx *priv;
	if (!dev || !data) return;

	priv = (GF_InputSensorCtx *)dev->input_stream_context;

	/*get all decoders and send frame*/
	i=0;
	while ((is_ctx = gf_list_enum(priv->odm->parentscene->compositor->input_streams, &i))) {
		if (is_ctx->type==priv->type) {
			IS_ProcessData(is_ctx, data, data_len);
		}
	}
}

static GF_InputSensorCtx *locate_is_ctx_for_odm(GF_Scene *scene, GF_ObjectManager *for_odm)
{
	u32 i, count;
	count = gf_list_count(scene->compositor->input_streams);
	for (i=0; i<count; i++) {
		GF_InputSensorCtx *is_ctx = gf_list_get(scene->compositor->input_streams, i);
		if (is_ctx->odm == for_odm) return is_ctx;
	}
	return NULL;
}

GF_Err gf_input_sensor_setup_object(GF_ObjectManager *odm, GF_ESD *esd)
{
	u32 i;
	GF_InputSensorCtx *is_ctx;
	GF_BitStream *bs;
	u32 len, size;
	char devName[255];
	u16 termSeq[20];
	GF_Scene *scene = odm->parentscene;

	if (esd->URLString) return GF_NOT_SUPPORTED;

	if (!esd->decoderConfig->decoderSpecificInfo || !esd->decoderConfig->decoderSpecificInfo->dataLength) return GF_NON_COMPLIANT_BITSTREAM;

	if (!scene->compositor->input_streams) {
		scene->compositor->input_streams = gf_list_new();
		if (!scene->compositor->input_streams) return GF_OUT_OF_MEM;
	}
	is_ctx = locate_is_ctx_for_odm(scene, odm);
	if (is_ctx) return GF_OK;

	GF_SAFEALLOC(is_ctx, GF_InputSensorCtx);
	if (!is_ctx) return GF_OUT_OF_MEM;

	is_ctx->odm = odm;
	is_ctx->is_nodes = gf_list_new();
	is_ctx->ddf = gf_list_new();

	is_ctx->ES_ID = esd->ESID;
	/*parse config*/
	bs = gf_bs_new(esd->decoderConfig->decoderSpecificInfo->data, esd->decoderConfig->decoderSpecificInfo->dataLength, GF_BITSTREAM_READ);
	len = gf_bs_read_int(bs, 8);
	for (i=0; i<len; i++) {
		devName[i] = gf_bs_read_int(bs, 8);
	}
	gf_bs_del(bs);
	devName[i] = 0;
	is_ctx->type = gf_crc_32(devName, len);
	size = len + 1;

	if (!stricmp(devName, "KeySensor")) {
		is_ctx->type = IS_KeySensor;
		add_field(is_ctx, GF_SG_VRML_SFINT32, "keyPressed");
		add_field(is_ctx, GF_SG_VRML_SFINT32, "keyReleased");
		add_field(is_ctx, GF_SG_VRML_SFINT32, "actionKeyPressed");
		add_field(is_ctx, GF_SG_VRML_SFINT32, "actionKeyReleased");
		add_field(is_ctx, GF_SG_VRML_SFBOOL, "shiftKeyPressed");
		add_field(is_ctx, GF_SG_VRML_SFBOOL, "controlKeyPressed");
		add_field(is_ctx, GF_SG_VRML_SFBOOL, "altKeyPressed");

	} else if (!stricmp(devName, "StringSensor")) {
		is_ctx->type = IS_StringSensor;
		add_field(is_ctx, GF_SG_VRML_SFSTRING, "enteredText");
		add_field(is_ctx, GF_SG_VRML_SFSTRING, "finalText");

		is_ctx->termChar = '\r';
		is_ctx->delChar = '\b';

		/*get escape chars if any specified*/
		if (size<esd->decoderConfig->decoderSpecificInfo->dataLength) {
			const char *src = esd->decoderConfig->decoderSpecificInfo->data + size;
			gf_utf8_mbstowcs(termSeq, esd->decoderConfig->decoderSpecificInfo->dataLength - size, &src);
			is_ctx->termChar = termSeq[0];
			is_ctx->delChar = termSeq[1];
		}
	} else if (!stricmp(devName, "Mouse")) {
		is_ctx->type = IS_Mouse;
		add_field(is_ctx, GF_SG_VRML_SFVEC2F, "position");
		add_field(is_ctx, GF_SG_VRML_SFBOOL, "leftButtonDown");
		add_field(is_ctx, GF_SG_VRML_SFBOOL, "middleButtonDown");
		add_field(is_ctx, GF_SG_VRML_SFBOOL, "rightButtonDown");
		add_field(is_ctx, GF_SG_VRML_SFFLOAT, "wheel");
	}
	else {
		GF_InputSensorDevice *ifce;
		/*not found, check all modules*/
		u32 plugCount = gf_modules_count();
		for (i = 0; i < plugCount ; i++) {
			ifce = (GF_InputSensorDevice *) gf_modules_load(i, GF_INPUT_DEVICE_INTERFACE);
			if (!ifce) continue;
			ifce->input_stream_context = is_ctx;
			if (ifce->RegisterDevice && ifce->RegisterDevice(ifce, devName, esd->decoderConfig->decoderSpecificInfo->data, esd->decoderConfig->decoderSpecificInfo->dataLength, isdev_add_field) ) {
				is_ctx->io_dev = ifce;
				break;
			}
			gf_modules_close_interface((GF_BaseInterface *) ifce);
		}
		if (!is_ctx->io_dev) {
			// not registered/added to input_streams yet - free our own lists here
			while (gf_list_count(is_ctx->ddf)) {
				GF_FieldInfo* fi = (GF_FieldInfo*)gf_list_get(is_ctx->ddf, 0);
				gf_list_rem(is_ctx->ddf, 0);
				gf_sg_vrml_field_pointer_del(fi->far_ptr, fi->fieldType);
				gf_free(fi);
			}
			gf_list_del(is_ctx->ddf);
			gf_list_del(is_ctx->is_nodes);
			gf_free(is_ctx);
			return GF_NOT_SUPPORTED;
		}
		is_ctx->io_dev->DispatchFrame = isdev_dispatch_frame;
	}

#ifdef GPAC_ENABLE_COVERAGE
	if (gf_sys_is_cov_mode()) {
		isdev_add_field(NULL, 0, NULL);
		isdev_dispatch_frame(NULL, NULL, 0);
	}
#endif

	gf_list_add(is_ctx->odm->parentscene->compositor->input_streams, is_ctx);
	return GF_OK;
}

void gf_input_sensor_delete(GF_ObjectManager *odm)
{
	/*get IS dec*/
	GF_InputSensorCtx *is_ctx = locate_is_ctx_for_odm(odm->parentscene, odm);
	if (!is_ctx) return;

	gf_list_del(is_ctx->is_nodes);

	while (gf_list_count(is_ctx->ddf)) {
		GF_FieldInfo *fi = (GF_FieldInfo *)gf_list_get(is_ctx->ddf, 0);
		gf_list_rem(is_ctx->ddf, 0);
		gf_sg_vrml_field_pointer_del(fi->far_ptr, fi->fieldType);
		gf_free(fi);
	}
	gf_list_del(is_ctx->ddf);
	gf_list_del_item(odm->parentscene->compositor->input_streams, is_ctx);
	gf_free(is_ctx);
}



static GF_Err IS_ProcessData(GF_InputSensorCtx *is_ctx, const char *inBuffer, u32 inBufferLength)
{
	u32 i, j, count;
	Double scene_time;
	GF_BitStream *bs;
	GF_FieldInfo *field;
	ISStack *st;
	GF_Err e = GF_OK;

	/*decode data frame except if local stringSensor*/
	bs = gf_bs_new((u8 *)inBuffer, inBufferLength, GF_BITSTREAM_READ);
	i=0;
	while ((field = (GF_FieldInfo *)gf_list_enum(is_ctx->ddf, &i))) {
		/*store present flag in eventIn for command skip - this is an ugly hack but it works since DDF don't have event types*/
		field->eventType = gf_bs_read_int(bs, 1);
		/*parse val ourselves (we don't want to depend on bifs codec)*/
		if (field->eventType) {
			switch (field->fieldType) {
			case GF_SG_VRML_SFBOOL:
				* ((SFBool *) field->far_ptr) = (SFBool) gf_bs_read_int(bs, 1);
				break;
			case GF_SG_VRML_SFFLOAT:
				*((SFFloat *)field->far_ptr) = FLT2FIX( gf_bs_read_float(bs) );
				break;
			case GF_SG_VRML_SFINT32:
				*((SFInt32 *)field->far_ptr) = (s32) gf_bs_read_int(bs, 32);
				break;
			case GF_SG_VRML_SFTIME:
				*((SFTime *)field->far_ptr) = gf_bs_read_double(bs);
				break;
			case GF_SG_VRML_SFVEC2F:
				((SFVec2f *)field->far_ptr)->x = FLT2FIX( gf_bs_read_float(bs) );
				((SFVec2f *)field->far_ptr)->y = FLT2FIX( gf_bs_read_float(bs) );
				break;
			case GF_SG_VRML_SFVEC3F:
				((SFVec3f *)field->far_ptr)->x = FLT2FIX( gf_bs_read_float(bs) );
				((SFVec3f *)field->far_ptr)->y = FLT2FIX( gf_bs_read_float(bs) );
				((SFVec3f *)field->far_ptr)->z = FLT2FIX( gf_bs_read_float(bs) );
				break;
			case GF_SG_VRML_SFCOLOR:
				((SFColor *)field->far_ptr)->red = FLT2FIX( gf_bs_read_float(bs) );
				((SFColor *)field->far_ptr)->green = FLT2FIX( gf_bs_read_float(bs) );
				((SFColor *)field->far_ptr)->blue = FLT2FIX( gf_bs_read_float(bs) );
				break;
			case GF_SG_VRML_SFVEC4F:
			case GF_SG_VRML_SFROTATION:
				((SFRotation *)field->far_ptr)->x = FLT2FIX( gf_bs_read_float(bs) );
				((SFRotation *)field->far_ptr)->y = FLT2FIX( gf_bs_read_float(bs) );
				((SFRotation *)field->far_ptr)->z = FLT2FIX( gf_bs_read_float(bs) );
				((SFRotation *)field->far_ptr)->q = FLT2FIX( gf_bs_read_float(bs) );
				break;

			case GF_SG_VRML_SFSTRING:
			{
				u32 size, length;
				size = gf_bs_read_int(bs, 5);
				length = gf_bs_read_int(bs, size);
				if (gf_bs_available(bs) < length) return GF_NON_COMPLIANT_BITSTREAM;

				if ( ((SFString *)field->far_ptr)->buffer ) gf_free( ((SFString *)field->far_ptr)->buffer);
				((SFString *)field->far_ptr)->buffer = (char*)gf_malloc(sizeof(char)*(length+1));
				if ( ((SFString *)field->far_ptr)->buffer) {
					for (j=0; j<length; j++) {
						((SFString *)field->far_ptr)->buffer[j] = gf_bs_read_int(bs, 8);
					}
					((SFString *)field->far_ptr)->buffer[length] = 0;
				} else {
					gf_bs_del(bs);
					return GF_OUT_OF_MEM;
				}
			}
			break;
			}
		}
	}
	gf_bs_del(bs);

	/*special case for StringSensor in local mode: lookup for special chars*/
	if (is_ctx->type == IS_StringSensor) {
		char tmp_utf8[5000];
		const unsigned short *ptr;
		u32 len;
		GF_FieldInfo *field1 = (GF_FieldInfo *)gf_list_get(is_ctx->ddf, 0);
		GF_FieldInfo *field2 = (GF_FieldInfo *)gf_list_get(is_ctx->ddf, 1);
		SFString *inText = (SFString *) field1->far_ptr;
		SFString *outText = (SFString *) field2->far_ptr;

		field1->eventType = field2->eventType = 0;
		is_ctx->enteredText[is_ctx->text_len] = (short) '\0';

		len = gf_utf8_wcslen(is_ctx->enteredText);
		if (len && (is_ctx->enteredText[len-1] == is_ctx->termChar)) {
			ptr = is_ctx->enteredText;
			len = gf_utf8_wcstombs(tmp_utf8, 5000, &ptr);
			if (len == GF_UTF8_FAIL) len = 1;
			if (outText->buffer) gf_free(outText->buffer);
			outText->buffer = (char*)gf_malloc(sizeof(char) * (len));
			memcpy(outText->buffer, tmp_utf8, sizeof(char) * (len-1) );
			outText->buffer[len-1] = 0;
			if (inText->buffer) gf_free(inText->buffer);
			inText->buffer = NULL;
			is_ctx->text_len = 0;

			field1->eventType = field2->eventType = 1;
		} else {
			if (is_ctx->delChar) {
				/*remove chars*/
				if ((len>1) && (is_ctx->enteredText[len-1] == is_ctx->delChar)) {
					is_ctx->enteredText[len-1] = (short) '\0';
					len--;
					is_ctx->enteredText[len-1] = (short) '\0';
					len--;
				}
			}
			is_ctx->text_len = len;
			ptr = is_ctx->enteredText;
			len = gf_utf8_wcstombs(tmp_utf8, 5000, &ptr);
			if (len == GF_UTF8_FAIL) len = 0;
			if (inText->buffer) gf_free(inText->buffer);
			inText->buffer = (char*)gf_malloc(sizeof(char) * (len+1));
			memcpy(inText->buffer, tmp_utf8, sizeof(char) * len);
			inText->buffer[len] = 0;
			field1->eventType = 1;
		}
	}

	//we still need this since we have no clue when the device sensor is calling us
	//TO CLEANUP (define PIDs and filters for input sensors and put them in the main thread ?)
	gf_sc_lock(is_ctx->odm->parentscene->compositor, GF_TRUE);

	/*apply it*/
	i=0;
	while ((st = (ISStack*)gf_list_enum(is_ctx->is_nodes, &i))) {
		if (!st->is || !st->mo || !st->is->enabled) continue;

		count = gf_list_count(st->is->buffer.commandList);
		scene_time = gf_scene_get_time(is_ctx->odm->parentscene);
		for (j=0; j<count; j++) {
			GF_Command *com = (GF_Command *)gf_list_get(st->is->buffer.commandList, j);
			GF_CommandField *info = (GF_CommandField *)gf_list_get(com->command_fields, 0);
			field = (GF_FieldInfo *)gf_list_get(is_ctx->ddf, j);
			if (info && field && field->eventType) {
				gf_sg_vrml_field_copy(info->field_ptr, field->far_ptr, field->fieldType);
				gf_sg_command_apply(is_ctx->odm->parentscene->graph, com, scene_time);
			}
		}
	}
	gf_sc_lock(is_ctx->odm->parentscene->compositor, GF_FALSE);
	return e;
}


/*
				input sensor node handling
*/
static void InputSensorUnregister(GF_Node *node, ISStack *st)
{
	GF_ObjectManager *odm;
	GF_InputSensorCtx *is_ctx;

	gf_mo_unregister(node, st->mo);

	odm = st->mo->odm;
	if (!odm) return;
	if (odm->type != GF_STREAM_INTERACT) return;

	/*get IS dec*/
	is_ctx = locate_is_ctx_for_odm(odm->parentscene, odm);
	if (!is_ctx) return;

	gf_list_del_item(is_ctx->is_nodes, st);


	/*stop stream*/
	if (st->mo->num_open) gf_mo_stop(&st->mo);
	st->mo = NULL;
	if (st->registered) {
		st->registered = 0;
		if (is_ctx->io_dev && is_ctx->io_dev->Stop) is_ctx->io_dev->Stop(is_ctx->io_dev);
	}
}

void gf_input_sensor_mo_destroyed(GF_Node *node)
{
	ISStack *st = (ISStack *)gf_node_get_private(node);
	if (!st) return;

	st->registered = 0;
	st->mo = NULL;
}

static void InputSensorRegister(GF_Node *n)
{
	GF_ObjectManager *odm;
	GF_InputSensorCtx *is_ctx;
	u32 i;
	ISStack *st = (ISStack *)gf_node_get_private(n);
	if (!st || !st->mo) return;
	odm = st->mo->odm;
	if (!odm || (odm->type != GF_STREAM_INTERACT)) return;

	/*get IS dec*/
	is_ctx = locate_is_ctx_for_odm(odm->parentscene, odm);
	if (!is_ctx) return;

	if ( gf_list_find(is_ctx->is_nodes, st) == -1 )
		gf_list_add(is_ctx->is_nodes, st);

	/*start stream*/
	gf_mo_play(st->mo, 0, -1, 0);

	gf_sc_unqueue_node_traverse(is_ctx->odm->parentscene->compositor, n);

	/*we want at least one sensor enabled*/
	i=0;
	while ((st = gf_list_enum(is_ctx->is_nodes, &i))) {
		if (st->is->enabled) {
			st->registered = 1;
			if (is_ctx->io_dev && is_ctx->io_dev->Start) is_ctx->io_dev->Start(is_ctx->io_dev);
			break;
		}
	}
}

static void TraverseInputSensor(GF_Node *node, void *rs, Bool is_destroy)
{
	ISStack *st = (ISStack*)gf_node_get_private(node);
	M_InputSensor *is = (M_InputSensor *)node;

	if (is_destroy) {
		GF_Scene *scene;
		if (st->registered) InputSensorUnregister(node, st);
		scene = (GF_Scene*)gf_sg_get_private(gf_node_get_graph(node));
		gf_sc_unqueue_node_traverse(scene->compositor, node);
		gf_free(st);
	} else if (!st->registered) {
		/*get decoder object */
		if (!st->mo) st->mo = gf_mo_register(node, &is->url, 0, 0);
		/*register with decoder*/
		if (st->mo) InputSensorRegister(node);
	}
}


void InitInputSensor(GF_Scene *scene, GF_Node *node)
{
	ISStack *stack;
	GF_SAFEALLOC(stack, ISStack);
	if (!stack) {
		GF_LOG(GF_LOG_ERROR, GF_LOG_INTERACT, ("[Compositor] Failed to allocate input sensor stack\n"));
		return;
	}
	stack->is = (M_InputSensor *) node;
	gf_node_set_private(node, stack);
	gf_node_set_callback_function(node, TraverseInputSensor);

	gf_sc_queue_node_traverse(scene->compositor, node);
}

/*check only URL changes*/
void InputSensorModified(GF_Node *node)
{
	GF_MediaObject *mo;
	ISStack *st = (ISStack *)gf_node_get_private(node);
	if (!st) return;

	mo = gf_mo_register(node, &st->is->url, 0, 0);
	if ((mo!=st->mo) || !st->registered) {
		if (mo!=st->mo) {
			if (st->mo) InputSensorUnregister(node, st);
			st->mo = mo;
		}
		if (st->is->enabled)
			InputSensorRegister(node);
		else
			return;
	} else if (!st->is->enabled) {
		InputSensorUnregister(node, st);
		return;
	}
}



/*
				input sensor DDF generations (user interface)
*/
GF_EXPORT
void gf_sc_input_sensor_mouse_input(GF_Compositor *compositor, GF_EventMouse *event)
{
	s32 X, Y;
	u32 left_but_down, middle_but_down, right_but_down;
	SFFloat wheel_pos;
	u32 i;
	GF_BitStream *bs;
	u8 *buf;
	u32 buf_size;
	Fixed bX, bY;
	GF_InputSensorCtx *is_ctx;

	if ( !gf_list_count(compositor->input_streams)) return;

	X = event->x;
	Y = event->y;
	left_but_down = middle_but_down = right_but_down = 0;
	wheel_pos = 0;
	switch (event->type) {
	case GF_EVENT_MOUSEDOWN:
		if (event->button==GF_MOUSE_RIGHT) right_but_down = 2;
		else if (event->button==GF_MOUSE_MIDDLE) middle_but_down = 2;
		else if (event->button==GF_MOUSE_LEFT) left_but_down = 2;
		break;
	case GF_EVENT_MOUSEUP:
		if (event->button==GF_MOUSE_RIGHT) right_but_down = 1;
		else if (event->button==GF_MOUSE_MIDDLE) middle_but_down = 1;
		else if (event->button==GF_MOUSE_LEFT) left_but_down = 1;
		break;
	case GF_EVENT_MOUSEWHEEL:
		wheel_pos = event->wheel_pos;
		break;
	case GF_EVENT_MOUSEMOVE:
		break;
	default:
		return;
	}

	/*get BIFS coordinates*/
	gf_sc_map_point(compositor, X, Y, &bX, &bY);
	bX = gf_divfix(bX, compositor->scale_x);
	bY = gf_divfix(bY, compositor->scale_y);

	bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);

	/*If wheel is specified disable X and Y (bug from MS wheel handling)*/
	if (wheel_pos) {
		gf_bs_write_int(bs, 0, 1);
	} else {
		gf_bs_write_int(bs, 1, 1);
		gf_bs_write_float(bs, FIX2FLT(bX));
		gf_bs_write_float(bs, FIX2FLT(bY));
	}
	gf_bs_write_int(bs, left_but_down ? 1 : 0, 1);
	if (left_but_down) gf_bs_write_int(bs, left_but_down-1, 1);
	gf_bs_write_int(bs, middle_but_down ? 1 : 0, 1);
	if (middle_but_down) gf_bs_write_int(bs, middle_but_down-1, 1);
	gf_bs_write_int(bs, right_but_down ? 1 : 0, 1);
	if (right_but_down) gf_bs_write_int(bs, right_but_down-1, 1);
	if (wheel_pos==0) {
		gf_bs_write_int(bs, 0, 1);
	} else {
		gf_bs_write_int(bs, 1, 1);
		gf_bs_write_float(bs, FIX2FLT(wheel_pos) );
	}

	gf_bs_align(bs);
	gf_bs_get_content(bs, &buf, &buf_size);
	gf_bs_del(bs);

	/*get all IS Mouse decoders and send frame*/
	i=0;
	while ((is_ctx = gf_list_enum(compositor->input_streams, &i))) {
		if (is_ctx->type==IS_Mouse) {
			IS_ProcessData(is_ctx, buf, buf_size);
		}
	}
	gf_free(buf);
}

GF_EXPORT
Bool gf_sc_input_sensor_keyboard_input(GF_Compositor *compositor, u32 key_code, u32 hw_code, Bool isKeyUp)
{
	u32 i;
	GF_BitStream *bs;
	GF_SLHeader slh;
	u8 *buf;
#ifndef GPAC_DISABLE_X3D
	X_KeySensor *n;
#endif
	GF_InputSensorCtx *is_ctx;
	u32 buf_size;
	u32 actionKey = 0;
	u32 shiftKeyDown, controlKeyDown, altKeyDown;
	s32 keyPressed, keyReleased, actionKeyPressed, actionKeyReleased;

	if (!gf_list_count(compositor->input_streams) && !gf_list_count(compositor->x3d_sensors)) return 0;

	memset(&slh, 0, sizeof(GF_SLHeader));
	slh.accessUnitStartFlag = slh.accessUnitEndFlag = 1;
	slh.compositionTimeStampFlag = 1;
	/*cf above*/
	slh.compositionTimeStamp = 0;

	bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);

	shiftKeyDown = controlKeyDown = altKeyDown = 0;
	keyPressed = keyReleased = actionKeyPressed = actionKeyReleased = 0;
	/*key-sensor codes*/
	switch (key_code) {
	case GF_KEY_F1:
		actionKey = 1;
		break;
	case GF_KEY_F2:
		actionKey = 2;
		break;
	case GF_KEY_F3:
		actionKey = 3;
		break;
	case GF_KEY_F4:
		actionKey = 4;
		break;
	case GF_KEY_F5:
		actionKey = 5;
		break;
	case GF_KEY_F6:
		actionKey = 6;
		break;
	case GF_KEY_F7:
		actionKey = 7;
		break;
	case GF_KEY_F8:
		actionKey = 8;
		break;
	case GF_KEY_F9:
		actionKey = 9;
		break;
	case GF_KEY_F10:
		actionKey = 10;
		break;
	case GF_KEY_F11:
		actionKey = 11;
		break;
	case GF_KEY_F12:
		actionKey = 12;
		break;
	case GF_KEY_HOME:
		actionKey = 13;
		break;
	case GF_KEY_END:
		actionKey = 14;
		break;
	case GF_KEY_PAGEUP:
		actionKey = 15;
		break;
	case GF_KEY_PAGEDOWN:
		actionKey = 16;
		break;
	case GF_KEY_UP:
		actionKey = 17;
		break;
	case GF_KEY_DOWN:
		actionKey = 18;
		break;
	case GF_KEY_LEFT:
		actionKey = 19;
		break;
	case GF_KEY_RIGHT:
		actionKey = 20;
		break;
	case GF_KEY_SHIFT:
		actionKey = 0;
		shiftKeyDown = isKeyUp ? 1 : 2;
		break;
	case GF_KEY_CONTROL:
		actionKey = 0;
		controlKeyDown = isKeyUp ? 1 : 2;
		break;
	case GF_KEY_ALT:
		actionKey = 0;
		altKeyDown = isKeyUp ? 1 : 2;
		break;

	default:
		actionKey = 0;
		break;
	}
	if (actionKey) {
		if (isKeyUp)
			actionKeyReleased = actionKey;
		else
			actionKeyPressed = actionKey;
	} else {
		/*handle numeric pad*/
		if ((key_code>=GF_KEY_0) && (key_code<=GF_KEY_9) ) {
			key_code = key_code + 0x30 - GF_KEY_0;
		}
		else
			key_code = hw_code;

		if (isKeyUp) keyReleased = key_code;
		else keyPressed = key_code;
	}

	gf_bs_write_int(bs, keyPressed ? 1 : 0, 1);
	if (keyPressed) gf_bs_write_int(bs, keyPressed, 32);
	gf_bs_write_int(bs, keyReleased ? 1 : 0, 1);
	if (keyReleased) gf_bs_write_int(bs, keyReleased, 32);
	gf_bs_write_int(bs, actionKeyPressed ? 1 : 0, 1);
	if (actionKeyPressed) gf_bs_write_int(bs, actionKeyPressed, 32);
	gf_bs_write_int(bs, actionKeyReleased ? 1 : 0, 1);
	if (actionKeyReleased) gf_bs_write_int(bs, actionKeyReleased, 32);
	gf_bs_write_int(bs, shiftKeyDown ? 1 : 0 , 1);
	if (shiftKeyDown) gf_bs_write_int(bs, shiftKeyDown-1, 1);
	gf_bs_write_int(bs, controlKeyDown ? 1 : 0 , 1);
	if (controlKeyDown) gf_bs_write_int(bs, controlKeyDown-1, 1);
	gf_bs_write_int(bs, altKeyDown ? 1 : 0 , 1);
	if (altKeyDown) gf_bs_write_int(bs, altKeyDown, 1);

	gf_bs_align(bs);
	gf_bs_get_content(bs, &buf, &buf_size);
	gf_bs_del(bs);

	/*get all IS keySensor decoders and send frame*/
	i=0;
	while ((is_ctx = gf_list_enum(compositor->input_streams, &i))) {
		if (is_ctx->type==IS_KeySensor) {
			IS_ProcessData(is_ctx, buf, buf_size);
		}
	}
	gf_free(buf);

#ifndef GPAC_DISABLE_X3D
	i=0;
	while ((n = (X_KeySensor*)gf_list_enum(compositor->x3d_sensors, &i))) {
		u16 tc[2];
		u32 len;
		char szStr[10];
		const unsigned short *ptr;
		if (gf_node_get_tag((GF_Node*)n) != TAG_X3D_KeySensor) continue;
		if (!n->enabled) return 0;

		if (keyPressed) {
			if (n->keyPress.buffer) gf_free(n->keyPress.buffer);
			tc[0] = keyPressed;
			tc[1] = 0;
			ptr = tc;
			len = gf_utf8_wcstombs(szStr, 10, &ptr);
			if (len == GF_UTF8_FAIL) len = 0;
			n->keyPress.buffer = (char*)gf_malloc(sizeof(char) * (len+1));
			memcpy(n->keyPress.buffer, szStr, sizeof(char) * len);
			n->keyPress.buffer[len] = 0;
			gf_node_event_out_str((GF_Node *)n, "keyPress");
		}
		if (keyReleased) {
			if (n->keyRelease.buffer) gf_free(n->keyRelease.buffer);
			tc[0] = keyReleased;
			tc[1] = 0;
			ptr = tc;
			len = gf_utf8_wcstombs(szStr, 10, &ptr);
			if (len == GF_UTF8_FAIL) len = 0;
			n->keyRelease.buffer = (char*)gf_malloc(sizeof(char) * (len+1));
			memcpy(n->keyRelease.buffer, szStr, sizeof(char) * len);
			n->keyRelease.buffer[len] = 0;
			gf_node_event_out_str((GF_Node *)n, "keyRelease");
		}
		if (actionKeyPressed) {
			n->actionKeyPress = actionKeyPressed;
			gf_node_event_out_str((GF_Node *)n, "actionKeyPress");
		}
		if (actionKeyReleased) {
			n->actionKeyRelease = actionKeyReleased;
			gf_node_event_out_str((GF_Node *)n, "actionKeyRelease");
		}
		if (shiftKeyDown) {
			n->shiftKey = (shiftKeyDown-1) ? 1 : 0;
			gf_node_event_out_str((GF_Node *)n, "shiftKey");
		}
		if (controlKeyDown) {
			n->controlKey = (controlKeyDown-1) ? 1 : 0;
			gf_node_event_out_str((GF_Node *)n, "controlKey");
		}
		if (altKeyDown) {
			n->altKey= (altKeyDown-1) ? 1 : 0;
			gf_node_event_out_str((GF_Node *)n, "altKey");
		}
		if (keyPressed || actionKeyPressed || (shiftKeyDown-1) || (controlKeyDown-1) || (altKeyDown-1)) {
			if (!n->isActive) {
				n->isActive = 1;
				gf_node_event_out_str((GF_Node *)n, "isActive");
			}
		} else if (n->isActive) {
			n->isActive = 0;
			gf_node_event_out_str((GF_Node *)n, "isActive");
		}
	}
#endif
	/*with KeySensor, we don't know if the key will be consumed or not, assume it is*/
	return 1;
}

GF_EXPORT
void gf_sc_input_sensor_string_input(GF_Compositor *compositor, u32 character)
{
	u32 i;
	GF_BitStream *bs;
#ifndef GPAC_DISABLE_X3D
	X_StringSensor *n;
#endif
	GF_InputSensorCtx *is_ctx;
	u8 *buf;
	u32 buf_size;

	if (!character) return;
	if (!gf_list_count(compositor->input_streams) && !gf_list_count(compositor->x3d_sensors)) return;

	/*get all IS StringSensor decoders and send frame*/
	i=0;
	while ((is_ctx = gf_list_enum(compositor->input_streams, &i))) {
		if (is_ctx->type==IS_StringSensor) {
			is_ctx->enteredText[is_ctx->text_len] = character;
			is_ctx->text_len += 1;

			/*write empty DDF*/
			bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);
			gf_bs_write_int(bs, 0, 1);
			gf_bs_write_int(bs, 0, 1);
			gf_bs_align(bs);
			gf_bs_get_content(bs, &buf, &buf_size);
			gf_bs_del(bs);

			IS_ProcessData(is_ctx, buf, buf_size);

			gf_free(buf);
		}
	}


#ifndef GPAC_DISABLE_X3D
	/*get all X3D StringSensors*/
	i=0;
	while ((n = (X_StringSensor*)gf_list_enum(compositor->x3d_sensors, &i))) {
		StringSensorStack *st;
		char szStr[5000];
		const unsigned short *ptr;
		u32 len;
		if (gf_node_get_tag((GF_Node*)n) != TAG_X3D_StringSensor) continue;
		if (!n->enabled) continue;

		st = (StringSensorStack *) gf_node_get_private((GF_Node *)n);

		if (character=='\b') {
			if (n->deletionAllowed && st->text_len) {
				st->text_len -= 1;
				st->enteredText[st->text_len] = 0;
				ptr = st->enteredText;
				len = gf_utf8_wcstombs(szStr, 10, &ptr);
				if (len == GF_UTF8_FAIL) len = 0;
				if (n->enteredText.buffer) gf_free(n->enteredText.buffer);
				szStr[len] = 0;
				n->enteredText.buffer = gf_strdup(szStr);
				gf_node_event_out_str((GF_Node *)n, "enteredText");
			}
		} else if (character=='\r') {
			if (n->finalText.buffer) gf_free(n->finalText.buffer);
			n->finalText.buffer = n->enteredText.buffer;
			n->enteredText.buffer = gf_strdup("");
			st->text_len = 0;
			gf_node_event_out_str((GF_Node *)n, "enteredText");
			gf_node_event_out_str((GF_Node *)n, "finalText");
		} else {
			st->enteredText[st->text_len] = character;
			st->text_len += 1;
			st->enteredText[st->text_len] = 0;
			ptr = st->enteredText;
			len = gf_utf8_wcstombs(szStr, 10, &ptr);
			if (len == GF_UTF8_FAIL) len = 0;
			if (n->enteredText.buffer) gf_free(n->enteredText.buffer);
			szStr[len] = 0;
			n->enteredText.buffer = gf_strdup(szStr);
			gf_node_event_out_str((GF_Node *)n, "enteredText");
		}
	}
#endif
}

#ifndef GPAC_DISABLE_X3D

void DestroyKeySensor(GF_Node *node, void *rs, Bool is_destroy)
{
	if (is_destroy) {
		GF_Compositor *compositor = (GF_Compositor *) gf_node_get_private(node);
		gf_list_del_item(compositor->x3d_sensors, node);
	}
}
void InitKeySensor(GF_Scene *scene, GF_Node *node)
{
	gf_node_set_private(node, scene->compositor);
	gf_node_set_callback_function(node, DestroyKeySensor);
	if (!scene->compositor->x3d_sensors)
		scene->compositor->x3d_sensors = gf_list_new();

	gf_list_add(scene->compositor->x3d_sensors, node);
}

void DestroyStringSensor(GF_Node *node, void *rs, Bool is_destroy)
{
	if (is_destroy) {
		StringSensorStack *st = (StringSensorStack *) gf_node_get_private(node);
		gf_list_del_item(st->compositor->x3d_sensors, node);
		gf_free(st);
	}
}
void InitStringSensor(GF_Scene *scene, GF_Node *node)
{
	StringSensorStack*st;
	GF_SAFEALLOC(st, StringSensorStack)
	if (!st) {
		GF_LOG(GF_LOG_ERROR, GF_LOG_INTERACT, ("[Compositor] Failed to allocate string sensor stack\n"));
		return;
	}
	st->compositor = scene->compositor;
	gf_node_set_private(node, st);
	gf_node_set_callback_function(node, DestroyStringSensor);

	if (!scene->compositor->x3d_sensors)
		scene->compositor->x3d_sensors = gf_list_new();

	gf_list_add(scene->compositor->x3d_sensors, node);
}

#endif /*GPAC_DISABLE_X3D*/

#else
GF_EXPORT
void gf_sc_input_sensor_mouse_input(GF_Compositor *compositor, GF_EventMouse *event)
{
}
GF_EXPORT
Bool gf_sc_input_sensor_keyboard_input(GF_Compositor *compositor, u32 key_code, u32 hw_code, Bool isKeyUp)
{
	return GF_TRUE;
}
GF_EXPORT
void gf_sc_input_sensor_string_input(GF_Compositor *compositor, u32 character)
{
}

#endif // !defined(GPAC_DISABLE_VRML) && !defined(GPAC_DISABLE_COMPOSITOR)
