/* Photo3 Server - DMS - march 99 - by Sylvain HUET */
/* av3d January 2000 - by Sébastien DENEUX */

/*	av3d v 4.0 by jmp (http://www.i-maginer.fr) */

/* update by iri  jan 07  (http://www.i-maginer.fr)
	- intégration de l'arborescence des avatars : type masculin et féminin et sous-types (sport, business, cool, .. : cf av3d-browser.pkg)
		- ajout des variables de stockage des paths des ressources 2d et 3d
		- fonctions de recherche
		- fonctions de register pour dwl éventuel par les clients
		- etc ...
	- enregistrement des fichiers 3d et 2d selon leur type (h/f) et sous-types
	- ajout et/ou upgrade des messages envoyés ou reçus, ajouts et modifications de fonctions
		- entre autres la (ré ?)initialisation des données user lorsqu'il se connecte
		- le registered du client
		- ...
	- modification du test de vérification du m3d lors de l'update par un client : avec l'ancien test, s'il prenait un avatar qui n'appartenait pas au sous-dossier "default", le srv lui renvoyait l'avatar par défaut... Dorénavant, le srv teste la disponibilité du m3d quelque soit le sous-type (et le code est simplifié par la même occasion).
	- gestion des filtres sur les textures

*/

/* update by iri  fev. 07  (http://www.i-maginer.fr)
	- correction de l'enregistrement du m3d choisi par un client : fonction ' __updateCliAvFile ', l'item associé au client et d'abord détruit puis un  nouvel item lui correspondant est créé. Auparavant, il était ajouté mais sans supprimer l'ancien et c'était cet ancien qui était retourné
*/

/* to do :
- le unregister n'est jamais fait, ni sur les m3D, ni sur les textures du mesh
  -> pb du browser : on ne peut pas supprimer les unregister pour les clients qui ont encore le mesh, meme si il disparait du browser
- le parse du m3D doit se faire uniquement du coté serveur, le serveur transmet le nom du m3D ainsi que les noms des textures associées
- compression de données vers les clients

- iri : à recoder proprement et lisiblement ...
*/

defcom CgetPlugin=getPlugin I S;;
defcom CsetSign=setSign I S S S S S S;;
defcom CsetMesh=setMesh I S S S S S S S;;
defcom CsetDefAvatarsList=setDefAvatarsList S S;;
defcom CsetDefHairsList=setDefHairsList S S;;
defcom CsetDefFacesList=setDefFacesList S S;;
defcom CsetDefClothesTopList=setDefClothesTopList S S;;
defcom CsetDefClothesList=setDefClothesList S S;;
defcom CsetDefShoesList=setDefShoesList S S;;
defcom CsetDefSStype = setDefSStype S;;	// ::::: iri  sous-types d'avatar dispos sur le srv
defcom CsetNewSStype = setNewSStype S S S S S S;;	// ::::: iri  envoi la liste des ressources du sous-type demandé par le client

defcom CsetAvatar=setAvatar S;;
defcom CsetAnimKey=setAnimKey S S;;

var type="av3d";;
typeof defaultAvFileM=S;;
typeof defaultAvFileF=S;;

typeof availableAvFileM = [[S [S r1]] r1];;	// ::::: iri 	liste des m3ds M pour chaque sous-type dispo
typeof availableAvFileF = [[S [S r1]] r1];;	// ::::: iri 	liste des m3ds F pour chaque sous-type dispo

typeof availableHairFileM = [[S [S r1]] r1];;	// ::::: iri 	liste des hairs M pour chaque sous-type dispo
typeof availableHairFileF = [[S [S r1]] r1];;	// ::::: iri 	liste des hairs F pour chaque sous-type dispo

typeof availableFaceFileM = [[S [S r1]] r1];;	// ::::: iri 	liste des faces M pour chaque sous-type dispo
typeof availableFaceFileF = [[S [S r1]] r1];;	// ::::: iri 	liste des faces F pour chaque sous-type dispo

typeof availableTopFileM = [[S [S r1]] r1];;	// ::::: iri 	liste des tops M pour chaque sous-type dispo
typeof availableTopFileF = [[S [S r1]] r1];;	// ::::: iri 	liste des tops F pour chaque sous-type dispo

typeof availableBottomFileM = [[S [S r1]] r1];;	// ::::: iri 	liste des bottoms M pour chaque sous-type dispo
typeof availableBottomFileF = [[S [S r1]] r1];;	// ::::: iri 	liste des bottoms F pour chaque sous-type dispo

typeof availableShoesFileM = [[S [S r1]] r1];;	// ::::: iri 	liste des shoes M pour chaque sous-type dispo
typeof availableShoesFileF = [[S [S r1]] r1];;	// ::::: iri 	liste des shoes F pour chaque sous-type dispo

struct Pho=[cliPho		:	CLIENT,
			idPho		:	I,
			workPho		:	S, // chemin de la texture du visage
			signPho		:	S, // signature de la texture du visage
			workHair	:	S,
			signHair	:	S,
			workClothesTop	:	S,
			signClothesTop	:	S,
			workClothes	:	S,
			signClothes	:	S,
			workShoes	:	S,
			signShoes	:	S,
			transPho	:	[[S r1] [S r1] [S r1] [S r1] [S r1]], // transparence sur le visage plus utilisé :: iri :  + ajout des filtres hairs, top, bottom et shoes
			state		:	S, // etat de l'avatar assis ou debout
			file		:	S, // fichier m3D du client
			sex		:	S	// sexe du client
			]mkPho;;

typeof av3dClis=[Pho r1];;

typeof clis=[CLIENT r1];;/*all clients that have started the module*/

//typeof defaultAvatarsDirectory=S;;/*default folder for avatars browser*/
typeof defaultClothesTopDirectory=S;;/*default folder for Top Clothes browser*/
typeof defaultClothesDirectory=S;;/*default folder for Clothes browser*/
typeof defaultHairsDirectory=S;;/*default folder for Hairs browser*/
typeof defaultFacesDirectory=S;;/*default folder for Faces browser*/
typeof defaultShoesDirectory=S;;/*default folder for Shoes browser*/

// :::::: jmp  gestion de la liste pour masculin ::::::
typeof defaultAvatarsListM=[S r1];;
typeof defaultClothesTopListM=[S r1];;
typeof defaultClothesListM=[S r1];;
typeof defaultHairsListM=[S r1];;
typeof defaultFacesListM=[S r1];;
typeof defaultShoesListM=[S r1];;

// :::::: jmp  gestion de la liste pour feminin ::::::
typeof defaultAvatarsListF=[S r1];;
typeof defaultClothesTopListF=[S r1];;
typeof defaultClothesListF=[S r1];;
typeof defaultHairsListF=[S r1];;
typeof defaultFacesListF=[S r1];;
typeof defaultShoesListF=[S r1];;

var   m3dItemRef="meshAv3d";; /* reference of the item that correspond to the avatar mesh file of each client*/


