/*

magicbar.js

Manages interaction with the MagicBar - currently the sidebar - that is not handled by other files.


*/

(function() {

	// duration & easing for adding & removing dynamic components to the sidebar.
	var effectEasing = BBX.easing.easeOutExpo, effectDuration = 600, o = {};

	// a function to remove dynamic components from the sidebar.
	function removeBarComponent(e, elm) {
		if(e !== null && e.preventDefault) {
			e.preventDefault();
		}
		if(!elm || elm === null || elm == undefined) {
			elm = this;
		}
		if(!$(elm).hasClass('interactive')) {
			elm = BBX.traverse.getAncestorByClass(elm, 'interactive');
		}
		if(elm) {
			elm = $(elm);
			elm.setStyle({'overflow':'hidden'});
			elm.cssSelect('*').setStyle({'overflow':'hidden'});
			elm.animate({"height":"0"}, {duration:effectDuration, easing:effectEasing,callback:function() { $(this).remove(); }});
		
		}
	}


	// this anonymous function allows us to group a few helpers together.
	var showHideBarSection = (function() {

	    function _toggleClass() {
		var elm = $(this);
		if(elm.hasClass('closed')) {
		    elm.removeClass('closed');
		} else {
		    elm.addClass('closed');
		}
		
	    }


	    /**
	     * Shows or Hides the all but the title of the bar component that contains the element
	     * that was clicked on.
	     *
	     * @param e Event The click event that caused this function to be called.
	     *
	     *
	     */

	    return function showHideBarSection(e) {
		BBX.log('sh called');
		var t = $(this), par = $(t.parentNode), sib = t.next();

		if(sib !== undefined && sib !== null) {
		    if(par.offsetHeight > (t.offsetHeight + 10)) {
			BBX.log('shrink');
			BBX.log(t.offsetHeight);
			par.setStyle({'overflow':'hidden'});
			par.cssSelect('*').setStyle({'overflow':'hidden'});
			par.animate({height:t.outerHeight()}, {easing:effectEasing, duration:effectDuration, callback:_toggleClass});
			BBX.log('"height":' + t.outerHeight() + '+"px');

		    } else {
			BBX.log('grow');
			BBX.log(sib.outerHeight(true));
			_toggleClass.apply(par);

			par.animate({"height":(sib.outerHeight(true) + t.outerHeight())}, {'easing':effectEasing, 'duration':effectDuration});

		    }
		}
	    }


	})();

	//======================================================================
	//======================================================================
	// Start section that deals with boxes, (sites)


	/*
	
		For receiving boxes that friends have shared with me 
		
	*/

	function receiveBoxes() {
	
		BBX.log('receive');
	
		function startReceive() {
		
			BBX.log('startreceive');
			var t,friend,li,a, data, boxes;
			t = $(this);
			li = $(BBX.traverse.getAncestorByTag(t,'li'));
			a = li.cssSelect('a').first();
			f = BBX.utils.getHref(a).substr(1);
			
			data = 'from=' + f;
			
			if(li.cssSelect('.interactive').length == 0) {
				boxes = li.create('div',{'className':'interactive loading'},true,BBX.langdata.getData('loading'));
			} else {
				boxes = li.cssSelect('.interactive').first();
			}
			BBX.log('data: '+data);
			boxes.ajax({'method':'POST','params':data,'url':'/apps/receiveboxes.php','callback':displayReceive});
			boxes.store('infotitle',t.innerHTML);
			
		
		}
		
		function displayReceive(resp) {
			BBX.log('displayreceive called');
			
			var r, t = $(this), header, closer, height, startHeight, sites;
//			BBX.log('variables initted');
//			BBX.log(resp);
			r = eval('(' + resp + ')');
			
			BBX.log('evald');
			if(r.error == 0) {
//				BBX.log('in if');
				startHeight = t.offsetHeight;
				t.setStyle({'overflow':'hidden','height':startHeight + 'px'});
				
				t.removeClass('loading');
				
				header = t.create('h5', {}, false);
				
				
				
				if(t.retrieve('infotitle') != undefined) {
					header.replaceContent(t.retrieve('infotitle'));
				}
				
				closer = header.create('a',{'className':'close'},true,BBX.langdata.getData('close'));
//				closer.addEvent('click',function() { removeBarComponent(t); });
				
				t.replaceContent(header);
				t.addContent(decodeURIComponent(r.html));
				
				// find out how tall this container should be.
				height = header.offsetHeight;
				height = height + t.cssSelect('ol').first().offsetHeight;
				
				t.animate({'height':{'value':height,'unit':'px'}}, {duration:effectDuration,easing:effectEasing, callback:function() { $(this).setStyle({'height':'auto'}); }});
				
				sites = t.cssSelect('ol').first().cssSelect('>li');
				sites.each(function(elm, nxt, other) { BBX.dragdrop.makeDraggable(elm); });
				
				BBX.log('done');
				
			}
		}
	
		$('#magicbar').relayEvent('click','.sidebar-friends .newboxes', startReceive);	
	}
	
	function dismissReceivedSite(e) {
		e.preventDefault();
		
		var t, li, data = '';
		t = $(this);
		li = $(BBX.traverse.getAncestorByTag(t, 'li'));
		
		data += '&act=markseen';
		data += '&box=' + li.getAttribute('data-bbx-bsid');
		
		t.ajax({'url':'/friend/conversation','method':'POST','params':data,'callback':function() {}});
		
		var par = $(li.parentNode), gpar;
		if(par.cssSelect('li').length === 1) {
			gpar = $(BBX.traverse.getAncestorByTag(par, 'li'));
			gpar.cssSelect('.newboxes').hide({'duration':effectDuration,'remove':true});
			removeBarComponent(null, BBX.traverse.getAncestorByClass(par, 'interactive'));
		} else {
			li.hide({'duration':effectDuration,'remove':true});
		}
		
	}
	
	
	// done receiving boxes.
	

	//======================================================================
	//======================================================================
	// Start section that deals with friends
	
	
	/*  
	
		For filtering friends
		
		
	*/
	
	o.friendFilter = function(ipt) {
		
		
		// allows us to pass any DOM node containing a filter input to this function
		if(ipt.nodeName.toLowerCase() != 'input') {
			ipt = $(ipt).cssSelect('.friendfilter').first();
		}
	
		var friendNodes, hashtable = [], par = $(BBX.traverse.getAncestorByClass(ipt, 'friendlist')), friendControls, numVisible=0;
		friendControls = par.cssSelect('.listcontrols').first();
		
		
		// a function for adding phrases to the hashtable.
		function addPhrase(elm,phrase) {
			hashtable.push({
				"phrase":phrase.toLowerCase(),
				"elm":elm
			});
		}
		
		// Adds all metadata phrases to the hashtable so it's easy to look up friends.
		friendNodes = par.cssSelect('.currentfriends .friend');
		
		friendNodes.each(function(elm,idx,coll) {
						
			elm = $(elm);
			
			if(numVisible < 5) {
				elm.setStyle({'display':'block'});
				numVisible++;
			} else {
				elm.setStyle({'display':'none'});
			}
			
			
			addPhrase(elm,decodeURIComponent(elm.getAttribute('data-bbx-fname')));
			addPhrase(elm,decodeURIComponent(elm.getAttribute('data-bbx-lname')));
			addPhrase(elm,decodeURIComponent(elm.getAttribute('data-bbx-nickname')));
			addPhrase(elm,decodeURIComponent(elm.getAttribute('data-bbx-email')));
			
			
		});
		
	
		
		function keyUpHandler(e) {
			BBX.log('fired');
			var t =  $(this), phrase = '', elm, testPhrase, testLength, list;
			friendNodes.setStyle({'display':'none'});
			numVisible = 0;
			
			phrase = t.value.toLowerCase();
			testLength = phrase.length;
			
			
			
			for(var i = 0; i < hashtable.length; i++) {
				testPhrase = hashtable[i].phrase.substr(0,testLength);
				
				if(phrase == testPhrase) {
					elm = $(hashtable[i].elm);
					
					if(elm.getStyle('display') == 'none') {
						elm.setStyle({'display':'block'});	
						numVisible++;
						
						if(numVisible >= 10) {
							break;
						}
					}	
				}
			
			}	// end of for loop
			
			
			list = $(BBX.traverse.getAncestorByTag(friendNodes[0],'ol'));
			
			if(testLength > 0) {
				list.addClass('filtered');
			} else {
				list.removeClass('filtered');
			}
		
		}
		
		$(ipt).addEvent('input', keyUpHandler);
		$(ipt).addEvent('change', keyUpHandler);
		
		par.cssSelect('.friendorder').addEvent('click',changeFriendOrder);
		
		
		
		function changeFriendOrder(e) {
			e.preventDefault();
			var changeto, t, par;
		
			t = $(this);
			changeto = t.getAttribute('data-bbx-friendorder');
			
			par = BBX.traverse.getAncestorByClass(this, 'friendlist');
			par.ajax({'url':'/apps/sidebarfriends.php','method':'POST','params':'forder='+encodeURIComponent(changeto),'callback':showNewFriendOrder});
		
		}
		
		function showNewFriendOrder(resp) {
			var t = $(this), ipt;
			t.replaceContent(resp);
						
			initSidebarFriends();
		
		}
		
		
		
		////////////////////
		
		
		function switchFriendNumber(e) {
			e.preventDefault();
			var t = $(this), currentfriends;
			currentfriends = par.cssSelect('.currentfriends').first();
			
			if(t.hasClass('morefriends')) {
				friendNodes.setStyle({'display':'block'});
				numVisible = friendNodes.length;
				
				currentfriends.addClass('allfriends');
				
				t.addClass('fewerfriends');
				t.removeClass('morefriends');
				t.replaceContent(BBX.langdata.getData('show fewer friends'));
				

				
			} else {
			
			
				numVisible = 0;
				friendNodes.setStyle({'display':'none'});
				friendNodes.each(function(elm,idx,coll) {
					if(numVisible < 5) {
						elm.setStyle({'display':'block'});
						numVisible++;
					} else {
						elm.setStyle({'display':'none'});
					}
				});
				
				
				t.addClass('morefriends');
				t.removeClass('fewerfriends');
				t.replaceContent(BBX.langdata.getData('show more friends'));
				
				currentfriends.removeClass('allfriends');
			}
		}


		if(friendControls.cssSelect('.morefriends').length === 0) {
			friendControls.create('a',{'className':'morefriends'},true,BBX.langdata.getData('show more friends')).addEvent('click',switchFriendNumber);
		}
		
		if(friendControls.cssSelect('.findfriends').length === 0) {
			friendControls.create('a',{'className':'findfriends'},true,BBX.langdata.getData('add buddies')).addEvent('click',buddySearch);
		}
	
	
	
	};
	
	// done friend filter.
	
	
	
	/*
	
		To add friends or edit a friend's info.
	
	*/
	
	function buddySearch(e) {
	
		BBX.dialog.show(e,'addeditfriends');
	}
	
	
	// done add friends, (it brought in another file:  addeditfriends.js
	
	
	
	/*
	
		To remove friends  
		
	
	*/
	
	
	o.makeFriendRemoveable = function(elm) {
	
	
		/* start support functions  */
	
		function breakup(e) {
			var t, li, friend;
			
			e.preventDefault();
			
			
			t = $(this);
			li = $(BBX.traverse.getAncestorByTag(t, 'li'));
			friend = li.getAttribute('data-bbx-nickname');
			
			t.ajax({"url":"/friend/breakup","method":"POST","params":"f="+friend,"callback":showFriendRemoved});
			
			li.hide({'remove':true,'duration':effectDuration});
			
		}
		
		function showFriendRemoved(resp) {
			// do nothing for now.
		
		}
		
		
		/* done support functions  */
			
		
		elm = $(elm);
		if(elm.cssSelect('.liner .removetool').length === 0) {
			elm.cssSelect('.liner').create('a',{'className':'removetool'},true,'d').addEvent('click',breakup);
		}
		
	};
	
	
	
	// done remove friends
	
	
	/*
		
		To Accept & Ignore friend requests 
		
	*/
	
	function pendingFriends() {
	
		
		
		
		function respondFriend(e) {
			BBX.log('ignore');
		
			var t = $(this), bname = '', data = '', pendingfriends, li;
			
			pendingfriends = $(BBX.traverse.getAncestorByClass(t, 'pendingfriends'));
			li = $(BBX.traverse.getAncestorByTag(t, 'li'));
			bname = li.getAttribute('data-bbx-nickname');
			data += '&f=' + bname;
			
			
			if(t.hasClass('accepttool')) {
				var par, currentfriends;
				data += '&response=approve';
				
				par = $(BBX.traverse.getAncestorByClass(li, 'friendlist'));
				currentfriends = par.cssSelect('.currentfriends');
				
				li.cssSelect('.friendaction').remove();
				
				if(currentfriends.length === 0) {
					currentfriends = par.create('ol',{'className':'currentfriends customorder'},true);
					currentfriends.addContent(li);
				} else {
					currentfriends = currentfriends.first();
					currentfriends.insertBefore(li, currentfriends.firstChild);
				}
				
				o.makeFriendRemoveable(li);
				BBX.dragdrop.makeDraggable(li);
				BBX.dragdrop.initSidebarFriend(li);
				
				
				
				
			} else {
			
				data += '&response=ignore';
			}
			
			
			
			
			
			
			t.ajax({'url':'/friend/respond','method':'POST','params':data,'callback':function(){}});
			
			
			if(t.hasClass('ignoretool')) {
				li.hide({'duration':effectDuration,'remove':true});
			}
			
			
			if(pendingfriends.cssSelect('.friend').length === 0 || t.hasClass('ignoretool')) {
				pendingfriends.hide({'duration':effectDuration, 'remove':true});
			}
			
		}
		
	
	
		var mb = $('#magicbar').first();
		mb.relayEvent('click', '.pendingfriends .accepttool', respondFriend);
		mb.relayEvent('click', '.pendingfriends .ignoretool', respondFriend);
		
		
	}
	
	// done with pending friends.
	
	
	function initSidebarFriends() {
	
		var friends = $('.sidebar-friends .currentfriends .friend');
		var isCustomOrder = $('.sidebar-friends ol.customorder').length;
		
		BBX.log('mark 0');
		friends.each(function(elm,idx,coll) { 
			BBX.dragdrop.initSidebarFriend(elm);
			if(isCustomOrder > 0)	{
				BBX.dragdrop.makeDraggable(elm);
			}
			
			o.makeFriendRemoveable(elm);
			
			
		});
		BBX.log('mark 1');
		
		$('.friendfilter').each(function(elm,idx,coll) { o.friendFilter(elm); });
		receiveBoxes();
		
	}



	


	



	


	// anonymous init function
	DOMAssistant.DOMReady(function() {
		// Initialize the sidebar friendlist as droptargets for sites, (for sharing)
		initSidebarFriends();
		pendingFriends();
		
		var mb = $("#magicbar").first();
		mb.relayEvent('click', '.close', removeBarComponent);
		mb.relayEvent('click', '.friend .dismisstool', dismissReceivedSite);
		mb.relayEvent('click', '.magicsection h4', showHideBarSection);
		mb.relayEvent('click', '.sidebar-email h4', function() {});

			
	});
	
	BBX.namespace('magicbar');
	BBX.magicbar = o;

})();
