//----------------------------------------------------------------------
// AETN Socialize Library by Eric Spector <Eric.Spector@aetn.com>
//
// The purpose of this library is to provide a custom Socialize framework for AETN sites
// This library is a plugin for the AETN SSOS Server
// 
// This library requires the following AETN JS libraries:
//   aetn.lib.cookie
//   aetn.lib.jsonp
//   aetn.lib.serialize
//   aetn.lib.unserialize
//
// Additionally the following JS must be loaded prior to this one:
//   http://cdn.gigya.com/JS/gigya.js?services=socialize
//
//----------------------------------------------------------------------
if(!aetn) {
	//init aetn namespace
	var aetn={}; 
}

/**
 * aetn.socialize
 * @projectDescription AETN Socialize Library
 * 
 * @author Eric Spector <Eric.Spector@aetn.com>
 */
aetn.socialize = function() {
	var pub = {}; //public
	var priv = {}; //private
	
	//init cache variables
	pub.cache = {};
	priv.cache = {};
	priv.cache.time = false; //default cookie time in seconds, if set to false it becomes a session cookie
	
	//init exeid
	priv.exeid = {};
	
	//callback function init
	pub.callback = {};
	pub.callback.prep = {};
	pub.callback.response = {};
	
	//ssos config
	priv.pid = '120';
	priv.ssos_server = 'http://ssos.mylifetime.com/aetn_socialize/jsonp';
	
	//conversion info
	priv.titles = {"aol":"AOL","blogger":"Blogger","facebook":"Facebook","gmail":"GMail","google":"Google","hyves":"Hyves","linkedin":"LinkedIn","livejournal":"LiveJournal","myspace":"MySpace","openid":"OpenID","twitter":"Twitter","typepad":"Typepad","verisign":"Verisign","yahoo":"Yahoo"};
	
	
	//------------------------------------------------------------------
	// Configuration Functions
	//------------------------------------------------------------------
	
	/**
	* Displays priv.conf
	* @author Eric Spector <Eric.Spector@aetn.com>
	* 
	* @return {Array} priv.conf
	*/
	pub.getConf = function() {
		return priv.conf;
	};
	
	/**
	* Set priv.conf
	* @author Eric Spector <Eric.Spector@aetn.com>
	* 
	* @param {Array} new_conf new priv.conf
	*/
	pub.setConf = function(new_conf) {
		priv.conf = new_conf;
	};
	
	/**
	* Reset internal callback variables
	* @author Eric Spector <Eric.Spector@aetn.com>
	* 
	*/
	priv.resetCallbacks = function() {
		priv.callback = priv_default.callback;
	};
	
	
	//------------------------------------------------------------------
	// Cache Management Functions
	//------------------------------------------------------------------
	
	/**
	* Private function to set cookie based cache
	* @author Eric Spector <Eric.Spector@aetn.com>
	* 
	* @param {String} cache_name Name of the cache to use, ex 'mycache'
	* @param {Object} cache_data Data to cache
	*/
	priv.cache.set = function(cache_name, cache_data) {
		//set the cookie cache
		var serialized_data = aetn.lib.serialize(cache_data);			
		aetn.lib.cookie.set('ssos_' + cache_name, serialized_data, priv.cache.time, '/'); //set cache for default time, set by aetn.socialize.cache.set_expire_time();
	};
	
	/**
	* Private function to get cookie based cache
	* If no cache is found; false is returned
	* @author Eric Spector <Eric.Spector@aetn.com>
	* 
	* @param {String} cache_name Name of the cache to use, ex 'mycache'
	* @return {Object} Object stored in requested cache
	*/
	priv.cache.get = function(cache_name) {
		var cached_data = aetn.lib.cookie.get('ssos_' + cache_name);
		
		if(cached_data) {
			return aetn.lib.unserialize(cached_data);
		} else {
			return false;
		}
	};
	
	/**
	* Reset all aetn.socialize cookie based cache
	* @author Eric Spector <Eric.Spector@aetn.com>
	* 
	* @param {String} cache_name Optional name of the cache to delete (without the ssos_ prefix)
	*/
	pub.cache.reset = function(cache_name) {
		
		if(cache_name != undefined) {
			//if set, remove targeted cache
			aetn.lib.cookie.remove('ssos_' + cache_name, '/');
			return;
		}
		
		//remove all cookies
		aetn.lib.cookie.remove('ssos_getAvailableProviders', '/');
		aetn.lib.cookie.remove('ssos_getUserInfo', '/');
	};
	
	/**
	* Set exipration time for aetn.socialize cookie based cache
	* Passing in false will set it as session based cache
	* @author Eric Spector <Eric.Spector@aetn.com>
	* 
	* @param {String} expire Time for cookie to expire (in seconds), false means mession based
	*/
	pub.cache.set_expire_time = function(expire) {
		priv.cache.time = expire;
	};
	
	//------------------------------------------------------------------
	// Internal Execution ID Management Functions
	//------------------------------------------------------------------
	
	/**
	* Get execid
	* @author Eric Spector <Eric.Spector@aetn.com>
	* 
	* @param {String} Get current execid value
	*/
	priv.exeid.get = function() {
		return priv.execid;
	};
	
	/**
	* Invalidate execid
	* @author Eric Spector <Eric.Spector@aetn.com>
	* 
	* @param {String} Invalidate execid
	*/
	priv.exeid.invalidate = function() {
		++priv.execid;
	};
	
	//------------------------------------------------------------------
	// AETN Socialize Application
	//------------------------------------------------------------------
	
	/**
	* Socialize Login function
	* 
	* Log in to a social network of your choice
	* 
	* @author Eric Spector <Eric.Spector@aetn.com>
	* 
	* @param {Array} params Parameters array
	* @param {String} params.provider Optional provider, ex params.provider = facebook
	* @param {String} params.callback Optional post-jsonp callback, ex params.callback = 'my_function'
	* @param {String} params.callback_internal Optional pre-jsonp callback, WARNING: experts only!
	*/
	pub.login = function(params) {
		priv.resetCallbacks(); //reset all callbacks to default
		priv.exeid.invalidate(); //invalidate exec id
		
		if(params==undefined) {
			var params = {};
		}
		
		//if set, overwrite jsonp callback script
		if(params.callback != undefined) {
			priv.callback.login.callback_jsonp_script = params.callback;
		}
		
		//if set, overwrite the callback script
		if(params.callback_internal != undefined) {
			priv.callback.login.callback_script = params.callback_internal;
		}
		
		//set session based cookie mode
		if(params.sessionExpiration == undefined) {
			params.sessionExpiration = '0';
		}
		
		//store login params in memory
		priv.callback.login.params = params;
		
		//if the user is not logged in, always do login rather than connect
		if(!aetn.lib.cookie.get("loginstatus")) {
			
			var params = priv.callback.login.params;
			
			//set callback script from memory
			params.callback =  priv.callback.login.callback_script;
			
			gigya.services.socialize.login(priv.conf, params);
			return;
		}
		
		//do getUserInfo call
		var params = {
			cache: false,
			resetCallback: false,
			callback: pub.callback.prep.login
		};
		
		pub.getUserInfo(params);
	};
	
	/**
	* Socialize Logout
	* @author Eric Spector <Eric.Spector@aetn.com>
	* 
	* 
	* @param {Array} params Parameters array
	* @param {Function} params.callback Callback function
	*/
	pub.logout = function(params) {
		priv.resetCallbacks(); //reset all callbacks to default
		
		if(params==undefined) {
			var params = {};
		}
		
		//if set, add the post callback script
		if(params.callback != undefined) {
			priv.callback.logout.callback_post_script = params.callback;
			params.callback = priv.callback.logout.callback_script;
		} else {
			params.callback = priv.callback.logout.callback_script;
		}
		
		//init gigya login
		gigya.services.socialize.logout(priv.conf, params);
		
		pub.cache.reset();
	};
	
	/**
	* Socialize Connect function
	* @author Eric Spector <Eric.Spector@aetn.com>
	* 
	* @param {Array} params Parameters array
	* 
	* @depricated Merged in to pub.login
	*/
	pub.connect = function(params) {
		return;
	};
	
	/**
	* Socialize Disconnect function
	* @author Eric Spector <Eric.Spector@aetn.com>
	* 
	* @param {Array} params Parameters array
	*/
	pub.disconnect = function(params) {
		priv.resetCallbacks(); //reset all callbacks to default
		
		if(params==undefined) {
			var params = {};
		}
		//init gigya login
		gigya.services.socialize.disconnect(priv.conf, params);
		
		pub.cache.reset();
	};
	
	/**
	* Link Socialize account to Current SSOS User
	* @author Eric Spector <Eric.Spector@aetn.com>
	* 
	* @param {Array} params Parameters array
	* @param {Function} params.callback Optional final callback, past notifyLogin
	* @param {String} params.callback_jsonp Optional post-jsonp callback, ex params.callback_jsonp = 'my_function', WARNING: experts only!
	* @param {Function} params.callback_internal Optional pre-jsonp callback, WARNING: experts only!
	*/
	pub.linkAccountToCurrentUser = function(params) {
		priv.resetCallbacks(); //reset all callbacks to default
		
		if(params==undefined) {
			var params = {};
		}
		
		//overwrite notifyLoginCallback if avaliable
		if(params.callback != undefined) {
			priv.callback.linkAccountToCurrentUser.callback_notifyLogin = params.callback;
		}
		
		//if set, overwrite jsonp callback script
		if(params.callback_jsonp != undefined) {
			priv.callback.linkAccountToCurrentUser.callback_jsonp_script = params.callback_jsonp;
		}
		
		//if set, overwrite the callback script
		if(params.callback_internal != undefined) {
			priv.callback.linkAccountToCurrentUser.callback_script = params.callback_internal;
			params.callback = params.callback_internal;
		} else {		
			params.callback = priv.callback.linkAccountToCurrentUser.callback_script;
		}

		//init gigya login
		gigya.services.socialize.getUserInfo(priv.conf, params);
		
		pub.cache.reset();
	};
	
	/**
	* UnLink Socialize account from Current SSOS User
	* @author Eric Spector <Eric.Spector@aetn.com>
	* 
	* @param {Array} params Parameters array
	* @param {String} params.callback Optional pre-jsonp callback, WARNING: experts only!
	* @param {String} params.callback_jsonp Optional post-jsonp callback, ex params.callback_jsonp = 'my_function', WARNING: experts only!
	*/
	pub.unlinkAccounts = function(params) {
		priv.resetCallbacks(); //reset all callbacks to default
		
		if(params==undefined) {
			var params = {};
		}
		
		//if set, overwrite jsonp callback script
		if(params.callback_jsonp != undefined) {
			priv.callback.unlinkAccounts.callback_jsonp_script = params.callback_jsonp;
		}

		/*
		 * init jsonp
		 */
		
		// Build the services call
	    var request = priv.ssos_server + '?command=unlinkAccount&pid=' + priv.pid + '&callback=' + priv.callback.unlinkAccounts.callback_jsonp_script; 
	    
	    //execute server-side callback via jsonp
	    aetn.lib.jsonp(request);
	};
	
	/**
	* Private UnLink Socialize account from Current SSOS User
	* @author Eric Spector <Eric.Spector@aetn.com>
	*/
	pub.callback.response.unlinkAccounts = function(response) {
		if(response.status==true) {
			var params = {};
			params.siteUID = response.uid;
			
			gigya.services.socialize.unlinkAccounts(priv.conf, params);  
		} else {
			alert('Unable to unlink account!');
		}
	};
	
	/**
	* Notify Socialize system of a current SSOS User
	* @author Eric Spector <Eric.Spector@aetn.com>
	* 
	* @param {Array} params Parameters array
	* @param {Function} params.callback Optional post-jsonp callback
	* @param {String} params.callback_jsonp Optional jsonp callback, ex params.callback_jsonp = 'my_function', WARNING: experts only!
	*/
	pub.notifyLogin = function(params) {
		priv.resetCallbacks(); //reset all callbacks to default
		
		if(params==undefined) {
			var params = {};
		}
		
		//if set, overwrite the callback script
		if(params.callback_jsonp != undefined) {
			priv.callback.notifyLogin.callback_jsonp_script = params.callback_jsonp;
		} 
		
		//if set, overwrite the callback script
		if(params.callback != undefined) {
			priv.callback.notifyLogin.callback_script = params.callback;
		}
		
		// Build the services call
	    var request = priv.ssos_server + '?command=notifyLogin&pid=' + priv.pid + '&callback=' + priv.callback.notifyLogin.callback_jsonp_script; 
	    
	    //execute server-side callback via jsonp
	    aetn.lib.jsonp(request);
	};
	
	/**
	* Default JSONP Responce for Notify Socialize system of a current SSOS User
	* @author Eric Spector <Eric.Spector@aetn.com>
	*/
	pub.callback.response.notifyLogin = function(response) {
		if(response.status==true) {		
			if(priv.callback.notifyLogin.callback_script != undefined) {
				response.params.callback = priv.callback.notifyLogin.callback_script;
			}
			priv.exeid.invalidate(); //invalidate exeid; Make sure the showLoginUI
			gigya.services.socialize.notifyLogin(priv.conf,response.params);  
		} else {
			return false;
		}
	};
	
	/**
	* ShowLoginUI Interface for Social Networks
	* 
	* Generates flash output of Social Network icons
	* @author Eric Spector <Eric.Spector@aetn.com>
	* 
	* @param {Array} params Parameters array
	* @param {String} params.containerID HTML dom id of the container to draw the buttons to
	* @param {String} params.buttonSize Optional size of buttons
	* @param {String} params.bgColor Optional button background color
	* @param {String} params.callback Optional post-jsonp callback, ex params.callback_jsonp = 'my_function'
	* @param {String} params.callback_internal Optional pre-jsonp callback, WARNING: experts only!
	*/
	pub.showLoginUI = function(params) {
		priv.resetCallbacks(); //reset all callbacks to default		
		priv.exeid.invalidate(); //invalidate exeid
		
		//default set
		var param_defaults = {
			showTermsLink: 'false'
			,hideGigyaLink: 'true'
			,height: '55'
			,width: '190'
			,containerID: 'componentDiv'
			,UIConfig: '<config><body><controls><snbuttons buttonsize="40"></snbuttons></controls><background frame-color="Transparent"></background></body></config>'
			,useFacebookConnect: 'true'
			,showEditLink: false
			,lastLoginIndication: 'none'
			,sessionExpiration: '0'
		};
		
		if(params == undefined) {
			var params = param_defaults;
		}
		
		//special button size setting, to make the api easier
		if(params.buttonSize != undefined || params.bgColor != undefined) {
			params.UIConfig = '<config><body><controls><snbuttons buttonsize="' + ((params.buttonSize)?params.buttonSize:'40') + '"></snbuttons></controls><background frame-color="Transparent" ' +  ((params.bgColor)?('background-color="' + params.bgColor + '"'):'') + '></background></body></config>';
		}
		
		//set the defaults for missing values
		for(var param_key in param_defaults) {
			if(params[param_key] == undefined) {
				params[param_key] = param_defaults[param_key];
			}
		}
		
		/*
		 * set up the onLogin system for the callback workaround
		 */
		
		//if set, overwrite jsonp callback script
		if(params.callback != undefined) {
			priv.callback.login.callback_jsonp_script = params.callback;
		}
		
		//if set, overwrite the callback script
		if(params.callback_internal != undefined) {
			priv.callback.showLoginUI.callback_script = params.callback_internal;
			params.callback = params.callback_internal;
		} else {		
			params.callback = priv.callback.showLoginUI.callback_script;
		}
		
		var exeid = priv.exeid.get(); //get a new exeid
		
		gigya.services.socialize.addEventHandlers(priv.conf, {
			//The onLogin/onConnect system must be setup for the UI's
			//This must include an exec validation mechanism, else all previous functions will execute
			onLogin:	function(event) {
							//only execute if exeid is valid
							if(priv.exeid.get()!=exeid) {
								return; //is invalid
							}
							
							eval(params.callback)(event);
						},
						
			onConnect:	function(event) {
							//only execute if exeid is valid
							if(priv.exeid.get()!=exeid) {
								return; //is invalid
							}
							
							eval(params.callback)(event);
						}
		   }
		);
		
		/*
		 * end of callback system workaround
		 */
		
		//store login params in memory
		priv.callback.showLoginUI.params = params;
		
		//if the user is not logged in, always do login rather than connect
		if(!aetn.lib.cookie.get("loginstatus")) {
			var params = priv.callback.showLoginUI.params;
			
			//get login params from memory
			params = priv.callback.showLoginUI.params;
			
			gigya.services.socialize.showLoginUI(priv.conf, params);
			return;
		}
		
		//do getUserInfo call
		var params = {
			cache: false,
			resetCallback: false,
			callback: pub.callback.prep.showLoginUI
		};
		
		pub.getUserInfo(params);
	};
	
	/**
	* Get avalible providers, along with user status on the server
	* @author Eric Spector <Eric.Spector@aetn.com>
	* 
	* @param {Array} params Parameters array
	* @param {Function} params.callback Function to return avaliable provider list to
	* @param {String} params.cache Optional If false don't return cached data
	* 
	*/
	pub.getAvailableProviders = function(params) {
		priv.resetCallbacks(); //reset all callbacks to default
		
		if(params==undefined) {
			var params = {};
		}
		
		//if set, set external callback
		if(params.callback != undefined) {
			priv.callback.getAvailableProviders.callback_script = params.callback;
		}
		
		//check for cache
		if(params.cache == undefined || (params.cache != undefined && params.cache == true)) {
			var cached_data = priv.cache.get('getAvailableProviders');
			
			if(cached_data) {
				//cache exists, pass to callback and exit
				if(priv.callback.getAvailableProviders.callback_script != undefined) {
					priv.callback.getAvailableProviders.callback_script(cached_data);
				}
				return;
			}
		} else {
			pub.cache.reset();
		}
		
		//set internal callback
		params.callback = pub.callback.getAvailableProviders; //set internal callback
		   
		gigya.services.socialize.getAvailableProviders(priv.conf,params);
	};
	
	/**
	* Displays a "Share" Widget. The Share Widget is a pop-up dialog, allowing the user to publish a newsfeed to various social networks.
	* @author Eric Spector <Eric.Spector@aetn.com>
	* 
	* @param {Array} params Parameters array
	* @param {String} params.title Title of the page
	* @param {String} params.userMessage User message
	* @param {String} params.description Description
	* @param {String} params.link Title Link
	* @param {String} params.actionLinkName Action Link Name (bottom right of FB post)
	* @param {String} params.actionLinkUrl Action Link URL (bottom right of FB post)
	* @param {Array} params.mediaItem Media Object, see http://wiki.gigya.com/030_API_reference/010_Client_API/010_Objects/UserAction_object#MediaObject
	* @param {Array} params.more Additional parameters, see http://wiki.gigya.com/030_API_reference/010_Client_API/020_Methods/socialize.showShareUI
	* 
	*/
	pub.showShareUI = function(params) {
		
		if(params == undefined) {
			var params = {};
		}

		//default set; link, title and description are required
		var param_defaults = {
			userMessage: 'Your Comment Here'
			,mediaItem: { type: 'image', src: 'http://photos-g.ak.fbcdn.net/photos-ak-sf2p/v27562/198/124663637544966/app_1_124663637544966_420.gif', href: 'http://www.mylifetime.com' }
			,more: { 
				successMessage: 'true'
				,showMoreButton: 'true'
			}
			,actionLinkName: 'Read More'
			,actionLinkUrl: params.link
		};
		
		//merge param defaults
		for(var param_key in param_defaults) {
			if(params[param_key] == undefined) {
				params[param_key] = param_defaults[param_key];
			}
		}
		
		//generate new act object
		var act = new gigya.services.socialize.UserAction();  
		   
		act.setUserMessage(params.userMessage);   // Setting the default user message  
		act.setTitle(params.title);  // Setting the Title  
		act.setLinkBack(params.link);  // Setting the Link Back  
		act.setDescription(params.description);   // Setting Description  
		act.addActionLink(params.actionLinkName, params.actionLinkUrl);  // Adding Action Link  
		// Adding a Media Item  
		act.addMediaItem(params.mediaItem);  
				
		var param_more = params.more;
				
		var params = {  
		    userAction:act
		    ,enabledProviders: 'facebook, twitter, myspace, yahoo, messenger, google'
		}; 
		
		//get more param options
		for(var param_key in param_more) {
			if(params[param_key] == undefined) {
				params[param_key] = param_more[param_key];
			}
		}
				
		// Show the "Share" dialog  
		gigya.services.socialize.showShareUI(priv.conf,params);  
	};
	
	
	/**
	* Get avalible providers, callback wrapper function
	* @author Eric Spector <Eric.Spector@aetn.com>
	* 
	* @param {Array} params AUTOMATIC, DO NOT TOUCH
	* 
	* @return {Array} Socialize response object 
	* 
	*/
	pub.callback.getAvailableProviders = function(response) {
			
		//init providers object
		var providers = {};
		
		//assume fail, until proven sucessful
		providers.status = false;
		
		if ( response['status'] == 'OK' ) {               
			var availableProviders = response['availableProviders'];  
	        
			/*
			 * generate custom providers array for easy parsing
			 */
			
			//init providers.providers array
			providers.providers = {};
	           
			if ( null!=availableProviders ) {
				for (var providerName in availableProviders) {
					if(availableProviders[providerName].available==true) {
						//data is avaliable, set to true
						providers.status = true;
			        	 
						//set the providers array
						//we want to keep the providerName as the key, so it's easier to process.. ex result['facebook'].loggedIn;
						providers.providers[providerName] = {};
						providers.providers[providerName].name = (priv.titles[providerName]?priv.titles[providerName]:providerName);
						providers.providers[providerName].loggedIn = availableProviders[providerName].isLoggedIn;
						providers.providers[providerName].connected = availableProviders[providerName].isConnected;
					}
				}              
			}
			
			//only store cache on OK status
			priv.cache.set('getAvailableProviders', providers);
	    } 
		
		if(priv.callback.getAvailableProviders.callback_script != undefined) {
			//forward the processed data to the original callback
			priv.callback.getAvailableProviders.callback_script(providers);
		}
	};
	
	/**
	* Get user info from Socialize connection
	* @author Eric Spector <Eric.Spector@aetn.com>
	* 
	* @param {Array} params Parameters array
	* @param {Function} params.callback Optional callback function
	* @param {String} params.cache Optional If false don't return cached data
	* @param {String} params.resetCallback Optional If false don't reset default callbacks
	*/
	pub.getUserInfo = function(params) {
		
		if(params==undefined) {
			var params = {};
		}
		
		if(params.resetCallback == undefined || (params.resetCallback != undefined && params.resetCallback == true)) {
			priv.resetCallbacks(); //reset all callbacks to default
		}
		
		//if set, set external callback
		if(params.callback != undefined) {
			priv.callback.getUserInfo.callback_script = params.callback;
		}
		
		//check for cache
		if(params.cache == undefined || (params.cache != undefined && params.cache == true)) {
			var cached_data = priv.cache.get('getUserInfo');
			
			if(cached_data) {
				//cache exists, pass to callback and exit
				if(priv.callback.getUserInfo.callback_script !=  undefined) {
					priv.callback.getUserInfo.callback_script(cached_data);
				}
				return;
			}
		} else {
			pub.cache.reset('getUserInfo');
		}
		
		//set internal callback
		params.callback = pub.callback.getUserInfo; //set internal callback
		
		//init gigya login
		gigya.services.socialize.getUserInfo(priv.conf, params);
		
		pub.cache.reset('getUserInfo');
	};
	
	/**
	* Get user info, callback wrapper function
	* @author Eric Spector <Eric.Spector@aetn.com>
	* 
	* @param {Array} params AUTOMATIC, DO NOT TOUCH
	* 
	* @return {Array} Socialize response object 
	* 
	*/
	pub.callback.getUserInfo = function(response) {
		if ( response['status'] == 'OK' ) {
			//only store cache on OK status
			priv.cache.set('getUserInfo', response);
	    } 
		
		if(priv.callback.getUserInfo.callback_script != undefined) {
			//forward the processed data to the original callback
			priv.callback.getUserInfo.callback_script(response);
		}
	};
	
	/**
	* linkAccountToCurrentUser Pre-JSONP callback
	* @author Eric Spector <Eric.Spector@aetn.com>
	* 
	* @param {Array} params AUTOMATIC, DO NOT TOUCH
	* 
	*/
	pub.callback.linkAccountToCurrentUser = function(response) {		
		
		pub.cache.reset();
		
		// Build the services call
	    var request = priv.ssos_server + '?command=linkAccountToCurrentUser&pid=' + priv.pid + '&signature=' + encodeURIComponent(response.signature) + '&uid=' + encodeURIComponent(response.user.UID) + '&timestamp=' + response.timestamp +  '&callback=' + priv.callback.linkAccountToCurrentUser.callback_jsonp_script; 
	    
	    //execute server-side callback via jsonp
	    aetn.lib.jsonp(request);
	};
	
	/**
	* linkAccountToCurrentUser Post-JSONP callback
	* 
	* Sample reference function, shouldn't be used on live site
	* @author Eric Spector <Eric.Spector@aetn.com>
	* 
	* @param {Array} data AUTOMATIC, DO NOT TOUCH
	* 
	*/
	pub.callback.response.linkAccountToCurrentUser = function(data) {
	    //reset notifyLogin callback jsonp to default
		priv.callback.notifyLogin.callback_jsonp_script = priv.callback.linkAccountToCurrentUser.callback_notifyLogin;
		
		//do notify login
		pub.notifyLogin();
	    
		return;
	};
	
	/**
	* Socialize Login Pre-LoginUI callback
	* 
	* This is needed because we're trying to determine user's current login state
	* Hence we can choose if it's a login or connect
	* 
	* Automatic Pre-LoginUI callback
	* @author Eric Spector <Eric.Spector@aetn.com>
	* 
	* @param {Array} response AUTOMATIC, DO NOT TOUCH
	* 
	*/
	pub.callback.prep.showLoginUI = function(response) {		
		//get login params from memory
		params = priv.callback.showLoginUI.params;
		
		if(response.user.isLoggedIn != undefined && response.user.isLoggedIn == true) {
			//the user is already logged in, therefore we want to initiate a connection rather than login
			priv.callback.login.enableConnect = true;
			
			gigya.services.socialize.showConnectUI(priv.conf, params);
		} else {
			priv.callback.login.enableConnect = false;
			
			//user is not logged in to gigya, log em in
			gigya.services.socialize.showLoginUI(priv.conf, params);
		}
	};
	
	/**
	* Socialize Login Pre-Login callback
	* 
	* This is needed because we're trying to determine user's current login state
	* Hence we can choose if it's a login or connect
	* 
	* Automatic Pre-Login callback
	* @author Eric Spector <Eric.Spector@aetn.com>
	* 
	* @param {Array} response AUTOMATIC, DO NOT TOUCH
	* 
	*/
	pub.callback.prep.login = function(response) {		
		//get login params from memory
		params = priv.callback.login.params;
		
		//set callback script from memory
		params.callback =  priv.callback.login.callback_script;
		
		if(response.user.isLoggedIn != undefined && response.user.isLoggedIn == true) {
			//the user is already logged in, therefore we want to initiate a connection rather than login
			priv.callback.login.enableConnect = true;
			gigya.services.socialize.connect(priv.conf, params);
		} else {
			
			priv.callback.login.enableConnect = false;
			//user is not logged in to gigya, log em in
			gigya.services.socialize.login(priv.conf, params);
		}
	};
	
	/**
	* Socialize Login Pre-(JSONP?) callback
	* 
	* Automatic Pre-JSONP callback
	* 
	* Note: JSONP Call will be skipped if this is a call from Connect
	* We cannot verify connect sig due to the way data is delivered from Gigya
	* 
	* @author Eric Spector <Eric.Spector@aetn.com>
	* 
	* @param {Array} response AUTOMATIC, DO NOT TOUCH
	* 
	*/
	pub.callback.login = function(response) {		
		pub.cache.reset();
				
		if(priv.callback.login.enableConnect) {
			//we are using connect instead of login, skip JSONP and go to the callback
			var r_status = false;
			if(response.status=='OK') {
				r_status = true;
			}
			
			eval(priv.callback.login.callback_jsonp_script)({status: r_status, usingConnect: true});
		} else {
			// Build the services call
		    var request = priv.ssos_server + '?command=login&pid=' + priv.pid + '&signature=' + encodeURIComponent(response.signature) + '&uid=' + encodeURIComponent(response.UID) + '&timestamp=' + response.timestamp +  '&callback=' + priv.callback.login.callback_jsonp_script; 
		    
		    //execute server-side callback via jsonp
		    aetn.lib.jsonp(request);
		}
	};
	
	/**
	* Socialize Login Post-JSONP callback
	* 
	* Sample reference function, shouldn't be used on live site
	* @author Eric Spector <Eric.Spector@aetn.com>
	* 
	* @param {Array} data AUTOMATIC, DO NOT TOUCH
	* 
	*/
	pub.callback.response.login = function(data) {
	    return;
	};
	
	/**
	 * Socialize Logout callback
	 * 
	 * This function resets the local cache
	 * If overwritten, be sure to include aetn.socialzie.cache.reset()
	 * Otherwise you will run in to caching issues
	 * 
	 * @author Eric Spector <Eric.Spector@aetn.com>
 	 * 
	 * @param {Array} data AUTOMATIC, DO NOT TOUCH
	 */
	pub.callback.logout = function(response) {
		pub.cache.reset();
		if(priv.callback.logout.callback_post_script != undefined) {
			priv.callback.logout.callback_post_script(response);
		}
	};
	
	/**
	 * Scaffold function
	 * 
	 * @deprecated
	 */
	pub.callback.disconnect = function(response) {
		alert('TODO: disconnect callback');
	};
	
	/**
	 * Error/Debug Handling can b expanded to work in IE
	 * 
	 */
	pub.error = function( msg ) {
		if (window.console && jQuery.trim(window.console.firebug) != '') console.error( msg );
	}

	pub.debug = function( msg ) {
		if (window.console && jQuery.trim(window.console.firebug) != '') console.debug( msg );
	}
	

	
	//------------------------------------------------------------------
	// these variables must be on the bottom of the application
	//------------------------------------------------------------------
	priv.execid = 1;
	
	priv.callback = {};
		
	priv.callback.linkAccountToCurrentUser = {};
	priv.callback.linkAccountToCurrentUser.callback_script = pub.callback.linkAccountToCurrentUser; //must be a function
	priv.callback.linkAccountToCurrentUser.callback_jsonp_script = 'aetn.socialize.callback.response.linkAccountToCurrentUser'; //must be a string
	
	priv.callback.unlinkAccounts = {};
	priv.callback.unlinkAccounts.callback_jsonp_script = 'aetn.socialize.callback.response.unlinkAccounts'; //must be a string
	
	priv.callback.login = {};
	priv.callback.login.callback_script = pub.callback.login; //must be a function
	priv.callback.login.callback_jsonp_script = 'aetn.socialize.callback.response.login'; //must be a string
	priv.callback.login.params = {}; //login params
	priv.callback.login.enableConnect = false; //run as connect in pre-callback JSONP
	
	priv.callback.showLoginUI = {};
	priv.callback.showLoginUI.callback_script = pub.callback.login; //must be a function
	priv.callback.showLoginUI.params = {}; //reset login para

	priv.callback.logout = {};
	priv.callback.logout.callback_script = pub.callback.logout; //must be a function
	
	priv.callback.connect = {};
	
	priv.callback.disconnect = {};
	
	priv.callback.getAvailableProviders = {};
	
	priv.callback.notifyLogin = {};
	priv.callback.notifyLogin.callback_jsonp_script = 'aetn.socialize.callback.response.notifyLogin';
	
	//internal callback overwrite setting
	priv.callback.linkAccountToCurrentUser.callback_notifyLogin = priv.callback.notifyLogin.callback_jsonp_script;
	
	priv.callback.getUserInfo = {};
	
	priv.conf = {
		APIKey: '2_dpuj8qzH1UKBAcoAzvdpftvboD_gW8U5o200mgqBxFQD76AIqHNbvmUYZa_fbtfh'
	};
	
	//backup the priv default settings
	var priv_default = priv;
	
	return pub;
}();