// ::::: lib (sinon charger la lib liste dans le dmc srv)
fun is_in_list (l, x)=
  if l==nil
  then
    0
  else
    let l->[a nxt] in
      (a==x)||is_in_list nxt x;;

/*----------------*/
/**parsing du fichier m3d*/
/*----------------*/

/*----------------*/
/*returns the texture name*/
fun getTexture(l)=
 if l==nil then nil
 else
  let l -> [tete queue] in
   if !strcmp hd tete "texture" then hd tl tete /*texture name*/
   else if !strcmp hd tete "}" then nil
   else getTexture queue;;

/*----------------*/
fun lastpercent(n,i,l)=
 if i>=strlen n then l
 else lastpercent n i+1 if (nth_char n i)=='% then i else l;;

/*----------------*/
fun cutnamefilter(n)=
 let lastpercent n 0 nil-> i in
  if i==nil then [n nil] else [substr n i+1 1000 substr n 1 i-1];;

/*----------------*/
/*register the texture*/
fun registerTexture(texture)=

 let cutnamefilter texture -> [textureFileName _] in
  (
   _RSunregister this textureFileName;
   _RSregisterfiles this textureFileName::nil RSfile+RScontrol;
   0
  );;

/*----------------*/
/*returns the bloc after the next "}" in l*/
fun goToNextBloc(l)=
 if l==nil then
  nil
 else
 let l-> [tete queue] in
  if !strcmp hd tete "}" then queue
  else goToNextBloc queue;;

/*----fonction appellée à partir de registerM3d ds av3ds----*/
/*register the textures of the m3d*/
fun registerM3dTextures(l)=
 if l== nil then nil
 else let l -> [tete queue] in
 (
  if !strcmp hd tete "material" then
   (
    let getTexture queue -> textureFileName in
     if textureFileName!=nil then 
		registerTexture textureFileName
	 else nil;
	 
	 registerM3dTextures (goToNextBloc queue)
   )
  else if !strcmp hd tete "shell" then
   registerM3dTextures (goToNextBloc queue)
  else if !strcmp hd tete "mesh" then
   registerM3dTextures (goToNextBloc queue)
  else if !strcmp hd tete "anim" then
   registerM3dTextures (goToNextBloc queue)
  else if !strcmp hd tete "camera" then
   registerM3dTextures (goToNextBloc queue)
  else
   registerM3dTextures queue;
  0
 );;

/*---Fonction appelée à partir de addbitmap ds av3ds-------------*/
/* register a m3d file and associated textures*/
fun registerM3d(fileName)=
// (_DLGMessageBox _channel nil "fun registerM3d" fileName nil;0);
 _RSunregister this fileName;   
 _RSregisterfiles this fileName::nil RSfile+RScontrol;
 
 let strextr _getpack _checkpack fileName -> l in
   registerM3dTextures l;;

/*----------------*/
/* register the list of m3d files and associated textures*/
fun registerM3dList(l)=
 if l==nil then nil
 else
  let l -> [tete queue] in
   (registerM3d tete;
    registerM3dList queue;
    0);;



/* ************** */
/* Client known ? */
/* ************** */
/*----------------*/
fun cliByCli(x,c)=
	x.cliPho==c;;/*CLIENT*/

/*----------------*/
fun cliById(x,id)=
	x.idPho==id;;/*I*/

/*----------------*/
fun broadReload(a,b)=_DMSsend this a b;;
/*----------------*/

fun broadMSG(a,b)=
_DMSsend this a b;;

/*----------------*/
fun logout(cli)=
   // _DLGMessageBox _channel nil "fun logout" itoa _DMSgetId cli 0;
 _RSunregister this itoa _DMSgetId cli;
 
 let search_in_list av3dClis @cliById _DMSgetId cli -> result in

 set av3dClis=remove_from_list av3dClis result;
 
 
 set clis=remove_from_list clis cli;
 
 /* _showconsole;
 _fooS strcat "taille de la liste clis : " itoa sizelist clis;
 _fooS strcat "taille de la liste av3dClis : " itoa sizelist av3dClis;*/

 0;;

/*----------------*/
/* returns the client avatar mesh filename*/
/* nil if no mesh or if mesh not on server*/
fun getCliAvFileName(cli)=
   // _DLGMessageBox _channel nil "fun getCliAvFileName " "on y passe " 0;

	
	/*	let _DMSfindItem cli m3dItemRef -> meshItem in
		let meshItem.nameItem -> meshName in
		(
   _DLGMessageBox _channel nil "fun getCliAvFileName m3dItemRef : " m3dItemRef 0;
   _DLGMessageBox _channel nil "fun getCliAvFileName _ITEMref meshItem :" _ITEMref meshItem 0;
   _DLGMessageBox _channel nil "fun meshName" meshName 0;0);
*/
 let _DMSfindItem cli "sex" -> meshItem in
 let meshItem.nameItem -> meshName in
 // let _checkpack meshName -> res in
   // if meshItem!=nil && res!=nil then meshName else nil;;
   meshName;;
   



/*
	::::: iri
	retourne le sous-type défini par le path d'une ressource
	ex : avatars/typem/cool/m3d/avdefault.m3d -> cool
	
	s -> S : path de la ressource
	  <- S : sous-type
*/
fun getSStype(s)=
	substr s strlen( "avatars/typem/" ) strlen(s) ;;

/* ----------------*/
/* returns the files of list l that have the extension ext*/
fun getExtOnly(l,ext)=
 if l==nil then nil
 else let l -> [t q] in
  let strlen t -> long in   
   if !strcmpi substr t long-(strlen ext) long ext then
     t::(getExtOnly q ext)
   else
     getExtOnly q ext;;

// ::::: iri  fun [[S r1] [[S r1] r1] S S ] [[S r1] r1]  retourne les fichiers portant l'extension '  ext  ' dans le dossier concerné
fun listeAregister(l, out, suffixe, ext)=
	if l == nil then
		out
	else
		(
		 set out = (getExtOnly _listoffiles (strcat hd l suffixe) ext) :: out;
		 listeAregister tl l out suffixe ext
		);;

// ::::: iri  fun [[[S r1] r1]] I  demande l'enregistrement d'une liste de fichiers
fun registerM3dListInit(l)=
	if l == nil then
		0
	else
		(
		 registerM3dList hd l;
		 registerM3dListInit tl l
		);;


/* ::::: iri   renvoie si une ressource est bien présente dans les listes du serveur (1) ou pas (0).
	l		-> [[S [S r1]] r1] : ' par ex availableAvFileM '
	r		-> S : nom de la ressource
			<- I : 1 si trouvée, 0 sinon */
fun rscExists(l, r)=
	if l == nil then
		0
	else
		let hd l -> [_ list] in
		if is_in_list list r then
			1
		else
			rscExists tl l r;;
	
