
// Member util




		// these functions expect an array of user objects

		function userAlphabetical(a, b) {
			var A = trim(a.username).toLowerCase();
			var B = trim(b.username).toLowerCase();
			if (A < B) return -1;
			if (A > B) return 1;
			return 0;
		}

		function userSortOnline(a, b) {
			var A = (a.nln ? 0 : 1); // reverse
			var B = (b.nln ? 0 : 1); // reverse
			if (A < B) return -1;
			if (A > B) return 1;
			return 0;
		}
		
		function userSortOnline2(a, b) {
			var A = parseInt(a.online);
			var B = parseInt(b.online);
			if (A < B) return 1;
			if (A > B) return -1;
			return 0;
		}
	
		function userSortLastLogin(a, b) {
			var A = trim(b.lastlogin).toLowerCase();
			var B = trim(b.lastlogin).toLowerCase();
			if (A < B) return 1;	// reverse
			if (A > B) return -1;	// reverse
			return 0;
		}
	
		// find a user in the list object by field.
		//  Eg: foundUser = findUserBy("id", "391", onlineUsers, true);
		function findUserBy(field, match, userListObj, returnObj) {
			i = 0;
			for(user in userListObj) {
				if (trim(userListObj[user][field]) == trim(match)) { return (returnObj ? userListObj[user] : i); }
				i++;
			}
			return undefined;
		}
	
	
	
	
	
	
	
	
	
	
	
	
	
	// fetch user infos from the db - this is synchroneous
	function getUserInfo(id) {
	    var xml = new JKL.ParseXML("api/users.php?cmd=getUserInfo&id="+id);
	    var data = xml.parse();
	    tmp_str = "";
	    if (data.nCube.userlist.response != "ERROR") {
			if (data.nCube.userlist.response != "No Match") {
				if (data.nCube.userlist.response) {
				    return data.nCube.userlist.response.user;
				} else { return "No Match"; }
			} else { return "No Match"; }
	    } else { return "ERROR"; }
	}
	
	// asynchroneous version of the above function
	function getUserInfoAsync(id, callback) {
	    var xml = new JKL.ParseXML("api/users.php?cmd=getUserInfo&id="+id);
		
		var aFunc = function(data) {
			
			tmp_str = "";
			if (data.nCube.userlist.response != "ERROR") {
				if (data.nCube.userlist.response != "No Match") {
					if (data.nCube.userlist.response) {
						callback(data.nCube.userlist.response.user);
					} else { callback("No Match"); }
				} else { callback("No Match"); }
			} else { callback("ERROR"); }
			
		};
		xml.async(aFunc);
	    xml.parse();
	}
	
	
	
	
	
	
	
	
	
	
		// user infos ----------------------------------------
	
		function getDefPic(uname, upic, gender, frisky) {
			gender = parseInt(gender);
			if (frisky) {
				return "file=default_frisky.jpg";
			//	if (gender == 1) { return "file=frs_default_male.jpg"; }
			//	else if (gender == 2) { return "file=frs_default_female.jpg"; }
			//	else if (gender == 3) { return "file=frs_default_couple.jpg"; }
			//	else if (gender == 4) { return "file=frs_default_female_couple.jpg"; }
			//	else { return "file=unknown.jpg"; }
			} else if (upic == undefined) {
				if (gender == 1) { return "file=default_male.jpg"; }
				else if (gender == 2) { return "file=default_female.jpg"; }
				else if (gender == 3) { return "file=default_couple.jpg"; }
				else if (gender == 4) { return "file=default_female_couple.jpg"; }
				else if (gender == 5) { return "file=default_trans.jpg"; }
				else { return "file=unknown.jpg"; }
			} else { return "user="+uname+"&file="+upic; }
		}


		// this version allows stuff you probably dont want to see. no time to modify func above
		function getDefPicFrs(uname, upic, gender, frisky) {
			gender = parseInt(gender);
			if (!upic) {
				if (frisky) {
				//	return "file=default_frisky.jpg";
					if (gender == 1) { return "file=frs_default_male.jpg"; }
					else if (gender == 2) { return "file=frs_default_female.jpg"; }
					else if (gender == 3) { return "file=frs_default_couple.jpg"; }
					else if (gender == 4) { return "file=frs_default_female_couple.jpg"; }
					else if (gender == 5) { return "file=frs_default_trans.jpg"; }
					else { return "file=unknown.jpg"; }
				} else if (upic == undefined) {
					if (gender == 1) { return "file=default_male.jpg"; }
					else if (gender == 2) { return "file=default_female.jpg"; }
					else if (gender == 3) { return "file=default_couple.jpg"; }
					else if (gender == 4) { return "file=default_female_couple.jpg"; }
					else if (gender == 5) { return "file=default_trans.jpg"; }
					else { return "file=unknown.jpg"; }
				}
			} else { return "user="+uname+"&file="+upic; }
		}

	
	
		function getGender(val) {
			switch(parseInt(val)) {
				case 1 :	return "Homme"; break;
				case 2 :	return "Femme"; break;
				case 3 :	return "Couple d'Hommes"; break;
				case 4 :	return "Couple de Femmes"; break;
				case 5 :	return "Travesti / Transexuel"; break;
				case 6 :	return "Transexuel"; break;
				default: 	return "Non Mentionné"; break;
			}
		}