function dump (arr,level) {
	var dumped_text = "";
		if(!level) level = 0;

		//The padding given at the beginning of the line.
		var level_padding = "";
		for(var j=0;j<level+1;j++) level_padding += "    ";

		if(typeof(arr) == 'object') { //Array/Hashes/Objects
		 for(var item in arr) {
		  var value = arr[item];
		 
		  if(typeof(value) == 'object') { //If it is an array,
		   dumped_text += level_padding + "'" + item + "' ...\n";
		   dumped_text += dump(value,level+1);
		  } else {
		   dumped_text += level_padding + "'" + item + "' => \"" + value + "\"\n";
		  }
		 }
		} else { //Stings/Chars/Numbers etc.
		 dumped_text = "===>"+arr+"<===("+typeof(arr)+")";
		}
		
		return dumped_text;
	};
//----------------------------------------------------------------------
// AETN wrapper for jsonp library by Eric Spector <Eric.Spector@aetn.com>
//
// The purpose of this library is to provide a custom JSONP framework for AETN sites
// This library can be used stand-alone
//
//----------------------------------------------------------------------

if(!aetn) {
	//init aetn namespace
	var aetn={}; 
}

if(!aetn.lib) {
	//init aetn.lib namespace
	aetn.lib={}; 
}


/**
 * aetn.lib.jsonp
 * @projectDescription AETN JSONP Library
 * 
 * @author Eric Spector <Eric.Spector@aetn.com>
 * 
 * @params {String} request JSONP uri
 * 
 * @example aetn.lib.jsonp('http://www.mylifetime.com/jsonp_call');
 */