/*
	::::: iri
	récupération des ressources correspondantes à un ss-type particulier
	
	l	-> [[S [S r1]] r1]
	key	-> S : sous-type demandé
		<- [S r1] : liste des ressources de ce sous-type
*/
fun getRscsList(l, key)=
	if l == nil then
		nil
	else
		let hd l -> [ss rscs] in
		if !strcmp key getSStype ss then
			rscs
		else
			getRscsList tl l key;;


/*
	::::: iri
	listes des ressources disponibles sur le serveur
*/

// ::::: iri   m3ds en fonction des sous-types
fun addRscsList(l, out, base, suffixe, ext)=
	if l == nil then
		out
	else
		let strcatn (hd l) :: suffixe :: nil -> sstype in
		let getExtOnly _listoffiles sstype ext -> files in
		(
		 set out = [hd l files] :: out;
		 addRscsList tl l out base suffixe ext
		);;
		 
/* ::::: iri  toutes les fonctions de register ci-dessous ont été modifiées pour prendre en compte la nouvelle
	arborescence contenant les sous-types d'avatar */
/* :: browser des ressources de l'avatar ::*/
/* register avatars meshes dans textures for default browser*/
fun registerBrowserAvatars()=
 /* unregisterBrowserFiles registeredBrowserFiles;*/
 // :::::: ici on register les fichiers m3D masculins ::::::
  // :::::: provisoire reconstruire le chemin correct en fonction du sexe :::::

 set defaultAvatarsListM = getExtOnly _listoffiles "avatars/typem/default/m3D" ".m3d";
 registerM3dListInit /* defaultAvatarsListM*/ (listeAregister _listofsubdir "avatars/typem" nil "/m3d" ".m3d"); /* register all files in browser*/  
 
 
  // :::::: ici on register les fichiers m3D feminins ::::::
 set defaultAvatarsListF = getExtOnly _listoffiles "avatars/typef/default/m3D" ".m3d";
 registerM3dListInit /* defaultAvatarsListF*/ (listeAregister _listofsubdir "avatars/typef" nil "/m3d" ".m3d"); /* register all files in browser*/
 
 set availableAvFileM = addRscsList _listofsubdir "avatars/typem" nil "avatars/typem" "/m3d" ".m3d"; // ::::: iri
 set availableAvFileF = addRscsList _listofsubdir "avatars/typef" nil "avatars/typem" "/m3d" ".m3d"; // ::::: iri
 0;;
 
 
/* :: Création de la liste des textures pour les cheveux ::*/
/* register textures hairs dans textures for default browser*/
fun registerBrowserHairs()=
 // :::::: ici on register les cheveux masculins ::::::
 set defaultHairsListM=getExtOnly _listoffiles "avatars/typeM/default/hair" ".jpg";
 registerM3dListInit /* defaultHairsListM*/ (listeAregister _listofsubdir "avatars/typem" nil "/hair" ".jpg"); /* register all files in browser*/
 // :::::: ici on register les cheveux feminins ::::::
 set defaultHairsListF=getExtOnly _listoffiles "avatars/typeF/default/hair" ".jpg";
 registerM3dListInit /* defaultHairsListF*/ (listeAregister _listofsubdir "avatars/typef" nil "/hair" ".jpg"); /* register all files in browser*/
 
 set availableHairFileM = addRscsList _listofsubdir "avatars/typem" nil "avatars/typem" "/hair" ".jpg"; // ::::: iri
 set availableHairFileF = addRscsList _listofsubdir "avatars/typef" nil "avatars/typem" "/hair" ".jpg"; // ::::: iri
 0;;

/* :: Création de la liste des textures pour les visages ::*/
/* register textures hairs dans textures for default browser*/
fun registerBrowserFaces()=
 // :::::: ici on register les visages masculins ::::::
 set defaultFacesListM=getExtOnly _listoffiles "avatars/typeM/default/face" ".jpg";
 registerM3dListInit /* defaultFacesListM*/ (listeAregister _listofsubdir "avatars/typem" nil "/face" ".jpg"); /* register all files in browser*/
 // :::::: ici on register les visages feminins ::::::
 set defaultFacesListF=getExtOnly _listoffiles "avatars/typeF/default/face" ".jpg";
 registerM3dListInit /* defaultFacesListF*/ (listeAregister _listofsubdir "avatars/typef" nil "/face" ".jpg"); /* register all files in browser*/
 
 set availableFaceFileM = addRscsList _listofsubdir "avatars/typem" nil "avatars/typem" "/face" ".jpg"; // ::::: iri
 set availableFaceFileF = addRscsList _listofsubdir "avatars/typef" nil "avatars/typem" "/face" ".jpg"; // ::::: iri
 0;;
 
 
/* :: Création de la liste des textures pour les vetements du haut ::*/
/* register textures vetements du haut dans textures for default browser*/
fun registerBrowserTopClothes()=
 // :::::: ici on register les vetements du haut masculins ::::::
 set defaultClothesTopListM=getExtOnly _listoffiles "avatars/typeM/default/top" ".jpg";
 registerM3dListInit /* defaultClothesTopListM*/ (listeAregister _listofsubdir "avatars/typem" nil "/top" ".jpg"); /* register all files in browser*/
 // :::::: ici on register les vetements du haut feminins ::::::
 set defaultClothesTopListF=getExtOnly _listoffiles "avatars/typeF/default/top" ".jpg";
 registerM3dListInit /* defaultClothesTopListF*/ (listeAregister _listofsubdir "avatars/typef" nil "/top" ".jpg"); /* register all files in browser*/
 
 set availableTopFileM = addRscsList _listofsubdir "avatars/typem" nil "avatars/typem" "/top" ".jpg"; // ::::: iri
 set availableTopFileF = addRscsList _listofsubdir "avatars/typef" nil "avatars/typem" "/top" ".jpg"; // ::::: iri
 0;;
 
/* :: Création de la liste des textures pour les vetements du bas ::*/
/* register textures vetements du bas dans textures for default browser*/
fun registerBrowserClothes()=
 // :::::: ici on register les vetements du bas masculins ::::::
 set defaultClothesListM=getExtOnly _listoffiles "avatars/typeM/default/bottom" ".jpg";
 registerM3dListInit /* defaultClothesListM*/ (listeAregister _listofsubdir "avatars/typem" nil "/bottom" ".jpg"); /* register all files in browser*/
 // :::::: ici on register les vetements du bas feminins ::::::
 set defaultClothesListF=getExtOnly _listoffiles "avatars/typeF/default/bottom" ".jpg";
 registerM3dListInit /* defaultClothesListF*/ (listeAregister _listofsubdir "avatars/typef" nil "/bottom" ".jpg"); /* register all files in browser*/
 
 set availableBottomFileM = addRscsList _listofsubdir "avatars/typem" nil "avatars/typem" "/bottom" ".jpg"; // ::::: iri
 set availableBottomFileF = addRscsList _listofsubdir "avatars/typef" nil "avatars/typem" "/bottom" ".jpg"; // ::::: iri
 0;;
 
