
/***************************************
 *		Facebook Interface
 ***************************************/ 

/**
 *	Makes sure only one script gets loaded to the dom
 */ 
var facebook_loaded = false;

/**
 *	Makes sure only one facebook gets initialized
 */ 
var facebook_initialized = false;
 
 
/**
 *	Facebook Class 
 *	@param facebook app id 
 */ 
function Facebook(_consumer)
{
	var consumer = '';
	if (typeof(_consumer) != "undefined")
		consumer = _consumer;
	
	/**
	 *	@key:	permission request
	 *	@value:	corresponding graph api request	  
	 */	 	
	var permissions = {"read_friendlists":"friends","read_stream":"feed","offline_access":"feed"};

	var me = this;
 	var timeout = 500;	
 	var user = null;
	var auth = null;
	
	var dom = new Dom();
	
	var error_log = '';
	
	var condition_function = function (){
		return facebook_initialized;
	};
	
	var loop = function (callback){
		var result = async_loop(
			condition_function,
			callback	
		);
		if (result != null)
			error_log += "\n---------------------------\nCondition_function:\n" + condition_function + "\nCallback_function:\n" + callback + "\nError Message: " + result;			
	};
	
	this.get_error_log = function(){
		return error_log;
	};
	
	/**
	 *	Constructor 
	 */	 	
 	(function() {
		
		if (facebook_loaded)
 			return;

 		facebook_loaded = true;

		$.getJSON("/appAuth/key/facebook/" + consumer,
			function(data)
			{
				if(data.request == 'success')
				{
					window.fbAsyncInit = function() {

						if (facebook_initialized)
							return;

						FB.init({
							appId: data.key,
							status: true,
							cookie: true,
							xfbml: true
						});

						me.set_callback();
						facebook_initialized = true;
					};

					var script = dom.new_script(document.location.protocol + "//connect.facebook.net/en_US/all.js");
					dom.add_to_object("fb-root", script);
				}
			}
		);

	}());

	/**
	 *	Sets callback for all cases
	 *	
	 *	@param	callback(boolean is_authed)	 	 
	 */	 	
	this.set_callback = function(callback){
		me.on_logout(callback);
		me.on_login(callback);
		me.on_existing_connection(callback);
	};
	
	/**
	 *	Oaths user and callsback with result of attempt
	 *	
	 *	@param	callback(bool successfull_oauth)	 	 
	 */	 	
	var login = function (callback){
		loop(
			function (){
				var permission_string = '';
				for (var permission in permissions)
					permission_string += "," + permission; 
				if (permission_string != '')
					permission_string = permission_string.substring(1);
				
				FB.login( 
					function (response) {
						manage_callback(response, callback);			
					},
					{perms:permission_string}
				);
			}
		);
	};

	/**
	 *	Logs user out
	 *	
	 *	@param	callback(bool successfull_oauth)	 	 
	 */	 	 	
	var logout = function(callback) {
		loop(
			function (){
				FB.logout(
					function(response) {
						manage_callback(response, callback);
					}
				);
			}
		);
	}
	
	/**
	 *  Manages stored information about user
	 *  
	 *	@param response variable from FB call-backs
	 *	@param callback(boolean have_user_and_required_info)	 	 	 
	 */	 	
	var manage_callback = function (response, callback){
		loop(
			function (){
				if(response.session) {
					auth = response.session;
					FB.api(
						"/me?metadata=1",
						function(current_user){
							user = current_user;					
							if (typeof(callback) == 'function')
								callback(me.has_permissions());
						}
					);
				}else {
					auth = null;
					user = null;			
					if (typeof(callback) == 'function')
						callback(false);		
				}
			}
		);	
	}	

	/**
	 *	Sets actions for when user likes something
	 *	@param on_like()	 	  
	 */	 	
 	this.on_like = function (callback) {
		loop(
			function (){
			 	FB.Event.subscribe('edge.create', function(response) {
			 		manage_callback(response,callback);
				});
			}
		);
	};
	
	/**
	 *	Sets actions for when user likes something
	 *	@param on_connect(retreived_user)	 	  
	 */	 	
 	this.on_logout = function (callback) {
		loop(
			function (){
			 	FB.Event.subscribe('auth.logout', function(response) {
					manage_callback(response,callback);
				});
			}
		);
	};	
	
	/**
	 *	Sets actions for when user likes something
	 *	@param on_connect(retreived_user)	 	  
	 */	 	
 	this.on_login = function (callback) {
		loop(
			function (){
			 	FB.Event.subscribe('auth.login', function(response) {
					manage_callback(response, callback);
				});
			}
		);
	};

	/**
	 *	Sets actions for when user likes something
	 *
	 *	@param callback(boolean OAuthed)
	 */
 	this.on_existing_connection = function (callback) {
		loop(
			function (){
			   	FB.getLoginStatus(function(response) {
					manage_callback(response,callback);
				});
			}
		);
	};

	/**
	 * Switches between Login and Logout buttons depending on current OAuth state.
	 *
	 * @param login_object_id Container containing the login button
	 * @param login_button_id Object that the login click event is binded to
	 * @param logout_object_id Container containing the logout button
	 * @param logout_button_id Object that the logout click event is binded to
	 * @param callback
	 */
	this.manage_login = function(login_object_id, login_button_id, logout_object_id, logout_button_id, callback) {		
		var toggle_buttons = function(authed) {
			if(authed) {
				$(login_object_id).hide("fast", function() {
					$(logout_object_id).show();
				});
			}else {
				$(logout_object_id).hide("fast", function() {
					$(login_object_id).show();
				});
			}
		};
        
        me.set_callback(callback);
		me.on_existing_connection(toggle_buttons);
        
		$(login_button_id).click( function(event) {			
			login(toggle_buttons);
			event.preventDefault();
		} );

		$(logout_button_id).click( function(event) {
			logout(toggle_buttons);
			event.preventDefault();
		} );
	}

	/**
	 *	Gives the user
	 *	@return user if there is one connected, null otherwise	 
	 */	 	
	this.get_user = function() {
		return user;
	};

	/**
	 *	Returns the authentication session information
	 *	
	 *	@return JSON object containing session information if the user connected,
	 *	otherwise null.
	 */
	this.get_auth = function() {
		return auth;
	};
	
	/**
	 *	Checks to see if most recent auth successfully retrived permissions
	 *	
	 *	@return true if permissions were met, false otherwise 	 	 
	 */	 	
	this.has_permissions = function(){
		if (user == null || auth == null)			
			return false;
			
		try{
			for (var permission in permissions)
				if (typeof(user.metadata.connections[permissions[permission]]) == undefined)					
					return false;
		}catch(err){
			return false;
		}
		
		return true;
	}
	
};