aetn.lib.jsonp = function() {
	pub = function(request) {
		// Create a new script object
		aObj = new aetn.lib.jsonp.object(request); 
	    // Build the script tag
	    aObj.buildScriptTag();
	    // Execute (add) the script tag
	    aObj.addScriptTag();
	    //remove tag after execution
	};
	
	return pub;
}();

//jsonp object
//provides granular functions to used by aetn.lib.jsonp() function
aetn.lib.jsonp.object = function() {
	// Original Script Information
	// ---------------------------
	//
	// JSONscriptRequest -- a simple class for accessing Yahoo! Web Services
	// using dynamically generated script tags and JSON
	//
	// Author: Jason Levitt
	// Date: December 7th, 2005
	// Constructor -- pass a REST request URL to the constructor
	
	JSONscriptRequest = function (fullUrl) {
	    // REST request path
	    this.fullUrl = fullUrl; 
	    // Keep IE from caching requests
	    this.noCacheIE = '&noCacheIE=' + (new Date()).getTime();
	    // Get the DOM location to put the script tag
	    this.headLoc = document.getElementsByTagName("head").item(0);
	    // Generate a unique script tag id
	    this.scriptId = 'YJscriptId' + aetn.lib.jsonp.scriptCounter++;
	};
	
	// buildScriptTag method
	//
	JSONscriptRequest.prototype.buildScriptTag = function () {
	
	    // Create the script tag
	    this.scriptObj = document.createElement("script");
	    
	    // Add script object attributes
	    this.scriptObj.setAttribute("type", "text/javascript");
	    this.scriptObj.setAttribute("src", this.fullUrl + this.noCacheIE);
	    this.scriptObj.setAttribute("id", this.scriptId);
	};
	 
	// removeScriptTag method
	// 
	JSONscriptRequest.prototype.removeScriptTag = function () {
	    // Destroy the script tag
	    this.headLoc.removeChild(this.scriptObj);  
	};
	
	// addScriptTag method
	//
	JSONscriptRequest.prototype.addScriptTag = function () {
	    // Create the script tag
	    this.headLoc.appendChild(this.scriptObj);
	};
	
	return JSONscriptRequest; //returned wrapped jsonp library
}();