/* :: Création de la liste des textures pour les chaussures ::*/
/* register textures chaussures dans textures for default browser*/
fun registerBrowserShoes()=
 // :::::: ici on register les chaussures masculins ::::::
 set defaultShoesListM=getExtOnly _listoffiles "avatars/typeM/default/shoes" ".jpg";
 registerM3dListInit /* defaultShoesListM*/ (listeAregister _listofsubdir "avatars/typem" nil "/shoes" ".jpg"); /* register all files in browser*/
 // :::::: ici on register les chaussures feminins ::::::
 set defaultShoesListF=getExtOnly _listoffiles "avatars/typeF/default/shoes" ".jpg";
 registerM3dListInit /* defaultShoesListF*/ (listeAregister _listofsubdir "avatars/typem" nil "/shoes" ".jpg"); /* register all files in browser*/
 
 set availableShoesFileM = addRscsList _listofsubdir "avatars/typem" nil "avatars/typem" "/shoes" ".jpg"; // ::::: iri
 set availableShoesFileF = addRscsList _listofsubdir "avatars/typef" nil "avatars/typem" "/shoes" ".jpg"; // ::::: iri
 0;;


/* ----------------*/
fun activate(from,cli,action,param,rep)= 

 if !strcmp action "start" then
  // let getCliAvFileName cli -> fileName in
   (
    let mkPho[DMSsender DMSsender.idCLI "" nil "" nil "" nil "" nil "" nil nil nil nil nil] -> r in
	set av3dClis=r::(remove_from_list av3dClis r);
	set clis=cli::(remove_from_list clis cli);
    
/* _showconsole;
 _fooS strcat "taille de la liste clis : " itoa sizelist clis;
 _fooS strcat "taille de la liste av3dClis : " itoa sizelist av3dClis;*/

  /*  if fileName != nil
      then 
      registerM3d fileName // register the client avatar m3d file and its textures
    else
    (
    registerM3d defaultAvFileM;
    registerM3d defaultAvFileF);	*/

   _DMScreateClientDMI this cli nil
   )
 
 else if !strcmp action "getPlugin" then
 
//  let getCliAvFileName cli -> fileName in
  (

   // let _DMScreateClientDMI this cli defaultAvFile -> result in
    _DLGMessageBox _channel nil "valeur de result dans getplugin : " rep 0;0;
   _DMSsend this cli CgetPlugin [_DMSgetHandle from rep]
  )

 else if !strcmp action "!ChgLogin" then
  let getCliAvFileName cli -> fileName in
    if fileName!=nil then
     (
      registerM3d fileName;
      _DMSsend this cli CsetAvatar [fileName]
     )
    else
      _DMSsend this cli CsetAvatar [nil] /* no avatar in item*/

 else if !strcmp action "reload" then
  (
   registerBrowserAvatars;
   let linebuild defaultAvatarsListM -> sm in
   let linebuild defaultAvatarsListF -> sf in
    apply_on_list clis @broadReload CsetDefAvatarsList [sm sf];
   registerBrowserTopClothes;
   let linebuild defaultClothesTopListM -> sm in
   let linebuild defaultClothesTopListF -> sf in
    apply_on_list clis @broadReload CsetDefClothesTopList [sm sf];
   registerBrowserClothes;
   let linebuild defaultClothesListM -> sm in
   let linebuild defaultClothesListF -> sf in
    apply_on_list clis @broadReload CsetDefClothesList [sm sf];
   registerBrowserHairs;
   let linebuild defaultHairsListM -> sm in
   let linebuild defaultHairsListF -> sf in
    apply_on_list clis @broadReload CsetDefHairsList [sm sf];
   registerBrowserFaces;
   let linebuild defaultFacesListM -> sm in
   let linebuild defaultFacesListF -> sf in
    apply_on_list clis @broadReload CsetDefFacesList [sm sf];
   registerBrowserShoes;
   let linebuild defaultShoesListM -> sm in
   let linebuild defaultShoesListF -> sf in
    apply_on_list clis @broadReload CsetDefShoesList [sm sf];
   0
  )
 else if !strcmp action "AnimKey" then
   (
    apply_on_list clis @broadMSG CsetAnimKey [_DMSgetLogin cli param];
   0)
 else if !strcmp action "AnimSelect" then
  let lineextr param -> list in
 let hd list -> pseudo in
 let hd tl list -> key in
 (
// (_DLGMessageBox _channel nil "on est coté serveur avec animation pour : " pseudo 0;0);
    apply_on_list clis @broadMSG CsetAnimKey [pseudo key];
    0)
  
 else nil;;
 
 
// -----------:: on verifie les droits du participant passé en param :: ---------------
fun cbStatut(from, user, action, param, others, tag)=
(
// _fooS strcat "fun cbStatut valeur de param dans AV3DS ????? : " param;
_DMSreplyTag tag strbuild ("user"::param::nil)::("Statut"::"Debout"::nil)::nil others 0;
0);;


/*----------------*/
// ::::: iri  ajout de l'arborescence des avatars : types (M et F) et sous-types (default, sport, business, cool, ...)
fun IniDMI(param)=

 let strextr _getpack _checkpack param -> l in /* get default avatar file*/
  (
   // set m3dItemRef = "typem";
   // set m3dItemRefF ="typeF";
  // set m3dItemRef =getInfo l "m3dItemRef";
   set defaultAvFileM = strcatn "Avatars/typem/default/m3d/avDefault.m3d" :: nil;
   set defaultAvFileF = strcatn "Avatars/typef/default/m3d/avDefault.m3d" :: nil;
   if (_checkpack defaultAvFileM) == nil then _closemachine else 0;
  // set defaultAvFile =strcatn"Avatars/"::m3dItemRef::"/m3d/avDefault.m3d"::nil;
   // set defaultAvatarsDirectory = strcatn "Avatars/"::m3dItemRef::"/"::(getInfo l "M3dAvBrowserPath")::nil;
   set defaultHairsDirectory = strcatn "Avatars/typem/default/" ::(getInfo l "HairAvBrowserPath")::nil;
   set defaultFacesDirectory = strcatn "Avatars/typem/default/" ::(getInfo l "FaceAvBrowserPath")::nil;
   set defaultClothesTopDirectory = strcatn "Avatars/typem/default/" ::(getInfo l "ClothesTopAvBrowserPath")::nil;
   set defaultClothesDirectory = strcatn "Avatars/typem/default/" ::(getInfo l "ClothesAvBrowserPath")::nil;
   set defaultShoesDirectory = strcatn "Avatars/typem/default/" ::(getInfo l "ShoesAvBrowserPath")::nil;
   
   /*
   set defaultHairsDirectory=strcat "Avatars/typeF/" getInfo l "HairAvBrowserPath";
   set defaultFacesDirectory=strcat "Avatars/typeF/" getInfo l "FaceAvBrowserPath";
   set defaultClothesTopDirectory=strcat "Avatars/typeF/" getInfo l "ClothesTopAvBrowserPath";
   set defaultClothesDirectory=strcat "Avatars/typeF/" getInfo l "ClothesAvBrowserPath";
   set defaultShoesDirectory=strcat "Avatars/typeF/" getInfo l "ShoesAvBrowserPath";
   */
   
   
   registerBrowserAvatars;
   registerBrowserTopClothes;
   registerBrowserClothes;
   registerBrowserHairs;
   registerBrowserFaces;
   registerBrowserShoes
  );
  _DMSregisterDMI this @activate @logout nil nil;
 
  _DMSdefineActions this (["Statut?" @cbStatut])::nil;
  0
 ;;