////////////////////////////////// FIELD NAMES ////////////////////////////////////////








	// psychologic portrait flags

	var PSY_EXTROVERSION_MIN 	= 1;
	var PSY_EXTROVERSION_AVG 	= 2;
	var PSY_EXTROVERSION_MAX 	= 4;

	var PSY_EXPERIENCING_MIN 	= 8;
	var PSY_EXPERIENCING_AVG 	= 16;
	var PSY_EXPERIENCING_MAX 	= 32;

	var PSY_IMAGINATION_MIN 	= 64;
	var PSY_IMAGINATION_AVG 	= 128;
	var PSY_IMAGINATION_MAX 	= 256;

	var PSY_ROMANTISM_MIN 	= 512;
	var PSY_ROMANTISM_AVG 	= 1024;
	var PSY_ROMANTISM_MAX 	= 2048;





	// seeking-for flags

	var SEEK_STD_NOP = 1; // no pref
	var SEEK_STD_MAN = 2; // seeking men
	var SEEK_STD_WOM = 4; // seeking women
	var SEEK_STD_CPL = 8; // seeking coupls (vague v1 pref - deprecated)
	
	var SEEK_STD_TSV = 256; // v2 seeking trans
	var SEEK_STD_CPL_M = 512; // v2 seeking cpl men
	var SEEK_STD_CPL_F = 1024; // v2 seeking couple wom
	var SEEK_STD_CPL_H = 2048; // v2 seeking hetero couple

	var SEEK_FRS_NOP = 16;
	var SEEK_FRS_MAN = 32;
	var SEEK_FRS_WOM = 64;
	var SEEK_FRS_CPL = 128;

	var SEEK_FRS_TSV = 4096;
	var SEEK_FRS_CPL_M = 8192;
	var SEEK_FRS_CPL_F = 16384;
	var SEEK_FRS_CPL_H = 32768;

	// Seeking Relation type (general)

	var RLTN_STD_FRN = 1;		// friendship
	var RLTN_STD_LOV = 2;		// love / dating
	var RLTN_STD_OUT = 4;		// outings
	var RLTN_STD_SOC = 8;		// social
	var RLTN_STD_COR = 16;		// correspondance
	var RLTN_STD_TRV = 32;		// travel


	// relation type (frisky)

	var RLTN_FRS_NOT = 64;		// Je vous dirai plus tard
	var RLTN_FRS_WEB = 128;		// Sexe 'virtuel'/webcam
	var RLTN_FRS_SAF = 256;		// safe - Embrasser/Toucher
	var RLTN_FRS_SEX = 512;		// Sexe
	var RLTN_FRS_3SM = 1024;		// 3 some - à trois
	var RLTN_FRS_SWG = 2048;		// swigner - Echangisme
	var RLTN_FRS_SNM = 4096;		// s&m - domination / soumission
	var RLTN_FRS_FSH = 8192;		// fétiches 














	// Bit masks

	function SetFlag(flag, flags, mark) {
		if (mark) {
			// Mark is true, set the flag.
			if (!(flags & flag)) { flags = (flags | flag); }
		} else {
			// mark is false, remove the flag
			if (flags & flag) { flags = (flags & ~flag); }
		}
		return flags;
	}


	function IfFlagged(flag, flags) {
		if (flags & flag) { return true; } else { return false; }
	}




	// no need for it being done in js -- managed by php user api
	/*
	function getAstro(timestamp, imgname) {


		day = date("d",timestamp);
		month = date("m",timestamp);


		Offset = floor(((((mktime( 0, 0, 0, $month, $day, 0 ) - mktime( 0, 0, 0, 1, 0, 0 ))) / 60) / 60) / 24); 


		// Lookup the Sign based on the 
		// number of days past Jan 1 

		if ( Offset >= 0 )   { Sign = "capricorne";		img = "capricorn"; }
		if ( Offset >= 20 )  { Sign = "Verseau"; 		img = "aquarius"; }
		if ( Offset >= 50 )  { Sign = "Poisson"; 		img = "pisces"; }
		if ( Offset >= 81 )  { Sign = "Bélier"; 		img = "aries"; }
		if ( Offset >= 110 ) { Sign = "Taureau"; 		img = "taurus"; }
		if ( Offset >= 141 ) { Sign = "Gémeaux "; 		img = "gemini"; }
		if ( Offset >= 173 ) { Sign = "Cancer"; 		img = "cancer"; }
		if ( Offset >= 204 ) { Sign = "Lion"; 			img = "leo"; }
		if ( Offset >= 235 ) { Sign = "Vierge"; 		img = "virgo"; }
		if ( Offset >= 266 ) { Sign = "Balance"; 		img = "libra"; }
		if ( Offset >= 296 ) { Sign = "Scorpion"; 		img = "scorpio"; }
		if ( Offset >= 327 ) { Sign = "Sagittaire"; 	img = "sagittarius"; }
		if ( Offset >= 357 ) { Sign = "Capricorne"; 	img = "capricorn"; }

		// 
		// Results 
		// 

		if (imgname) { return img; } else { return Sign; }

	}
																*/






	function getSeeking(val) {

		val = parseInt(val);
		if (IfFlagged(SEEK_STD_NOP, val)) { return "pas de préf."; }
		else {
			str = "";
			if (IfFlagged(SEEK_STD_MAN, val)) { str += "hommes"; }
			if (IfFlagged(SEEK_STD_WOM, val)) { if (str != "") { str += ", "; } str += "femmes"; }
			if (IfFlagged(SEEK_STD_CPL, val)) { if (str != "") { str += ", "; } str += "couples"; }
		}
		return str;
	}








	function getSeekingFrs(val) {
		val = parseInt(val);
		if (IfFlagged(SEEK_FRS_NOP, val)) { return "pas de préf."; }
		else {
			str = "";
			if (IfFlagged(SEEK_FRS_MAN, val)) { str += "hommes"; }
			if (IfFlagged(SEEK_FRS_WOM, val)) { if (str != "") { str += ", "; } str += "femmes"; }
			if (IfFlagged(SEEK_FRS_CPL, val)) { if (str != "") { str += ", "; } str += "couples"; }
		}
		return str;
	}






	function getSpoken(val) {
		switch(parseInt(val)) {
			case 0 :	return "bilingue"; break;
			case 1 :	return "français"; break;
			case 2 : 	return "anglais"; break;
			case 3 :	return "bilingue"; break;
			default:	return "(inconnu)"; break;
		}
	}




	function getOrientation(val, sex) {
		sex = parseInt(sex);
		switch(parseInt(val)) {
			case 1 :	if (sex == 1) { return "Hétérosexuel"; } else if (sex == 2) { return "Hétérosexuelle"; } else { return "Hétérosexuel(le)"; } break;
			case 2 : 	if (sex == 1) { return "Gay"; } else if (sex == 2) { return "Lesbienne"; } else { return "Gay/Lesbienne"; } break;
			case 3 :	if (sex == 1) { return "Bisexuel"; } else if (sex == 2) { return "Bisexuelle"; } else { return "Bisexuel(le)"; } break;
			default:	if (sex == 1) { return "Hétérosexuel"; } else if (sex == 2) { return "Hétérosexuelle"; } else { return "Hétérosexuel(le)"; } break;
		}
	}



	/* handled by user api
	  
	function getAge(val) {


	//	return date('Y') - date('Y', $val) - 1 + (int)((date('m', $val) <= date('m')) && (date('d', $val) <= date('d')));  


		$now = time();

		$age = floor(($now - $val) / 31536000);

		return $age;

	}
																																					 */




	function getMatrimonial(val) {
		switch(parseInt(val)) {
			case 1 :	return "Célibataire"; break;
			case 2 :	return "Marié(e)"; break;
			case 3 :	return "Divorcé(e)"; break;
			case 4 :	return "Veuf / Veuve"; break;
			case 5 :	return "Autre"; break;
			case 6 :	return "En Couple"; break;
			case 7 :	return "Séparé(e)"; break;
			default: 	return "Non Mentionné"; break;
		}
	}






	function getReligion(val) {
		switch(parseInt(val)) {
			case 1 :	return "Catholique"; break;
			case 2 :	return "Protestant(e)"; break;
			case 3 :	return "Juif(ve)"; break;
			case 4 :	return "Boudiste"; break;
			case 5 :	return "Musulman(e)"; break;
			case 6 :	return "Athée"; break;
			case 10:	return "Agnostique"; break;
 			case 7 :	return "Hindouiste"; break;
			case 8 :	return "Orthodoxte"; break;
			case 9 :	return "Autre"; break;
			default:	return "Non Mentionné"; break;
		}
	}






	function getProfession(val) {
		switch(parseInt(val)) {
			case 1 :	return "Salarié(e)"; break;
			case 2 :	return "Etudiant(e)"; break;
			case 3 :	return "Indépendant(e)"; break;
			case 4 :	return "Sans-Emploi"; break;
			case 5 :	return "Professionnel"; break;
			case 6 :	return "Travailleur(se) Autonome"; break;
			case 7 :	return "Retraité(e)"; break;
			case 8 :	return "Autre"; break;
			default:	return "Non Mentionné"; break;
		}
	}








	function getStudies(val) {
		switch(parseInt(val)) {
			case 1 :	return "Primaire"; break;
			case 2 :	return "Secondaire"; break;
			case 3 :	return "Cégep"; break;
			case 4 :	return "Baccalauréat"; break;
			case 5 :	return "Maîtrise"; break;
			case 6 :	return "Doctorat"; break;
			case 7 :	return "Autre"; break;
			default:	return "Non Mentionné"; break;
		}
	}









	function getHousing(val) {
		switch(parseInt(val)) {
			case 1 :	return "Appartement"; break;
			case 2 :	return "Maison"; break;
			case 3 :	return "Maison Louée"; break;
			case 4 :	return "Condo"; break;
			case 5 :	return "Colocation"; break;
			case 6 :	return "Autre"; break;
			default:	return "Non Mentionné"; break;
		}
	}









	function getChilds(val) {
		switch(parseInt(val)) {
			case 1 :	return "Aucun"; break;
			case 2 :	return "1 enfant"; break;
			case 3 :	return "2 enfants"; break;
			case 4 :	return "3 ou plus"; break;
			case 5 :	return "1 à Charge"; break;
			case 6 :	return "2 à Charge"; break;
			case 7 :	return "3+ à Charge"; break;
			case 8 :	return "Autre"; break;
			default:	return "Non Mentionné"; break;
		}
	}





	function getWants_Chldr(val) {
		switch(parseInt(val)) {
			case 1 :	return "Non"; break;
			case 2 :	return "Oui"; break;
			case 3 :	return "Un jour, peut-être"; break;
			default:	return "Non Mentionné"; break;
		}
	}




	function getAlcohol(val) {
		switch(parseInt(val)) {
			case 1 :	return "Non"; break;
			case 2 :	return "A l'Occasion"; break;
			case 3 :	return "En Social"; break;
			case 4 :	return "Régulier"; break;
			default:	return "Non Mentionné"; break;
		}
	}




	function getSmoking(val) {
		switch(parseInt(val)) {
			case 1 :	return "Non"; break;
			case 2 :	return "A l'Occasion"; break;
			case 3 :	return "Régulier"; break;
			default:	return "Non Mentionné"; break;
		}
	}







	function getEyes(val) {
		switch(parseInt(val)) {
			case 1 :	return "Bleus"; break;
			case 2 :	return "Verts"; break;
			case 3 :	return "Pers"; break;
			case 4 :	return "Marrons"; break;
			case 5 :	return "Noirs"; break;
			case 6 :	return "Gris"; break;
			case 7 :	return "Autre"; break;
			default:	return "Non Mentionné"; break;
		}
	}






	function getHair(val) {
		switch(parseInt(val)) {
			case 1 :	return "Noirs"; break;
			case 2 :	return "Bruns"; break;
			case 3 :	return "Chatains"; break;
			case 4 :	return "Blonds"; break;
			case 5 :	return "Cendrés"; break;
			case 6 :	return "Poivre et Sel"; break;
			case 7 :	return "Blancs"; break;
			case 8 :	return "Roux"; break;
			case 9 :	return "Auburn"; break;
			case 10:	return "Rouges"; break;
			case 11:	return "Prune"; break;
			case 12:	return "Autre"; break;
			default:	return "Non Mentionné"; break;
		}
	}



