var facebookConnect = (function () {
	// result codes
	// 0 - success
	// 1 - permission not granted
	// 2 - login canceled/failed
	// 3 - api call canceled/failed
	
	var appID,
		userID,
		responder,
		permissionCache,
		loggedIn = false;
	
	function ensureLogin(permissions, resultFunction) {
		if (loggedIn) {
			checkSavedPerms(permissions,
				function(response) {
					if (response.success === true) {
						resultFunction(response);
					}
					else {
						doLogin(permissions, resultFunction);
					}
				}
			);
		}
		else {
			doLogin(permissions, resultFunction);
		}
	};
	
	function doLogin(permissions, resultFunction) {
		var loginArgs = {};
		if (permissions) {
			loginArgs.perms = permissions;
		}
		
		FB.login(
			function(response) {
				loggedIn = response.session != null;
				if (loggedIn) {
					userID = response.session.uid;
					ensurePerms(permissions, resultFunction);
				}
				else {
					resultFunction({success: false, id: 2});
				}
			}, loginArgs
		);
	};
	
	function checkSavedPerms(permissions, resultFunction) {
		if (!permissions) {
			permissions = "basic";
		}
		
		if ( permissionCache[permissions] === true) {
			resultFunction({success: true, id: 0});
		}
		else {
			resultFunction({success: false, id: 1});
		}
	};
	
	function ensurePerms(permissions, resultFunction) {
		checkSavedPerms(permissions, 
			function(response) {
				if (response.success === true)
				{
					resultFunction(response);
				}
				else if (permissions){
					FB.api( {method: 'users.hasAppPermission', ext_perm: permissions}, 
						function(response) {
							var success = response === "1";
							permissionCache[permissions] = success;							
							resultFunction({success: success, id: (success ? 0 : 1)});
						}
					);
				}
				else {
					FB.api( {method: 'users.isAppUser'}, 
						function(response) {
							var success = response === true;
							permissionCache["basic"] = success;							
							resultFunction({success: success, id: (success ? 0 : 1)});
						}
					);
				}
			}
		);
	};
	
	function facebookShareDialog(url, resultFunction) {
		FB.ui( 
			{
				method: 'stream.share',
				u: url,
				display: 'popup'
            }, 
            resultFunction
        );
    };
    
    function facebookPublishDialog(message, description, caption, imageUrl, actionLinkText, actionLinkUrl, promptMessage, resultFunction) {
		FB.ui( 
			{
				method: 'stream.publish',
				message: message,
				display: 'popup',
				attachment: {                               
					name: promptMessage,
					caption: caption,
					description: description,
					href: actionLinkUrl,
					media: [{
							type: 'image',
							src: imageUrl,
							href: actionLinkUrl
						}]
				},
				action_links: [{ 
					text: actionLinkText, 
					href: actionLinkUrl 
				}]
            },
            resultFunction
        );
    };
    
    function dispatchResult(resultType, resultFunction, resultObject) {
    	if (responder) {
    		responder[resultType](resultObject);
    	}
    	
    	if (resultFunction) {
    		resultFunction(resultObject);
    	}
    };
	
    return {
    	init: function(facebookAppID, facebookResponder, permissionList) {
    		appID = facebookAppID;
    		responder = facebookResponder;
    		
    		permissionCache = {};
    		if (!permissionList) {
    			permissionList = [];
    		}    		
    		
	    	FB.init({appId: appID, status: true, cookie: true, xfbml: true});

    		FB.getLoginStatus(
    			function(response) {
    				loggedIn = response.session != null;
    				
    				if (loggedIn) {
    					userID = response.session.uid;
    					
    					for (var i = 0; i < permissionList.length; ++i) {
    						var perm = permissionList[i];
	    					ensurePerms(perm,
	    						function(response) {
	    							//console.log("init permission for "+perm + ": "+permissionCache[perm]);
	    						}
	    					);
    					}	
    				}
    				else {
    					//console.log("initial login status: "+loggedIn);
    				}
    			}
    		);
    	},
    	
    	api: function( params, permissions, resultFunction ) {    		
    		if (!permissions)
    			permissions = '';
    		
    		ensureLogin(permissions,
				function(response) {
					if (response.success) {
	    				FB.api(params,
	    					function(response) {
	    						if (response) {
	    							dispatchResult('apiResult', resultFunction, {success: true, id: 0, response: response});
	    						}
	    						else {
	    							dispatchResult('apiResult', resultFunction, {success: false, id: 3, response: response});
	    						}
	    					}
	    				);
					}
					else {
						dispatchResult('apiResult', resultFunction, {success: false, id: 1, response: response});
					}
				}
			);
    	},
    	
    	publish: function( params, resultFunction ) {
    		facebookPublishDialog( params.message, params.description, params.caption, params.imageUrl, params.actionLinkText, params.actionLinkUrl, params.promptMessage,
				function (response) {
					var published = response != null && response.post_id != null;
					dispatchResult('publishResult', resultFunction, {success: published, id: (published ? 0 : 3)});
				}
			);
    	},
    	
    	share: function( url, resultFunction ) {
    		facebookShareDialog( url,
				function (response) {
					// TODO: why is response "false" on successful share?
					dispatchResult('shareResult', resultFunction, {success: true, id: 0});
				}
			);
    	},
    	
    	getUserID: function( params, resultFunction) {
    		dispatchResult('getUserIDResult', resultFunction, {success: true, id: userID});
    		return userID;
    	}
    };
}());