/*----------------*/
/*register the sign files textures*/
/*send the name of the texture of the avatar*/

/*----------------*/
// ::::: iri   adaptation pour la transmission des filtres
fun __getSign(id)=
 let search_in_list av3dClis @cliById id -> q in
 let q.transPho -> [f fh ft fb fs] in
 ( 
// (_DLGMessageBox _channel nil "fun __getSign" strcatn"valeur de q.signPho : " ::q.signPho:: "\n" :: "valeur de q.signHair : "::q.signHair:: "\n" :: "valeur de q.signClothesTop : " ::q.signClothesTop:: "\n" :: "valeur de q.transPho : " ::q.transPho::nil 0;0);
  _DMSsend this DMSsender CsetSign [id q.signPho q.signHair q.signClothesTop q.signClothes q.signShoes strbuild f :: fh :: ft :: fb :: fs :: nil];
  
  );; 
  
// :::::: iri
fun __getSign2()=
	let search_in_list av3dClis @cliByCli DMSsender -> q in
	__getSign q.idPho;;

/* ----------------*/
/* register the mesh filename and its textures*/
/* send the name of the mesh of the avatar*/
// ::::: iri   adaptation pour la transmission des filtres
fun __getMesh(id)=

 let search_in_list av3dClis @cliById id -> q in /**/
 let _DMSbyId id -> cli in
  let getCliAvFileName cli -> fileName in
  let q.transPho -> [f fh ft fb fs] in
  (  // _DLGMessageBox _channel nil "fun __getSign srv mesh" strcatn "id " :: (itoa id) :: "_top " :: q.signClothesTop :: nil 0;
 // _DLGMessageBox _channel nil "fun __getSign srv filtre" linebuild f :: fh :: ft :: fb :: fs :: nil 0;
 /* (_DLGMessageBox _channel nil "fun __getMesh srv" 
strcatn"Valeur de id : "::(itoa id)::"\n"::
"valeur de fileName : "::fileName::"\n"::
"valeur de q.signPho : "::q.signPho::"\n"::
"valeur de q.signHair : "::q.signHair::"\n"::
"valeur de q.signClothesTop : "::q.signClothesTop::"\n"::
"valeur de q.signClothes : "::q.signClothes::"\n"::
"valeur de q.signShoes : "::q.signShoes::"\n"::
nil 0;0);*/
    /* _fooS strcat "**** av3d : demande mesh au server = " fileName;*/
    _DMSsend this DMSsender CsetMesh [id fileName q.signPho q.signHair q.signClothesTop q.signClothes q.signShoes strbuild f :: fh :: ft :: fb :: fs :: nil]
   );;

/* ----------------*/
/*
	:::::: iri
	réception des données clientes
	met à jour la structure Pho du client sur le serveur (pour les filtres)
	
	ajout des filtres hairs, top, bottom et shoes
	
	f 	-> S : filtre de transparence (obsolète)
	fh	-> S : filtre hairs
	ft	-> S : filtre top
	fb -> S : filtre bottom
	fs	-> S : filtre shoes
		<- [S S S S S]
*/
fun __trans(f, fh, ft, fb, fs)=
	let search_in_list av3dClis @cliByCli DMSsender -> q in
	let if q != nil then
			q
		else 
			let mkPho[DMSsender DMSsender.idCLI "" nil "" nil "" nil "" nil "" nil nil nil nil nil] -> r in
			(
			 set av3dClis = r :: av3dClis;
			 r
			)
	-> p in
	set p.transPho = [lineextr f lineextr fh lineextr ft lineextr fb lineextr fs];;

/* ----------------*/
fun stringCompare(a,b)=!strcmpi a b;;

/* ----------------*/
// ::::: on recoit le sexe et le M3d du client ::::::
/* ::::: iri
	Modifications des tests de disponibilité des ressources : désormais, le serveur vérifie que le m3d choisit par le client est reconnu par le serveur.
	Avec l'ancienne méthode, si le client choisissait un sous-type différents du sous-type 'default'; le serveur lui retournait l'avatar par défaut ...
*/
fun __updateCliAvFile(sex, m3d)=


// _DLGMessageBox _channel nil "__updateCliAvFile sexe " sex 0;
// _DLGMessageBox _channel nil "__updateCliAvFile M3D :" m3d 0;

	if !strcmp "F" sex then
		(
		 // ::::: iri   if (search_in_list defaultAvatarsListF @stringCompare m3d)==nil && (strcmp m3d getCliAvFileName DMSsender) && (strcmp m3d defaultAvFileF) then
		 if rscExists availableAvFileF m3d then
			_DMSsend this DMSsender CsetAvatar [defaultAvFileF] /* default avatar */
		 else
			(
			 // _DMSsubItem DMSsender sex 500; /* to be sure !*/
			 _DMSclearItem DMSsender;
			 let mkItem ["sex" m3d 0 nil] -> item in
			 _DMSaddItem DMSsender item
			)
		)
	else 
		(
		 // ::::: iri   if (search_in_list defaultAvatarsListM @stringCompare m3d)==nil && (strcmp m3d getCliAvFileName DMSsender) && (strcmp m3d defaultAvFileM) then
		 if rscExists availableAvFileM m3d then
			_DMSsend this DMSsender CsetAvatar [defaultAvFileM] /* default avatar*/
		 else
			(
			 // _DMSsubItem DMSsender sex 500; /* to be sure !*/
			 _DMSclearItem DMSsender;
			 let mkItem ["sex" m3d 0 nil] -> item in
			 _DMSaddItem DMSsender item;
			 )
		);; 


// ::::: iri  fun [[S r1] [S r1]] [S r1]  
fun getFolderNameOnly(l, out)=
	if l == nil then
		out
	else
		let strlen "avatars/typem/" -> n in
		(
		 set out = (substr hd l n strlen(hd l)) :: out;
		 getFolderNameOnly tl l out
		);;

  

 
   