//Static script ID counter
aetn.lib.jsonp.scriptCounter = 1;//----------------------------------------------------------------------
// AETN wrapper for Cookie Management library by Eric Spector <Eric.Spector@aetn.com>
//
// The purpose of this library is to provide a custom cookie framework for AETN sites
// This library can be used stand-alone
//
//----------------------------------------------------------------------

if(!aetn) {
	//init aetn namespace
	var aetn={}; 
}

if(!aetn.lib) {
	//init aetn.lib namespace
	aetn.lib={}; 
}

/**
 * aetn.lib.cookie
 * @projectDescription AETN Cookie Library
 * 
 * @author Eric Spector <Eric.Spector@aetn.com>
 */
aetn.lib.cookie = function() {
	var pub = {}; //public
	
	/**
	* aetn.lib.cookie.set
	* 
	* Public function to set cookie
	* 
	* @author Eric Spector <Eric.Spector@aetn.com>
	* 
	* @param {String} name Name of the cookie
	* @param {String} value Cookie data
	* @param {String} expires Optional Time to expire cookie (in seconds), if set to false... then session cookie
	* @param {String} path Optional Path
	* @param {String} domain Optional Domain
	* @param {String} secure Optional Is it secure?
	*/
	pub.set = function(name, value, expires, path, domain, secure) {
		// set time, it's in milliseconds
		var today = new Date();
		today.setTime( today.getTime() );

		/*
		if the expires variable is set, make the correct
		expires time, the current script below will set
		it for x number of days, to make it for hours,
		delete * 24, for minutes, delete * 60 * 24
		*/
		if ( expires ) {
			//expires = expires * 1000 * 60 * 60 * 24;
			expires = expires * 1000; //convert to seconds
		}
		
		var expires_date = new Date( today.getTime() + (expires) );

		document.cookie = name + "=" +escape( value ) +	( ( expires ) ? ";expires=" + expires_date.toGMTString() : "" ) + ( ( path ) ? ";path=" + path : "" ) +	( ( domain ) ? ";domain=" + domain : "" ) +	( ( secure ) ? ";secure" : "" );
	};
	
	/**
	* aetn.lib.cookie.get
	* 
	* Public function to get cookie
	* 
	* @author Eric Spector <Eric.Spector@aetn.com>
	* 
	* @param {String} name Name of the cookie
	*/
	pub.get = function(check_name) {
		// first we'll split this cookie up into name/value pairs
		// note: document.cookie only returns name=value, not the other components
		var a_all_cookies = document.cookie.split( ';' );
		var a_temp_cookie = '';
		var cookie_name = '';
		var cookie_value = '';
		var b_cookie_found = false; // set boolean t/f default f

		for ( i = 0; i < a_all_cookies.length; i++ ) {
			// now we'll split apart each name=value pair
			a_temp_cookie = a_all_cookies[i].split( '=' );


			// and trim left/right whitespace while we're at it
			cookie_name = a_temp_cookie[0].replace(/^\s+|\s+$/g, '');

			// if the extracted name matches passed check_name
			if ( cookie_name == check_name ) {
				b_cookie_found = true;
				// we need to handle case where cookie has no value but exists (no = sign, that is):
				if ( a_temp_cookie.length > 1 )	{
					cookie_value = unescape( a_temp_cookie[1].replace(/^\s+|\s+$/g, '') );
				}
				// note that in cases where cookie is initialized but no value, null is returned
				return cookie_value;
				break;
			}
			a_temp_cookie = null;
			cookie_name = '';
		}
		if ( !b_cookie_found ) {
			return null;
		}
	};
	
	/**
	* aetn.lib.cookie.remove
	* 
	* Public function to remove cookie
	* 
	* @author Eric Spector <Eric.Spector@aetn.com>
	* 
	* @param {String} name Name of the cookie
	* @param {String} path Optional Path
	* @param {String} domain Optional Domain
	*/
	pub.remove = function( name, path, domain ) {
		if ( pub.get( name ) ) {
			document.cookie = name + "=" +	( ( path ) ? ";path=" + path : "") + ( ( domain ) ? ";domain=" + domain : "" ) + ";expires=Thu, 01-Jan-1970 00:00:01 GMT";
		}
	};

	
	return pub;
}();//----------------------------------------------------------------------
// AETN wrapper for Serialize / Unserialize library by Eric Spector <Eric.Spector@aetn.com>
//
// The purpose of this library is to provide a custom serialization framework for AETN sites
// This library can be used stand-alone
//
// Library based on discussion at http://phpjs.org/functions/serialize:508
//
//----------------------------------------------------------------------

