//var FR_SERVER_URL = "http://localhost:8080/social-service/";
var FR_SERVER_URL = "http://justlocate.com/social-service/";
var FR_SERVICE_URL = FR_SERVER_URL+"FriendService";
var FR_IMG_URL = FR_SERVER_URL+"img/";
var FRRequest = new Object();
var FR_IS_LIVE = true;

/*var init = function(){
	var userId = 48763062;//223177463;//134223350;//330343129;
	var consumer_key = "http://www.myspace.com/362820325";//"http://www.myspace.com/330787305";
	var consumer_secret = "672aae8231174b66b0ef7e4e6e5674c7";//"074cdaac849d408d8068cee292fae325";
	var friend_selector = new FriendSelector("allContent", 3, 4);
	friend_selector.init();
	friend_selector.draw();
}*/

/**
* You are advised to create an instance of FriendSelector class in the
* init function of your application and to call the init() method of the
* created instance, for your application to perform better.
* Call the draw() method of your friend_selector object when you want to
* see the user's friend list on your web page.
* the getFrinedList() method returns the whole friend list
* the getSelectedFrineds() method returns the selected friend list at the current time
*/
function FriendSelector(containerId, row_count, col_count, posCriteria){
	
	var self = this;
	var selectedFriends = [];
	var friendList = [];
	var topFriendList = [];
	var alphabetGroups = {"a":[],"b":[],"c":[],"d":[],"e":[],"f":[],"g":[],"h":[],"i":[],"j":[],"k":[],"l":[],
	"m":[],"n":[],"o":[],"p":[],"q":[],"r":[],"s":[],"t":[],"u":[],"v":[],"w":[],"x":[],"y":[],"z":[],"#":[]};
	var currentList = [];
	var onlineList = [];		//for "online" citeria
	var offlineList = [];		//for "offline" citeria
	var wholeList = [];			//for "all" citeria
	var friendCount = null;
	var selectedCount = 0;
	var listName = "all";
	var pagesFrom = 0;
	var actPage = 0;
	var container = null;
	var visiblePageCount = 5;
	var colCount = null;
	var rowCount = null;
	var items_per_page = null;
	var alphabet = ["a","b","c","d","e","f","g","h","i","j","k","l","m",
				"n","o","p","q","r","s","t","u","v","w","x","y","z"];
	var drawCalled = 0;
	/*-------------params for retrieving friend list------------*/
	var defaultPageSize = 100;
	var loadedPageNumber = 0;
	/*------params for the separate view of selected friends----*/
	var selRowCount = null;
	var selColCount = null;
	var selItems_per_page = null;
	var selPagesFrom = 0;
	var selActPage = 0;
	var visPageCntForSel = 3;
	/*------params for "fr_paging" div's constant width and height----*/
	var fr_paging_width = null;
	var fr_paging_height = null;
	var item_width = 73;
	/*------params to define the open social container----*/
	var containerDomain = null;
	/*---params to define whether the container does not respond---*/
	var globalError = 0;
	
	
	this.init = function(){
		if(typeof gadgets == "undefined"){
			FR_IS_LIVE = false;
		}
		var env = opensocial.getEnvironment();
		containerDomain = env.getDomain();
		container = document.getElementById(containerId);
		container.setAttribute("style", "font-family:tahoma");
		if(col_count == null || typeof col_count == "undefined"){
			colCount = 6;
		}else{
			colCount = col_count;
		}
		if(row_count == null || typeof row_count == "undefined"){
			rowCount = 4;
		}else{
			rowCount = row_count;
		}
		items_per_page = rowCount*colCount;
		switch(rowCount){
			case 1: selRowCount = 2; break;
			case 2: selRowCount = 3; break;
			case 3: selRowCount = 5; break;
			case 4: selRowCount = 7; break;
			case 5: selRowCount = 9; break;
			case 6: selRowCount = 10; break;
			case 7: selRowCount = 12; break;
			default: selRowCount = 5;
		}
		selColCount = 3;
		selItems_per_page = selRowCount*selColCount;
		if(posCriteria == null || typeof posCriteria == "undefined"){
			posCriteria = "left";
		}
		fr_paging_height = rowCount*90 + 30;
		fr_paging_width = colCount*item_width > 380 ? colCount*item_width : 380;
		req_getTopFriends();
	}
	
	
	var getFriendList_iterativeReq = function(page){
		var req = opensocial.newDataRequest();
		var params = {};
		params[opensocial.DataRequest.PeopleRequestFields.FIRST] = page*defaultPageSize+(containerDomain == "myspace.com" ? 1 : 0);
		params[opensocial.DataRequest.PeopleRequestFields.MAX] = defaultPageSize;
		if(containerDomain != "myspace.com"){
			params[opensocial.DataRequest.PeopleRequestFields.PROFILE_DETAILS]= [opensocial.Person.Field.PROFILE_URL];
		}
		var idspec = getIdSpec("VIEWER");
		req.add(req.newFetchPeopleRequest(containerDomain=="friendster.com" ? "VIEWER_FRIENDS" : idspec, params), "friends");
		req.send(getFriendList_iterativeResp);
	}
	
	var getFriendList_iterativeResp = function(resp){
		var friends = resp.get("friends").getData().asArray();
		friendCount = resp.get("friends").getData().getTotalSize();
		if(loadedPageNumber == 1){
			friendList = [];
			for(var i = 0; i < alphabet.length; i++){
				alphabetGroups[alphabet[i]] = [];
			}
			alphabetGroups["#"] = [];
		}
		for(var i = 0; i < friends.length; i++){
			friends[i].index = (loadedPageNumber-1)*defaultPageSize + i;
			var id = friends[i].fields_.id;
			friends[i].fields_.id = id.match(":") ? id.substring(id.indexOf(":")+1) : friends[i].getId();
			friendList.push(friends[i]);
		}
		fillAlphabetGroups(friends);
		defineCurrentList();
		if(drawCalled == 1){
			putEvents();
		}else if(drawCalled == "ok"){
			self.drawPaging(pagesFrom, actPage);
		}
		var stillLoading = document.getElementById("fr_stillLoading");
		if(friendList.length < friendCount){
			if(stillLoading){
				stillLoading.innerHTML = "<span style='letter-spacing:2px;'>L<img src='"+FR_IMG_URL+"loading.png' height='10px' />ading</span>... "+
										"<span>"+friendList.length+" of "+friendCount+"</span>";
			}
			getFriendList_iterativeReq(loadedPageNumber++);
		}else{
			for(var i = 0; i < alphabet.length; i++){
				if(alphabetGroups[alphabet[i]].length == 0){
					var letter = document.getElementById("fr_alphaGroup"+i);
					if(letter){
						letter.parentNode.removeChild(letter);
					}
				}
			}
			if(alphabetGroups["#"].length == 0){
				var sharp= document.getElementById("fr_#page");
				if(sharp){
					sharp.parentNode.removeChild(sharp);
				}
			}
			if(friendCount == 0){
				var fr_paging = document.getElementById("fr_paging");
				if(fr_paging){
					fr_paging.innerHTML = "<span style='font-size:13px;background:#F0F0F0 none repeat scroll 0;border:1px solid gray;'>Your friend list is empty</span>";
				}
			}
			if(stillLoading){
				stillLoading.innerHTML = "";
			}
		}
	}
	
	var req_getTopFriends = function(){
		var req = opensocial.newDataRequest();
		var params = {};
		params[opensocial.DataRequest.PeopleRequestFields.FILTER] = opensocial.DataRequest.FilterType.TOP_FRIENDS;
		if(containerDomain != "myspace.com"){
			params[opensocial.DataRequest.PeopleRequestFields.PROFILE_DETAILS]= [opensocial.Person.Field.PROFILE_URL];
		}
		var idspec = getIdSpec("VIEWER");
		req.add(req.newFetchPeopleRequest(containerDomain=="friendster.com" ? "VIEWER_FRIENDS" : idspec, params), "friends");
		req.send(resp_getTopFriends);
	}
	
	var resp_getTopFriends = function(response){
		if(response.globalError_ && globalError <= 3){
			globalError++;
			sleep(4000);
			req_getTopFriends();
			return;
		}else if(globalError > 3){
			var fr_paging = document.getElementById("fr_paging");
			if(fr_paging){
				fr_paging.innerHTML = "<span style='font-size:13px;background:#F0F0F0 none repeat scroll 0;border:1px solid gray;'>The server does not respond, please refresh the page.</span>";
			}
			return;
		}
		topFriendList = response.get("friends").getData().asArray();
		friendCount = response.get("friends").getData().getTotalSize();
		for(var i = 0; i < topFriendList.length; i++){
			topFriendList[i].index = i;
			var id = topFriendList[i].fields_.id;
			topFriendList[i].fields_.id = id.match(":") ? id.substring(id.indexOf(":")+1) : topFriendList[i].getId();
		}
		for(var i = 0; i < topFriendList.length; i++){
			friendList[i] = topFriendList[i];
		}
		fillAlphabetGroups(friendList);
		var stillLoading = document.getElementById("fr_stillLoading");
		if(friendList.length < friendCount){
			if(stillLoading){
				stillLoading.innerHTML = "<span style='letter-spacing:2px;'>L<img src='"+FR_IMG_URL+"loading.png' height='10px' />ading</span>... "+
										"<span>"+friendList.length+" of "+friendCount+"</span>";
			}
		}
		if(drawCalled == 1){
			putEvents();
		}else if(drawCalled == "ok"){
			self.drawPaging(pagesFrom, actPage);
		}
		getFriendList_iterativeReq(loadedPageNumber++);
	}
	
	var getIdSpec = function(id){
		//create the parameters for the idspec to send into the fetch app data request
		var idParams = {};
		idParams[opensocial.IdSpec.Field.USER_ID] = opensocial.IdSpec.PersonId[id];
		idParams[opensocial.IdSpec.Field.NETWORK_DISTANCE] = 1;
		idParams[opensocial.IdSpec.Field.GROUP_ID] = 'FRIENDS';
		//create the idspec
		var idspec = opensocial.newIdSpec(idParams);
		return idspec;
	}

	this.draw = function(){
		drawCalled = 1;
		var str = "<table><tbody><tr>"+
		"<td class='fr_parentTd' colspan='2'>"+
			"<table><tbody><tr"+(posCriteria=="top" ? "" : " style='display:none;'")+">"+
					"<td style='display:none;'>"+
						"<div style='margin:5px;margin-bottom:35px;'>"+
							"<div align='center' style='margin-bottom:5px;'>Select</div>"+
							"<div style='border:1px solid gray;background:#E8F2FE;'>"+
								"<div class='fr_online'><input id='fr_online' type='radio' name='fr_online' value='online' />online</div>"+
								"<div class='fr_online'><input id='fr_offline' type='radio' name='fr_online' value='offline' />offline</div>"+
								"<div class='fr_online'><input id='fr_all' type='radio' name='fr_online' value='all' checked />all</div>"+
							"</div>"+
						"</div>"+
					"</td>"+
					(posCriteria=="top" ? "" : "</tr><tr>")+
					"<td>"+
						"<div style='padding:5px;margin:5px;border:1px solid gray;background:#f7f5f5;width:145px;'>"+
							"<div><input id='fr_typeSearch' class='fr_nameInput_inact' type='text' value='Search by name' style='width:145px;' /></div>"+
						"</div>"+
					"</td>"+
					(posCriteria=="top" ? "" : "</tr><tr>")+
					"<td style='position:relative;'>"+
						"<div id='fr_stillLoading' style='font-size:13px;color:gray;"+(posCriteria=="top" ? "" : "position:relative;top:"+(fr_paging_height-15)+"px;left:15px;")+"'>"+
							(friendCount == null || friendList.length < friendCount ? "<span style='letter-spacing:2px;'>L<img src='"+FR_IMG_URL+"loading.png' height='10px' />ading</span>... " : "")+
						"</div>"+
					"</td>"+
			"</tr></tbody></table>"+
		"</td>"+
		(posCriteria=="top" ? "</tr><tr>" : "")+
		"<td id='fr_contentTd' class='fr_parentTd'>"+
			"<div style='font-size:13px;border:2px solid lightgray;padding-bottom:2px;padding-top:2px;'>"+
				"<div style='margin-bottom:5px;'>"+
					"<span id='fr_selectedFr' class='fr_paging_inact' style='display:none'>Show selected</span>"+
					"<span id='fr_selAll' class='fr_paging_inact'>Select all</span>&nbsp|&nbsp"+
					"<span id='fr_deselAll' class='fr_paging_inact'>Deselect all</span>"+
				"</div>"+
				"<div id='fr_alphaListing'></div>"+
			"</div>"+
			"<div id='fr_paging' style='margin-top:5px;height:"+fr_paging_height+"px;width:"+fr_paging_width+"px;position:relative;'>"+
				(globalError > 3 ? "<span style='font-size:13px;background:#F0F0F0 none repeat scroll 0;border:1px solid gray;'>The server does not respond, please refresh the page.</span>" : (friendCount==0 ? "<span style='font-size:13px;background:#F0F0F0 none repeat scroll 0;border:1px solid gray;'>Your friend list is empty</span>" : ""))+
			"</div>"+
		"</td>"+
		"<td class='fr_parentTd'>"+
			"<div id='fr_watchSelected' class='fr_watchSel'>Selected "+selectedCount+" friends</div>"+
			"<div id='fr_selDetail' style='width:152px;height:"+fr_paging_height+"px;position:relative;'></div>"+
		"</td>"+
		"</tr></tbody></table>";
		container.innerHTML = str;
		
		if(friendList.length == friendCount){
			putEvents();
		}
	}
	
	var putEvents = function(){
		drawCalled = "ok";
		var listing = document.getElementById("fr_alphaListing");
		var str = "<span id='fr_topFr' class='fr_paging_inact' style='font-wieght:bold;'>Top</span>"+
				"<span id='fr_allFr' class='fr_act_page' style='font-wieght:bold;margin:0px 15px;'>All</span>"+
				"<span>";
		for(var i = 0; i < alphabet.length; i++){
			str += "<span id='fr_alphaGroup"+i+"' letter='"+alphabet[i]+"' class='fr_inact_page'>"+alphabet[i].toUpperCase()+"</span>";
		}
		str += "<span id='fr_#page' class='fr_paging_inact'>#</span>";
		listing.innerHTML = str;

		document.getElementById("fr_paging").innerHTML = "";
		var online = document.getElementById("fr_online");
		online.onclick = function(){
							self.showOnlineOffline("online");
						}
		var offline = document.getElementById("fr_offline");
		offline.onclick = function(){
							self.showOnlineOffline("offline");
						}
		var all = document.getElementById("fr_all");
		all.onclick = function(){
							self.showOnlineOffline("all");
						}	
		var typeSearch = document.getElementById("fr_typeSearch");
		typeSearch.onkeyup = function(){
								self.onTypeSearch(this.value);
							}
		typeSearch.onfocus = function(){
								if(this.className == "fr_nameInput_inact"){
									this.value = "";
									this.className = "fr_nameInput_act";
									var u = 0;
								}
							}
		typeSearch.onblur = function(){
								if(this.value == ""){
									this.value = "Search by name";
									this.className = "fr_nameInput_inact";
								}
							}
		var allFriends = document.getElementById("fr_topFr");
		allFriends.onclick = function(){
								self.createPaging("top");
							}
		var allFriends = document.getElementById("fr_allFr");
		allFriends.onclick = function(){
								self.createPaging("all");
							}
		var selectedFriends = document.getElementById("fr_selectedFr");
		selectedFriends.onclick = function(){
									self.createPaging("selected");
								}
		var selAll = document.getElementById("fr_selAll");
		selAll.onclick = function(){
							self.selectAll();
						}
		var deselAll = document.getElementById("fr_deselAll");
		deselAll.onclick = function(){
							self.deselectAll();
						}
		for(var i = 0; i < alphabet.length; i++){
			var page = document.getElementById("fr_alphaGroup"+i);
			if(page){
				page.onclick = function(){
							self.createPaging(this.getAttribute("letter"));
						}
			}
		}
		var sharp = document.getElementById("fr_#page");
		if(sharp){
			sharp.onclick = function(){
							self.createPaging("#");
						}
		}

		self.createPaging("all");
	}
	
	this.createPaging = function(_listName){
		listName = _listName;
		defineCurrentList();
		setActivePaging();
		
		var online = document.getElementsByName("fr_online");
		for(var i = 0; i < online.length; i++){
			if(online[i].checked){
				online = online[i].value;
				break;
			}
		}
		self.showOnlineOffline(online);
	}
	
	var defineCurrentList = function(){
		if(listName=="all"){
			currentList = [];
			for(var i = 0; i < friendList.length; i++){
				currentList.push(friendList[i]);
			}
		}else if(listName=="top"){
			currentList = [];
			for(var i = 0; i < topFriendList.length; i++){
				currentList.push(topFriendList[i]);
			}
		}else if(listName=="selected"){
			currentList = [];
			for(var i = 0; i < selectedFriends.length; i++){
				currentList.push(selectedFriends[i]);
			}
		}else if(listName=="#"){
			var list = alphabetGroups["#"];
			currentList = [];
			for(var i = 0; i < list.length; i++){
				currentList.push(list[i]);
			}
		}else{
			for(var i = 0; i < alphabet.length; i++){
				if(listName==alphabet[i]){
					var list = alphabetGroups[listName];
					currentList = [];
					if(list){
						for(var i = 0; i < list.length; i++){
							currentList.push(list[i]);
						}
					}
					break;
				}
			}
		}
		getOnlineOffline();
	}
	
	var setActivePaging = function(){
		var selectAll = document.getElementById("fr_allFr");
		var selectTop = document.getElementById("fr_topFr");
		var showSelected = document.getElementById("fr_selectedFr");
		var sharp = document.getElementById("fr_#page");
		var alphaArray = [];
		selectAll.className = listName == "all" ? "fr_act_page" : "fr_paging_inact";
		selectTop.className = listName == "top" ? "fr_act_page" : "fr_paging_inact";
		showSelected.className = listName == "selected" ? "fr_act_page" : "fr_paging_inact";
		if(sharp){
			sharp.className = listName == "#" ? "fr_act_page" : "fr_paging_inact";
		}
		for(var i = 0; i < alphabet.length; i++){
			var letter = document.getElementById("fr_alphaGroup"+i);
			if(letter){
				letter.className = listName == alphabet[i] ? "fr_act_page" : "fr_paging_inact";
			}
		}
	}
	
	this.drawPaging = function(_pagesFrom, _actPage){
		pagesFrom = _pagesFrom;
		actPage = _actPage;
		var container = document.getElementById("fr_paging");
		var pageCount = Math.ceil(currentList.length/items_per_page);
		var pagesTo = visiblePageCount;
		if(pageCount - pagesFrom < visiblePageCount){
			pagesTo = pageCount - pagesFrom;
		}
		
		str = "<div id='fr_container'></div>"+
				"<div style='height:20px;width:100%;position:absolute;top:"+(fr_paging_height-24)+"px;left:0px;'>"+
					(pagesFrom!=0 ? "<span id='fr_previous' style='cursor:pointer;float:left;'>Previous</span>... " : "")+
					"<span id='fr_pages'>";
		for(var i = pagesFrom; i < pagesFrom+pagesTo; i++){
			str += "<span id='fr_page"+i+"' index='"+i+"' class='"+(i==pagesFrom ? "fr_act_page" : "fr_inact_page")+"'>"+(i+1)+"</span> ";
		}
		str += "</span>"+
				(pageCount-pagesFrom>visiblePageCount ? " ...<span id='fr_next' style='cursor:pointer;float:right;margin-top:-20px'>Next</span>" : "")+
				"</div>";
		container.innerHTML = str;
		
		var prev = document.getElementById("fr_previous");
		if(prev){
			prev.onclick = function(){
							self.drawPaging(pagesFrom-visiblePageCount, pagesFrom-1);
						}
		}
		var next = document.getElementById("fr_next");
		if(next){
			next.onclick = function(){
							self.drawPaging(pagesFrom+visiblePageCount, pagesFrom+visiblePageCount);
						}
		}
		for(var i = pagesFrom; i < pagesFrom+pagesTo; i++){
			var page = document.getElementById("fr_page"+i);
			page.onclick = function(){
							self.pagingHandler(this.getAttribute("index"));
						}
			page.onmouseover = function(){
							if(this.className == "fr_inact_page"){
								this.className = "fr_inact_page_hover";
							}
						}
			page.onmouseout = function(){
							if(this.className == "fr_inact_page_hover"){
								this.className = "fr_inact_page";
							}
						}
		}
		
		self.pagingHandler(actPage);
	}
	
	this.pagingHandler = function(page){
		actPage = page;
		var cont = document.getElementById("fr_container");
		var index = page*colCount*rowCount;
		var listEnded = false;
		var str = "";
		
		var parentWidth = cont.offsetWidth;
		var tdWidth = item_width;
		var tableOffset = (parentWidth - colCount*tdWidth)/2;
		
		if(currentList.length == 0){
			str = "<span style='font-size:13px;'>The chosen list is empty</span>";
		}else{
			str = "<table cellspacing='5' id='fr_table'"+(tableOffset>0 ? " style='margin-left:"+tableOffset+"px'" : "")+"><tbody>";
			for(var i = 0; i < rowCount; i++){
				str += "<tr>";
				for(var j = 0; j < colCount; j++){
					var ind = index+i*colCount+j;
					if(ind==currentList.length){
						listEnded = true;
						break;
					}
					var friend = currentList[ind];
					var online = friend.onlineNow=="True" ? "online" : "offline";
					str += "<td class='"+(isSelected(friend.index)!=null ? "fr_td_act" : "fr_td_inact")+"' title='"+friend.getDisplayName()+"' fr_index='"+friend.index+"' tbl_index='"+ind+"'>"+
							"<img class='fr_img' src='"+ friend.fields_.thumbnailUrl +"'>"+
							"<div class='fr_name'>"+friend.getDisplayName()+"</div>"+
							"<div style='display:none;' class='fr_name' style='font-size:12px;'>"+
								"<img width='9px' src='"+FR_IMG_URL+(friend.onlineNow=="True" ? "online.png" : "offline.png")+"' />&nbsp "+
								online+
							"</div>"+
						"</td>";
				}
				str += "</tr>";
				if(listEnded){
					if(j==0){
						str.length -= 4;
					}
					break;
				}
			}		
			str += "</tbody></table>";
		}
		cont.innerHTML = str;
		
		if(currentList.length != 0){
			var table = document.getElementById("fr_table");
			var tds = table.getElementsByTagName("td");
			for(var i = 0; i < tds.length; i++){
				tds[i].onclick = function(){
									self.add_remove_selection(this.getAttribute("fr_index"), this.getAttribute("tbl_index"));
								}
				tds[i].onmouseover = function(){
										if(this.className == "fr_td_inact"){
											this.className = "fr_td_over";
										}
									}
				tds[i].onmouseout = function(){
										if(this.className == "fr_td_over"){
											this.className = "fr_td_inact";
										}
									}
			}
			setPageNumberStyle(page);
		}
	}
	
	var getOnlineOffline = function(){
		onlineList = [];
		offlineList = [];
		wholeList = currentList;
		for(var i = 0; i < currentList.length; i++){
			if(currentList[i].onlineNow == "True"){
				onlineList.push(currentList[i]);
			}else{
				offlineList.push(currentList[i]);
			}
		}
	}
	
	this.showOnlineOffline = function(status){
		if(status == "online"){
			currentList = onlineList;
			self.drawPaging(0, 0);
		}else if(status == "offline"){
			currentList = offlineList;
			self.drawPaging(0, 0);
		}else if(status == "all"){
			currentList = wholeList;
			self.drawPaging(0, 0);
		}
	}
	
	this.onTypeSearch = function(startLetters){
		startLetters = startLetters.toLowerCase();
		var list = [];
		var size = startLetters.length;
		if(size == 0){
			defineCurrentList();
		}else{
			for(var i = 0; i < friendList.length; i++){
				var name = friendList[i].getDisplayName();
				if(!isHavingEnglishLetter(name)){
					continue;
				}
				var index = getFirstLetterIndex(name);
				name = name.substring(index, index+size).toLowerCase();
				if(name == startLetters){
					list.push(friendList[i]);
				}
			}
			currentList = list;
		}
		getOnlineOffline();
		
		var online = document.getElementsByName("fr_online");
		for(var i = 0; i < online.length; i++){
			if(online[i].checked){
				online = online[i].value;
				break;
			}
		}
		if(online == "online" || online == "offline" || online == "all"){
			self.showOnlineOffline(online);
		}else{
			self.drawPaging(0, 0);
		}
	}
	
	var setPageNumberStyle = function(page){
		var cont = document.getElementById("fr_pages");
		var pages = cont.getElementsByTagName("span");
		
		for(var i = 0; i < pages.length; i++){
			pages[i].className = (i==page%visiblePageCount) ? "fr_act_page" : "fr_inact_page";
		}
	}
	
	var setSelPageNumberStyle = function(page){
		var cont = document.getElementById("fr_selPages");
		var pages = cont.getElementsByTagName("span");
		
		for(var i = 0; i < pages.length; i++){
			pages[i].className = (i==page%visPageCntForSel) ? "fr_act_page" : "fr_inact_page";
		}
	}
	
	this.createPagingForSelected = function(_pagesFrom, _actPage){
		selPagesFrom = _pagesFrom;
		selActPage = _actPage;
		var container = document.getElementById("fr_selDetail");
		var pageCount = Math.ceil(selectedFriends.length/selItems_per_page);
		var pagesTo = visPageCntForSel;
		if(pageCount - selPagesFrom < visPageCntForSel){
			pagesTo = pageCount - selPagesFrom;
		}
		
		str = "<div id='fr_selContainer'></div>"+
				"<div style='height:20px;width:100%;position:absolute;top:"+(fr_paging_height-24)+"px;left:0px;'>"+
					(selPagesFrom!=0 ? "<span id='fr_selPrev' style='cursor:pointer;float:left;'><<</span>... " : "")+
					"<span id='fr_selPages'>";
		for(var i = selPagesFrom; i < selPagesFrom+pagesTo; i++){
			str += " <span id='fr_selPage"+i+"' index='"+i+"' class='"+(i==selPagesFrom ? "fr_act_page" : "fr_inact_page")+"'>"+(i+1)+"</span> ";
		}
		str += "</span>"+
				(pageCount-selPagesFrom > visPageCntForSel ? " ...<span id='fr_selNext' style='cursor:pointer;float:right;margin-top:-20px'>>></span>" : "")+
				"</div>";
		container.innerHTML = str;
		
		var prev = document.getElementById("fr_selPrev");
		if(prev){
			prev.onclick = function(){
							self.createPagingForSelected(selPagesFrom-visPageCntForSel, selPagesFrom-1);
						}
		}
		var next = document.getElementById("fr_selNext");
		if(next){
			next.onclick = function(){
							self.createPagingForSelected(selPagesFrom+visPageCntForSel, selPagesFrom+visPageCntForSel);
						}
		}
		for(var i = selPagesFrom; i < selPagesFrom+pagesTo; i++){
			var page = document.getElementById("fr_selPage"+i);
			page.onclick = function(){
							self.selPagingHandler(this.getAttribute("index"));
						}
			page.onmouseover = function(){
							if(this.className == "fr_inact_page"){
								this.className = "fr_inact_page_hover";
							}
						}
			page.onmouseout = function(){
							if(this.className == "fr_inact_page_hover"){
								this.className = "fr_inact_page";
							}
						}
		}
		
		self.selPagingHandler(selActPage);
	}
	
	this.selPagingHandler = function(page){
		selActPage = page;
		var cont = document.getElementById("fr_selContainer");
		var index = page*selColCount*selRowCount;
		var listEnded = false;
		var str = "";
		
		var parentWidth = cont.offsetWidth;
		var tdWidth = 65;
		var tableOffset = (parentWidth - selColCount*tdWidth)/2;
		
		if(selectedFriends.length == 0){
			var selDetail = document.getElementById("fr_selDetail");
			selDetail.innerHTML = "";
		}else{
			str = "<table id='fr_selTable'"+(tableOffset > 0 ? " style='margin-left:"+tableOffset+"px'" : "")+"><tbody>";
			for(var i = 0; i < selRowCount; i++){
				str += "<tr>";
				for(var j = 0; j < selColCount; j++){
					var ind = index+i*selColCount+j;
					if(ind==selectedFriends.length){
						listEnded = true;
						break;
					}
					var friend = selectedFriends[ind];
					var online = friend.onlineNow=="True" ? "online" : "offline";
					str += "<td class='fr_selTd_act' fr_index='"+friend.index+"' title='"+friend.getDisplayName()+"' tbl_index='"+ind+"'>"+
							"<img class='fr_selImg' src='"+ friend.fields_.thumbnailUrl +"'>"+
						"</td>";
				}
				str += "</tr>";
				if(listEnded){
					if(j==0){
						str.length -= 4;
					}
					break;
				}
			}		
			str += "</tbody></table>";
		}
		if(i == 0 && j == 0){
			self.selPagingHandler(page-1);
			return;
		}else{
			cont.innerHTML = str;
		}
		
		if(selectedFriends.length != 0){
			var table = document.getElementById("fr_selTable");
			var tds = table.getElementsByTagName("td");
			for(var i = 0; i < tds.length; i++){
				tds[i].onclick = function(){
									self.add_remove_selection(this.getAttribute("fr_index"), this.getAttribute("tbl_index"));
								}
				tds[i].onmouseover = function(){
										this.className = "fr_td_over";
									}
				tds[i].onmouseout = function(){
										this.className = "fr_selTd_act";
									}
			}
			setSelPageNumberStyle(page);
		}
	}
	
	this.add_remove_selection = function(index, tbl_index){
		var exists = isSelected(index);
		if(exists==null){
			for(var i = 0; i < currentList.length; i++){
				if(currentList[i].index==index){
					break;
				}
			}
			selectedFriends.push(currentList[i]);
			selectedCount++;
		}else{
			for(var j = exists; j < selectedFriends.length-1; j++){
				selectedFriends[j] = selectedFriends[j+1];
			}
			selectedFriends.length--;
			selectedCount--;
		}
		
		var table = document.getElementById("fr_table");
		var tds = table.getElementsByTagName("td");
		for(var i = 0; i < tds.length; i++){
			if(tds[i].getAttribute("fr_index") == index){
				tds[i].className = exists!=null ? "fr_td_inact" : "fr_td_act";
				break;
			}
		}
		
		updateWatchSelection();
	}
	
	//returns the index of the selected friend in the selectedFriends list if friend is selected and null if not selected
	var isSelected = function(index){
		var ind = null;
		for(var i = 0; i < selectedFriends.length; i++){
			if(selectedFriends[i].index == index){
				ind = i;
				break;
			}
		}
		return ind;
	}
	
	this.selectAll = function(){
		var selCount = 0;
		for(var i = 0; i < currentList.length; i++){
			var selected = isSelected(currentList[i].index);
			if(selected==null){
				selectedFriends.push(currentList[i]);
				selCount++;
			}
		}
		selectedCount += selCount;
		updateWatchSelection();
		
		var table = document.getElementById("fr_table");
		if(table){
			var tds = table.getElementsByTagName("td");
			for(var i = 0; i < tds.length; i++){
				tds[i].className = "fr_td_act";
			}
		}
	}
	
	this.deselectAll = function(){
		var selCount = 0;
		for(var i = 0; i < currentList.length; i++){
			var friend = currentList[i];
			var selected = isSelected(friend.index);
			if(selected!=null){
				for(var j = selected; j < selectedFriends.length-1; j++){
					selectedFriends[j] = selectedFriends[j+1];
				}
				selCount++;
			}
		}
		selectedCount -= selCount;
		if(selectedCount == 0){
			selActPage = 0;
			selPagesFrom = 0;
		}
		selectedFriends.length -= selCount;
		updateWatchSelection();
		
		var table = document.getElementById("fr_table");
		var tds = table.getElementsByTagName("td");
		for(var i = 0; i < tds.length; i++){
			tds[i].className = "fr_td_inact";
		}
	}
	
	var updateWatchSelection = function(){
		var watch_selected = document.getElementById("fr_watchSelected");
		watch_selected.innerHTML = "Selected "+selectedCount+" friends";
		
		self.createPagingForSelected(selPagesFrom, selActPage);
	}
	
	//returns the selected friend list at the current time
	this.getSelectedFrineds = function(){
		return selectedFriends;
	}
	
	//returns the whole friend list
	this.getFriendList = function(){
		return friendList;
	}
	
	//returns the friend with the specified ID
	this.getFriendsById = function(idList){
		var friends = [];
		for(var i = 0; i < idList.length; i++){
			for(var j = 0; j < friendList.length; j++){
				if(friendList[j].fields_.id == idList[i]){
					friends.push(friendList[j]);
				}
			}
		}
		return friends;
	}
	
	var getFirstLetterIndex = function(name){
		var index = null;
		for(var i = 0; i < name.length; i++){
			if(isLetter(name.substring(i, i+1))){
				index = i;
				break;
			}
		}
		return index;
	}
	
	var isLetter = function(ch){
		var isLet = false;
		for(var i = 0; i < alphabet.length; i++){
			if(ch.toLowerCase() == alphabet[i]){
				isLet = true;
				break;
			}
		}
		return isLet;
	}
	
	var isHavingEnglishLetter = function(name){
		var isEng = false;
		if(name == null){
			return isEng;
		}
		for(var i = 0; i < name.length; i++){
			for(var j = 0; j < alphabet.length; j++){
				if(name.substring(i, i+1).toLowerCase() == alphabet[j]){
					isEng = true;
					break;
				}
			}
			if(isEng){
				break;
			}
		}
		return isEng;
	}
	
	var fillAlphabetGroups = function(friends){
		var group = [];
		for(var i = 0; i < friends.length; i++){
			var friend = friends[i];
			var name = friend.getDisplayName();
			if(name == null || !isHavingEnglishLetter(name)){
				group = alphabetGroups["#"];
				group.push(friend);
			}else{
				var index = getFirstLetterIndex(name);
				var letter = name.substring(index, index + 1);
				group = alphabetGroups[letter.toLowerCase()];
				group.push(friend);
			}
		}
	}
	
	var sleep = function(millis){
		var date = new Date();  
		var curDate = null;  
		do{
			curDate = new Date();
		}while(curDate-date < millis);  
	}

	
	
}