// ::::: iri	(ré ?)initialise les données du client qui vient de se connecter
// fun __updateInitCli(s)=
fun updateInitCli(l, p)=
	// let lineextr s -> [ ph [ ha [ to [ bo [ sh [ se [ m3 _ ]]]]]]] in
	let l -> [ ph [ ha [ to [ bo [ sh [ se [ m3 _ ]]]]]]] in
	/* let search_in_list av3dClis @cliByCli DMSsender -> q in
	let if q != nil then	// le client est déjà connu du serveur
			q
		else				// le client est encore inconnu du serveur : il est ajouté
			let mkPho[DMSsender DMSsender.idCLI "" nil "" nil "" nil "" nil "" nil nil nil nil nil] -> r in
			(
			 set av3dClis = r :: av3dClis;
			 r
			)
		-> p in */
	(
	 // m3d
	 set p.file = m3;
	 
	 // sexe
	 set p.sex = se;
	 
	 // statut
	 set p.state = "";
	 
	 // photo
	 let ph -> s in
	 if s == nil then
		set p.workPho = ""
	 else if strlen s then
		(
		 set p.workPho = let strcat p.workPho s -> ns in
		 if (strlen ns) < 32768 then
			ns 
		 else
			""
		)
	 else
		/* :: attention : on associe le guest avec le nom du matériau ::*/
		let strcat itoa _DMSgetId DMSsender "face" -> guest in
		let _getlongname p.workPho "" "#" -> sign in
		(
		 _storepack p.workPho strcatn "tmp/" :: m3dItemRef :: "/photo/srv" :: sign :: nil;
		 _RSunregister this guest;
		 let _RSregister this guest 0 p.workPho -> register in
		 set p.workPho=nil;
		 set p.signPho = strcatn "tmp/" :: m3dItemRef :: "/photo/" :: sign :: nil;
		);
	 
	 // hair
	 let ha -> s in
	 if s == nil then
		set p.workHair = ""
	 else if strlen s then
		(
		 set p.workHair = let strcat p.workHair s -> ns in
		 if (strlen ns) < 32768 then
			ns 
		 else
		 ""
		)
	 else
		/* :: attention : on associe le guest avec le nom du matériau ::*/
		let strcat itoa _DMSgetId DMSsender "hair" -> guest in
		let _getlongname p.workHair "" "#" -> sign in
		(
		 _storepack p.workHair strcatn "tmp/" :: m3dItemRef :: "/hair/srv" :: sign :: nil;
		 _RSunregister this guest;
		 _RSregister this guest 0 p.workHair;
		 set p.workHair=nil;
		 set p.signHair=strcatn "tmp/" :: m3dItemRef :: "/hair/" :: sign :: nil;
		);
	
	 // vêtement haut
	 let to -> s in
	 if s == nil then
		set p.workClothesTop = ""
	 else if strlen s then
		(
		 set p.workClothesTop = let strcat p.workClothesTop s -> ns in
		 if (strlen ns) < 32768 then
			ns 
		 else
			""
		)
	 else
		/* :: attention : on associe le guest avec le nom du matériau ::*/
		let strcat itoa _DMSgetId DMSsender "clothestop" -> guest in
		let _getlongname p.workClothesTop "" "#" -> sign in
		(
		 _storepack p.workClothesTop strcatn "tmp/" :: m3dItemRef :: "/Top/srv" ::sign::nil;
		 _RSunregister this guest;
		 _RSregister this guest 0 p.workClothesTop;
		 set p.workClothesTop=nil;
		 set p.signClothesTop=strcatn "tmp/" :: m3dItemRef :: "/Top/" :: sign::nil;
		);
		
	 // vêtement bas
	 let bo -> s in
	 if s == nil then
		set p.workClothes = ""
	 else if strlen s then
		(
		 set p.workClothes = let strcat p.workClothes s -> ns in
		 if (strlen ns) < 32768 then
			ns 
		 else
			""
		)
	else
		/* :: attention : on associe le guest avec le nom du matériau ::*/
		let strcat itoa _DMSgetId DMSsender "clothes" -> guest in
		let _getlongname p.workClothes "" "#" -> sign in
		(
		 _storepack p.workClothes strcatn "tmp/" :: m3dItemRef :: "/Bot/srv" :: sign:: nil;
		 _RSunregister this guest;
		 _RSregister this guest 0 p.workClothes;
		 set p.workClothes=nil;
		 set p.signClothes=strcatn "tmp/" :: m3dItemRef :: "/Bot/" :: sign :: nil;
		);
		
	 // shoes
	 let sh -> s in
	 if s == nil then
		set p.workShoes=""
	 else if strlen s then
		(
		 set p.workShoes = let strcat p.workShoes s -> ns in
		 if (strlen ns) < 32768 then
			ns 
		 else
			""
		)
	else
		/* :: attention : on associe le guest avec le nom du matériau ::*/
		let strcat itoa _DMSgetId DMSsender "shoes" -> guest in
		let _getlongname p.workShoes "" "#" -> sign in
		(
		 _storepack p.workShoes strcatn "tmp/"::m3dItemRef::"/shoes/srv"::sign::nil;
		 _RSunregister this guest;
		 _RSregister this guest 0 p.workShoes;
		 set p.workShoes=nil;
		 set p.signShoes=strcatn "tmp/"::m3dItemRef::"/shoes/"::sign::nil;
  

		 let getCliAvFileName DMSsender -> fileName in
		 if fileName != nil then /* register the client avatar m3d file and its textures*/
			registerM3d fileName
		 else
			nil;
 
		 _DMSsetress DMSsender "Avatar" type;
		 _DMSevent this DMSsender "changed" nil nil;
		 nil
		);
	 0
	);;