if(!aetn) {
	//init aetn namespace
	var aetn={}; 
}

if(!aetn.lib) {
	//init aetn.lib namespace
	aetn.lib={}; 
}


/**
 * @projectDescription AETN (Un)Serialize Library
 * 
 * @author Eric Spector <Eric.Spector@aetn.com>
 * 
 */

/**
* aetn.lib.serialize
* 
* Public function to serialize data
* 
* @param {Object} data Object to serialize
* @return {String} serialized data
* 
* @example aetn.lib.serialize(data);
*/
aetn.lib.serialize = function() {
    var f = function(data) {
	    var str_data;        
	    if (data == null || (typeof(data) == 'string' && data == '')) {
	            str_data = 'N;';
        } else switch(typeof(data)) {
            case 'object':
            	var arrayCount = 0;

                str_data = '';

                for (i in data) {
                	if (i == 'length') {
                		continue;
            		}                                                
                	
                	arrayCount++;
                	
                	switch (typeof(i)) {
	                    case 'number':                                                                
	                    	str_data += 'i:' + i + ';' + f(data[i]);
	                        break;
	                    case 'string':
	                        str_data += 's:' + i.length + ':"' + i + '";' + f(data[i]);                                                                
	                        break;
	                    default:
	                        break;                                                
                    }
                }

                if (!arrayCount) {
                	str_data = 'N;';        
                } else {
                	str_data = 'a:' + arrayCount + ':{' + str_data + '}';                                        
            	}
                    
                break;
            case 'string':                                        
            	str_data = 's:' + data.length + ':"' + data + '";';
                break;    
            case 'number':
                str_data = 'i:' + data + ';';                                        
                break;
            case 'boolean':
                str_data = 'b:' + (data ? '1' : '0') + ';';
                break;        
            default:
                return null;
	    } 
	    return str_data;
    };

    return f;        
}();