/* stupid internet explorer crashing because an object, far far in a scope light-years away, is defined with the same name.

	feet = 12;				--> ie says unidentified object doesnt support this property on bogus line 1902689384

	feet -> rename fee_;	--> ie is happy.

	Msft fucktards.

*/

	function getHeight(val) {
		val = parseInt(val);
		if (val > 0) {
			fee_ = Math.floor(val/12);
			in_ = Math.round(((val/12) - fee_)*12);
			hei_ = fee_+"&#39; "+in_+"&quot;";
		} else { hei_ = 0; }
		return hei_;
	}



	function getFeets(val) {
		fee_ = Math.floor(parseInt(val)/12);
		return fee_;
	}


	function getInches(val) {
		fee_ = Math.floor(parseInt(val)/12);
		in_ = ((parseInt(val)/12) - fee_)*12;
		return Math.round(in_);
	}



	function getBody_type(val) {
		switch(parseInt(val)) {
			case 1 :	return "Mince"; break;
			case 2 :	return "Athlétique"; break;
			case 3 :	return "Moyen"; break;
			case 4 :	return "Un peu enrobé"; break;
			case 5 :	return "Encore plus a aimer !"; break;
			case 6 :	return "Autre"; break;
			default:	return "Non Mentionné"; break;
		}
	}





	function getWeight(val) {
		switch(parseInt(val)) {
			case 1 :	return "moins de 90 lbs"; break;
			case 2 :	return "90 - 100 lbs"; break;
			case 3 :	return "100 - 110 lbs"; break;
			case 4 :	return "110 - 120 lbs"; break;
			case 5 :	return "120 - 130 lbs"; break;
			case 6 :	return "130 - 140 lbs"; break;
			case 7 :	return "140 - 150 lbs"; break;
			case 8 :	return "150 - 160 lbs"; break;
			case 9 :	return "160 - 170 lbs"; break;
			case 10:	return "170 - 180 lbs"; break;
			case 11:	return "180 - 190 lbs"; break;
			case 12:	return "190 - 200 lbs"; break;
			case 13:	return "200 - 210 lbs"; break;
			case 14:	return "210 - 220 lbs"; break;
			case 15:	return "220 - 230 lbs"; break;
			case 16:	return "230 - 240 lbs"; break;
			case 17:	return "240 - 250 lbs"; break;
			case 18:	return "250 - 260 lbs"; break;
			case 19:	return "plus de 260 lbs"; break;
			default:	return "Non Mentionné"; break;
		}
	}





	function getEth_group(val, sex) {
		sex = parseInt(sex);
		switch(parseInt(val)) {
			case 1 :	return "Blanc"+(sex == 2 ? "he" : ""); break;
			case 2 :	return "Noir"+(sex == 2 ? "e" : ""); break;
			case 3 :	return "Asiatique"; break;
			case 4 :	return "Hispanique / Latino"; break;
			case 5 :	return "Premieres Nations"; break;
			case 6 :	return "Inde"; break;
			case 7 :	return "Arabique"; break;
			case 8 :	return "Mixte/Mulâtre"; break;
			case 9 :	return "Iles du pacifique"; break;
			case 10:	return "Autre"; break;
			default:	return "Non Mentionné"; break;
		}
	}





	function getAppearance(val) {
		switch(parseInt(val)) {
			case 1 :	return "Top Modèle"; break;
			case 2 :	return "Belle Apparence"; break;
			case 3 :	return "Agréable"; break;
			case 4 :	return "Moyen"; break;
			case 5 :	return "Bof..."; break;
			case 6 :	return "Autre"; break;
			default:	return "Non Mentionné"; break;
		}
	}






	function getStyle(val) {
		switch(parseInt(val)) {
			case 1 :	return "Bon Chic Bon Genre"; break;
			case 2 :	return "Classique"; break;
			case 3 :	return "Sportif"; break;
			case 4 :	return "Excentrique"; break;
			case 5 :	return "Marginal"; break;
			case 6 :	return "Designer à mes heures!"; break;
			case 7 :	return "Tout ce qui se porte"; break;
			case 8 :	return "Indescriptible.."; break;
			case 9 :	return "Autre"; break;
			default:	return "Non Mentionné"; break;
		}
	}






	
