var Facebook = (function()
{
	var apiKey          = false,
	    crossDomainFile = false,
	    initialized     = false,
	    loggedIn        = false;
	
	/**
	 * Run callback when we know Facebook assets are loaded
	 * 
	 * @param {Object} callback
	 */
	function ensureInitialized( callback )
	{
		Facebook.log.debug( 'ensureInitialized()' );
		if ( !apiKey ) trace("api_key is not set");
		if ( !crossDomainFile ) trace("crossDomainFile is not set");
		
		if ( initialized )
		{
			Facebook.log.debug( 'initialized, calling callback()' );
			callback();
		}
		else
		{
			Facebook.log.debug( 'before FB_RequireFeatures' );
			
			FB_RequireFeatures( ["Api", "Connect"], function()
			{
				Facebook.log.debug('start FB_RequireFeatures');
				try
				{
					FB.Facebook.init( apiKey, crossDomainFile );
	                initialized = true;
	                Facebook.log.debug( 'end FB_RequireFeatures, before callback' );
	                callback();
				}
				catch ( e ) {};
			});
		}
	}
	
	function sessionReady( session )
	{
		if ( session )
		{
			Facebook.log.debug( 'sessionReady()' );
			swf().loggedIn();
		}
	}
	
	function trace( str )
	{
		Facebook.log.debug( str );
	}
	
	var fbOverlayTO = false;
	var checkFbOverlayDelay = 1000;
	
	function checkFbOverlay()
	{
		//Facebook.log.debug('checkFbOverlay')
		if ( fbOverlayTO ) $clear(fbOverlayTO);
		
		// if the popup exists, wait and call this again
		if ( document.getElement('.fb_popupContainer') && document.getElement('.fb_popupContainer').getChildren().length )
		{
			// still open
			fbOverlayTO = checkFbOverlay.delay( checkFbOverlayDelay );
		}
		else
		{
			// closed
			Facebook.log.debug( 'checkFbOverlay calling loginCancelled' );
			swf().loginCancelled();
		}
	}
	
	return {
		getInitialized    : function() { return initialized; },
		setAPI            : function( key ) {  apiKey = key; },
		setXdReceiver     : function( path ) { crossDomainFile = path;},
		showExtPermission : function( perm ) { FB.Connect.showPermissionDialog( perm ); },
		
	    /**
	     * Simple logger.
	     * 
	     * Usage: Facebook.log.debug('my message');
	     * 
	     * From the console, run Facebook.log.dump(); . 
	     */
	    log: (function()
	    {
			var _log = [];
			
			return {
				debug: function( txt )
				{
				    _log.push( new Date() + ": " + txt );
				},
				
				get: function()
				{
				    return _log;
				},
				
				dump: function()
				{
				    if ( typeof console !== 'undefined' && typeof console.log !== 'undefined' )
				    {
				        console.log( _log.join("\n") );
				        return;
				    }
				    try 
				    {
				        var logWindow = window.open( "/empty.html", "logWindow", "toolbar=no,width=500,height=500,resizable=yes,scrollbars=yes" );
				        logWindow.document.write( _log.join('<br />' ) + '</body></html>' );
				        return false;          
				    } 
				    catch (err) 
				    {
				        alert( log.join("\n") );
				        return false;
				    }
				    
				    
				    return _log.join( "\n" );
				},
				
				clear: function()
				{
				    _log = [];
				}
			};
	    })(),
		
		login: function()
		{
			Facebook.log.debug( 'login()' );
			ensureInitialized( function()
			{
				Facebook.log.debug( 'login.ensureInitialized()' );
				trace( "getting session state." );
				
				FB.Facebook.get_sessionState().waitUntilReady( function(session)
				{
					// This callback is called AFTER successful login
					Facebook.log.debug( 'waitUntilReady()' );
					sessionReady( session );
				});
				
				// Ensure the user is authenticated
				FB.Connect.requireSession( function() { trace('sessioned'); $clear(fbOverlayTO); },false );
				fbOverlayTO = checkFbOverlay.delay( checkFbOverlayDelay );
			});
		},
		
		logout: function() // called from flash
		{
			FB.Connect.logout( function()
			{
				trace( "Let flash know we're logged out" );
				swf().loggedOut();
			});
		},
		
		isConnected: function()
		{
			Facebook.log.debug( 'isConnected()' );
			// first arg: logged IN, second arg: logged OUT
			ensureInitialized( function()
			{
				Facebook.log.debug( 'isConnected.ensureInitialized' );
				
				trace( "check if is connected" );
				
				// setConnected: user is logged IN, call setConnected to Flash
				// setDisconnected: user is logged OUT, call setDisconnected to Flash
				FB.Connect.ifUserConnected( swf().setConnected, swf().setDisconnected );
			});
		}
	};
})();