/**
* aetn.lib.unserialize
* 
* Public function to unserialize data
* 
* @param {String} str Serialized data
* @return {Object} data Object to unserialize
* 
* @example aetn.lib.unserialize(data);
*/
aetn.lib.unserialize = function() {    
    var priv = {};
    
    priv.matchB = function (str, iniPos) {
        var nOpen, nClose = iniPos;
        do  {
        	nOpen = str.indexOf('{', nClose+1);
            nClose = str.indexOf('}', nClose+1);

            if (nOpen == -1)  {
            	return nClose;
            }
            if (nOpen < nClose ) {
                nClose = priv.matchB(str, nOpen);                                
            }
        } while (nOpen < nClose);
        return nClose;
    };
    
    var f = function (str) {
    	
        switch (str.charAt(0))  {
        	case 'a':
        		var data = new Array();
                var n = parseInt( str.substring(str.indexOf(':')+1, str.indexOf(':',2) ) );
                var arrayContent = str.substring(str.indexOf('{')+1, str.lastIndexOf('}'));
                for (var i = 0; i < n; i++)  {
                	var pos = 0;

                    /* Process Index */
                    var indexStr = arrayContent.substr(pos, arrayContent.indexOf(';')+1);                                                
                    var index = f(indexStr);
                    pos = arrayContent.indexOf(';', pos)+1;
                                
                    /* Process Content */
                    var part = null;                                                
                    switch (arrayContent.charAt(pos)) {
                    	case 'a':
                    		var pos_ = priv.matchB(arrayContent, arrayContent.indexOf('{', pos))+1;
                            part = arrayContent.substring(pos, pos_);                                                                
                            pos = pos_;
                            data[index] = f(part);
                            break;
                                
                    	case 's':                                                                
                    		var pval = arrayContent.indexOf(':', pos+2);
                            var val  = parseInt(arrayContent.substring(pos+2, pval));
                            pos = pval + val + 4;
                            data[index] = arrayContent.substr(pval+2, val);
                            break;
                            
                        default:
                           	part = arrayContent.substring(pos, arrayContent.indexOf(';', pos)+1);
                            pos = arrayContent.indexOf(';', pos)+1;
                            data[index] = f(part);                                                                
                            break;
                    }
                    arrayContent = arrayContent.substr(pos);
                }
                break;                                        
            case 's':
            	var pos = str.indexOf(':', 2);
                var val = parseInt(str.substring(2,pos));
                var data = str.substr(pos+2, val);                                        
                str = str.substr(pos + 4 + val);
                break;

            case 'i':
            case 'd':                                        
            	var pos = str.indexOf(';');
                var data = parseInt(str.substring(2,pos));
                str = str.substr(pos + 1);
                break;
            case 'N':
                var data = null;
                str = str.substr(str.indexOf(';') + 1);
                break;
            case 'b':
                var data = str.charAt(2) == '1' ? true : false;
                break;
        }
        return data;                
    };
    
    return f;
}();