/*----------------------------------FRRequest--------------------------------------*/

FRRequest.send = function(url, method, responseHandler, data, urlencoded){
	var req; 
	if(window.XMLHttpRequest){
		req = new XMLHttpRequest();
	}else if(window.ActiveXObject){
		req = new ActiveXObject("Microsoft.XMLHTTP");
	}
	req.onreadystatechange = function() {
		if(req.readyState == 4){	// only if req shows "loaded"
			if(req.status < 400){	// only if "OK"
				try{
					req.data = eval("("+req.responseText+")"); 
				}catch(ex){}
				req.text = req.responseText;
				responseHandler(req);
			}
		}
	}
	if(method=="POST"){
		req.open("POST", url, true);
		if(urlencoded) req.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
		req.send("" + data);
	}else{
		req.open("GET", url, true);
		req.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
		req.send(null);
	}

	return req;
}

FRRequest.sendPOST = function(url, data, responseHandler){
	if(FR_IS_LIVE){
		var os_params = {};
		os_params[gadgets.io.RequestParameters.METHOD] = gadgets.io.MethodType.POST;
		os_params[gadgets.io.RequestParameters.CONTENT_TYPE] = gadgets.io.ContentType.JSON;
		os_params[gadgets.io.RequestParameters.POST_DATA] = data;
		gadgets.io.makeRequest(url, responseHandler, os_params);
	}else{
		if(undefined == data) data = '';
		FRRequest.send(url, "POST", responseHandler, data, true);
	}
}

FRRequest.sendGET = function(url, responseHandler){
	if(FR_IS_LIVE){
		var os_params = {};
		os_params[gadgets.io.RequestParameters.METHOD] = gadgets.io.MethodType.GET;
		os_params[gadgets.io.RequestParameters.CONTENT_TYPE] = gadgets.io.ContentType.JSON;
		gadgets.io.makeRequest(url, responseHandler, os_params);
	}else{
		FRRequest.send(url, "GET", responseHandler);
	}
}