/*----------------*/
/* client started*/
/* send avatars default list*/
// ::::: jmp a optimiser ?? en fonction du sexe du sender ? :::::
// ::::: iri  en fonction du ss-type de chaque ressource défini par le client
fun __registered(s)=
/* :::::: iri
 _DMSsend this DMSsender CsetDefAvatarsList [linebuild defaultAvatarsListM linebuild defaultAvatarsListF];
 _DMSsend this DMSsender CsetDefClothesList [linebuild defaultClothesListM linebuild defaultClothesListF];
 _DMSsend this DMSsender CsetDefClothesTopList [linebuild defaultClothesTopListM linebuild defaultClothesTopListF];
 _DMSsend this DMSsender CsetDefHairsList [linebuild defaultHairsListM linebuild defaultHairsListF];
 _DMSsend this DMSsender CsetDefFacesList [linebuild defaultFacesListM linebuild defaultFacesListF];
 _DMSsend this DMSsender CsetDefShoesList [linebuild defaultShoesListM linebuild defaultShoesListF];
 */
 
 // let getCliAvFileName DMSsender -> fileName in
 let search_in_list av3dClis @cliByCli DMSsender -> q in
 let lineextr s -> [ ssex [av [ssav [ ssph [ ssha [ ssto [ ssbo [ sssh suite ]]]]]]]] in
 let if q != nil then	// le client est déjà connu du serveur
			q
		else				// le client est encore inconnu du serveur : il est ajouté
			let mkPho[DMSsender DMSsender.idCLI "" nil "" nil "" nil "" nil "" nil nil nil nil nil] -> r in
			(
			 set av3dClis = r :: av3dClis;
			 r
			)
		-> p in
 (
  /* set p.sex = if ssex == nil then "M" else ssex;
  set p.file = if av == nil then "" else av; */
  updateInitCli suite p;
  _DMSclearItem DMSsender;
  let mkItem ["sex" p.file 0 nil] -> item in
  _DMSaddItem DMSsender item;
 // let getCliAvFileName DMSsender -> fileName in
 //  let _DLGMessageBox _channel DMSwin "REGISTERED" strcat "fileName : " fileName 0 -> _ in
 /* if fileName != nil then 
      registerM3d fileName // register the client avatar m3d file and its textures
    else
    (
     registerM3d defaultAvFileM;
     registerM3d defaultAvFileF
	);
 */

		
 // ::::: iri    envoi des paths suivants les sous-types de chaque ressource
 // let lineextr s -> [ ssav [ ssph [ ssha [ ssto [ ssbo [ sssh _ ]]]]]] in
 
 let getRscsList availableAvFileM ssav -> tmp in
 let if tmp == nil then linebuild defaultAvatarsListM else linebuild tmp -> avM in
 let getRscsList availableAvFileF ssav -> tmp in
 let if tmp == nil then linebuild defaultAvatarsListF else linebuild tmp -> avF in
 
 let getRscsList availableFaceFileM ssph -> tmp in
 let if tmp == nil then linebuild defaultFacesListM else linebuild tmp -> faM in
 let getRscsList availableFaceFileF ssph -> tmp in
 let if tmp == nil then linebuild defaultFacesListF else linebuild tmp -> faF in
 
 let getRscsList availableHairFileM ssha -> tmp in
 let if tmp == nil then linebuild defaultHairsListM else linebuild tmp -> haM in
 let getRscsList availableHairFileM ssha -> tmp in
 let if tmp == nil then linebuild defaultHairsListF else linebuild tmp -> haF in
 
 let getRscsList availableTopFileM ssto -> tmp in
 let if tmp == nil then linebuild defaultClothesTopListM else linebuild tmp -> toM in
 let getRscsList availableTopFileF ssto -> tmp in
 let if tmp == nil then linebuild defaultClothesTopListF else linebuild tmp -> toF in
 
 let getRscsList availableBottomFileM ssbo -> tmp in
 let if tmp == nil then linebuild defaultClothesListM else linebuild tmp -> boM in
 let getRscsList availableBottomFileF ssbo -> tmp in
 let if tmp == nil then linebuild defaultClothesListF else linebuild tmp -> boF in
 
 let getRscsList availableShoesFileM sssh -> tmp in
 let if tmp == nil then linebuild defaultShoesListM else linebuild tmp -> shM in
 let getRscsList availableShoesFileF sssh -> tmp in
 let if tmp == nil then linebuild defaultShoesListF else linebuild tmp -> shF in
 (
  _DMSsend this DMSsender CsetDefAvatarsList [zip avM zip avF];
  _DMSsend this DMSsender CsetDefFacesList [zip faM zip faF];
  _DMSsend this DMSsender CsetDefHairsList [zip haM zip haF];
  _DMSsend this DMSsender CsetDefClothesTopList [zip toM zip toF];
  _DMSsend this DMSsender CsetDefClothesList [zip boM zip boF];
  _DMSsend this DMSsender CsetDefShoesList [zip shM zip shF];
 );
 
 // ::::: iri  ajout des sous-types disponibles sur le srv
 _DMSsend this DMSsender CsetDefSStype [if !strcmpi ssex "M" then zip linebuild getFolderNameOnly _listofsubdir "avatars/typem" nil else zip linebuild getFolderNameOnly _listofsubdir "avatars/typef" nil]
);;


// ::::: iri
/*
fun __registered(s)=
	let lineextr s -> [ph [ ha [ to [ bo [ sh [ m3 _]]]]]] in
	(
	 _DMSsend this DMSsender CsetDefConf
	 _DMSsend this DMSsender CsetDefAvatarsList [linebuild defaultAvatarsListM linebuild defaultAvatarsListF];
	 _DMSsend this DMSsender CsetDefClothesList [linebuild defaultClothesListM linebuild defaultClothesListF];
	 _DMSsend this DMSsender CsetDefClothesTopList [linebuild defaultClothesTopListM linebuild defaultClothesTopListF];
	 _DMSsend this DMSsender CsetDefHairsList [linebuild defaultHairsListM linebuild defaultHairsListF];
	 _DMSsend this DMSsender CsetDefFacesList [linebuild defaultFacesListM linebuild defaultFacesListF];
	 _DMSsend this DMSsender CsetDefShoesList [linebuild defaultShoesListM linebuild defaultShoesListF];
 
	 // ::::: iri  ajout des sous-types disponibles sur le srv
	 _DMSsend this DMSsender CsetDefSStype [linebuild getFolderNameOnly _listofsubdir "avatars/typem" nil linebuild getFolderNameOnly _listofsubdir "avatars/typef" nil]
	);;
*/


// ::::: iri
fun __newSStype(s)= 
	_DMSsend this DMSsender CsetNewSStype [zip linebuild getExtOnly _listoffiles (strcat s "m3d") ".m3d"
												zip linebuild getExtOnly _listoffiles (strcat s "bottom") ".jpg"
												zip linebuild getExtOnly _listoffiles (strcat s "top") ".jpg"
												zip linebuild getExtOnly _listoffiles (strcat s "hair") ".jpg"
												zip linebuild getExtOnly _listoffiles (strcat s "face") ".jpg"
												zip linebuild getExtOnly _listoffiles (strcat s "shoes") ".jpg"];;


/*----------------*/
/*not bitmap choosen*/
fun __nobitmap()=
// (_DLGMessageBox _channel nil "fun __nobitmap" "nothing" nil;0);
 let getCliAvFileName DMSsender -> fileName in
  if fileName!=nil then /*register the client avatar m3d file and its textures*/
     registerM3d fileName
  else nil;
  _DMSsetress DMSsender "Avatar" type;
  _DMSevent this DMSsender "changed" nil nil;;


// ::::: iri    update m3d
fun __addM3d(s)= 
	let search_in_list av3dClis @cliByCli DMSsender -> q in
	let if q != nil then
			q
		else 
			let mkPho[DMSsender DMSsender.idCLI "" nil "" nil "" nil "" nil "" nil nil nil nil nil] -> r in
			(
			 set av3dClis = r :: av3dClis;
			 r
			)
		-> p in
	if s == nil then
		set p.file = ""
	else
		set p.file = s;;

/*----------------*/
/*receive statut*/
fun __updateStatut(s)=
//(_DLGMessageBox _channel nil "fun __addstatut coté serveur !" s nil;0);

let search_in_list av3dClis @cliByCli DMSsender -> q in
let if q!=nil then q
 else 
    let mkPho[DMSsender DMSsender.idCLI "" nil "" nil "" nil "" nil "" nil nil nil nil nil] -> r in
 (set av3dClis=r::av3dClis;r)
 -> p in
if s==nil then
  set p.state=""
else if strlen s then
 (set p.state= s)
 else nil;;





/*----------------*/
/*receive bitmap*/
fun __addbitmap(s)=
// _fooS strcat "____######_SRV__ADDBITMAP__" s;

let search_in_list av3dClis @cliByCli DMSsender -> q in
let if q!=nil then q
 else 
    let mkPho[DMSsender DMSsender.idCLI "" nil "" nil "" nil "" nil "" nil nil nil nil nil] -> r in
 (set av3dClis=r::av3dClis;r)
 -> p in
(
	if s==nil then
	  set p.workPho=""
	else if strlen s then
	 (set p.workPho= let strcat p.workPho s -> ns in
	   if (strlen ns)<32768 then ns else "")
	else
	 /* :: attention : on associe le guest avec le nom du matériau ::*/
	 let strcat itoa _DMSgetId DMSsender "face" -> guest in
	 let _getlongname p.workPho "" "#" -> sign in
	 (
	 _storepack p.workPho strcatn "tmp/"::m3dItemRef::"/photo/srv"::sign::nil;
	  _RSunregister this guest;
	  let _RSregister this guest 0 p.workPho -> register in
	  set p.workPho=nil;
	  set p.signPho=strcatn "tmp/"::m3dItemRef::"/photo/"::sign::nil);
	0);;
  
  
/*----------------*/
/*receive hair bitmap*/
fun __addbitmaphair(s)=
// (_DLGMessageBox _channel nil "fun __addbitmaphair" "yes" nil;0);

// _fooS strcat "____######_SRV__ADDBITMAPHAIR__" s;

let search_in_list av3dClis @cliByCli DMSsender -> q in
let if q!=nil then q
 else 
    let mkPho[DMSsender DMSsender.idCLI "" nil "" nil "" nil "" nil "" nil nil nil nil nil] -> r in
 (set av3dClis=r::av3dClis;r)
 -> p in
if s==nil then
  set p.workHair=""
else if strlen s then
 (set p.workHair= let strcat p.workHair s -> ns in
   if (strlen ns)<32768 then ns else "")
else
	 /* :: attention : on associe le guest avec le nom du matériau ::*/
	let strcat itoa _DMSgetId DMSsender "hair" -> guest in
	let _getlongname p.workHair "" "#" -> sign in
	 (_storepack p.workHair strcatn "tmp/"::m3dItemRef::"/hair/srv"::sign::nil;
	  _RSunregister this guest;
	  _RSregister this guest 0 p.workHair;
	  set p.workHair=nil;
	  set p.signHair=strcatn "tmp/"::m3dItemRef::"/hair/"::sign::nil;
	  nil);;
  
   
/*----------------*/
/*receive clothestop bitmap*/
fun __addbitmapclothestop(s)=
// (_DLGMessageBox _channel nil "fun __addbitmapclothestop" "yes" nil;0);

// _fooS strcat "____######_SRV__ADDBITMAPTOP__" s;

let search_in_list av3dClis @cliByCli DMSsender -> q in
let if q!=nil then q
 else 
    let mkPho[DMSsender DMSsender.idCLI "" nil "" nil "" nil "" nil "" nil nil nil nil nil] -> r in
 (set av3dClis=r::av3dClis;r)
 -> p in
if s==nil then
  set p.workClothesTop=""
else if strlen s then
 (set p.workClothesTop= let strcat p.workClothesTop s -> ns in
   if (strlen ns)<32768 then ns else "")
else
	 /* :: attention : on associe le guest avec le nom du matériau ::*/
	let strcat itoa _DMSgetId DMSsender "clothestop" -> guest in
 let _getlongname p.workClothesTop "" "#" -> sign in
 (_storepack p.workClothesTop strcatn "tmp/"::m3dItemRef::"/Top/srv"::sign::nil;
  _RSunregister this guest;
  _RSregister this guest 0 p.workClothesTop;
  set p.workClothesTop=nil;
  set p.signClothesTop=strcatn "tmp/"::m3dItemRef::"/Top/"::sign::nil;
  nil);;
  
  /*----------------*/
/*receive clothes bitmap*/
fun __addbitmapclothes(s)=
// (_DLGMessageBox _channel nil "fun __addbitmapclothes" s nil;0);

// _fooS strcat "____######_SRV__ADDBITMAPBAS__" s;

let search_in_list av3dClis @cliByCli DMSsender -> q in
let if q!=nil then q
 else 
    let mkPho[DMSsender DMSsender.idCLI "" nil "" nil "" nil "" nil "" nil nil nil nil nil] -> r in
 (set av3dClis=r::av3dClis;r)
 -> p in
if s==nil then
  set p.workClothes=""
else if strlen s then
 (set p.workClothes= let strcat p.workClothes s -> ns in
   if (strlen ns)<32768 then ns else "")
else
	 /* :: attention : on associe le guest avec le nom du matériau ::*/
	let strcat itoa _DMSgetId DMSsender "clothes" -> guest in
 let _getlongname p.workClothes "" "#" -> sign in
 (_storepack p.workClothes strcatn "tmp/"::m3dItemRef::"/Bot/srv"::sign::nil;
  _RSunregister this guest;
  _RSregister this guest 0 p.workClothes;
  set p.workClothes=nil;
  set p.signClothes=strcatn "tmp/"::m3dItemRef::"/Bot/"::sign::nil;
  nil);;
  
  
    /*----------------*/
/*receive clothes bitmap*/
fun __addbitmapshoes(s)=
// (_DLGMessageBox _channel nil "fun __addbitmapshoes" s nil;0);

// _fooS strcat "____######_SRV__ADDBITMAPSHOES__" s;

let search_in_list av3dClis @cliByCli DMSsender -> q in
let if q!=nil then q
 else 
    let mkPho[DMSsender DMSsender.idCLI "" nil "" nil "" nil "" nil "" nil nil nil nil nil] -> r in
 (set av3dClis=r::av3dClis;r)
 -> p in
if s==nil then
  set p.workShoes=""
else if strlen s then
 (set p.workShoes= let strcat p.workShoes s -> ns in
   if (strlen ns)<32768 then ns else "")
else
	 /* :: attention : on associe le guest avec le nom du matériau ::*/
	let strcat itoa _DMSgetId DMSsender "shoes" -> guest in
 let _getlongname p.workShoes "" "#" -> sign in
 (_storepack p.workShoes strcatn "tmp/"::m3dItemRef::"/shoes/srv"::sign::nil;
  _RSunregister this guest;
  _RSregister this guest 0 p.workShoes;
  set p.workShoes=nil;
  set p.signShoes=strcatn "tmp/"::m3dItemRef::"/shoes/"::sign::nil;
  

  let getCliAvFileName DMSsender -> fileName in
   if fileName!=nil then /*register the client avatar m3d file and its textures*/
   registerM3d fileName
   else nil;
 
  _DMSsetress DMSsender "Avatar" type;
  _DMSevent this DMSsender "changed" nil nil;
  
  
  nil);;
  
  
  