//
// Copyright 2009-2010 Electronic Arts, Inc.
//


/**
	* Set of helper methods to be used to interact with facebook.
	*/
var PogoFB = PogoFB || {
	/* Flag to indicate if the API was initialized. */
	_apiInitialized: false,
	
	/* Flag to indicate if the initialization after a status change has been done. */
	_statusChangeInitilized: false,
	
	/* Stores the allowed permissions on facebook */
	_allowedPermissions: '',

	/**
	* Initializes the Facebook API.
	*/
	initializeFB: function() {
	if (PogoFB._apiInitialized) {
		return;
	}
	var fbroot = $('fb-root');

	if (fbroot == null) {
		fbroot = new Element('div', {id: 'fb-root'});
		fbroot.inject($(document.body), 'bottom');
	}

	FB.init({appId: PogoFBConstants.apiKey, 
		status: true, 
		cookie: true,
		oauth:true, 
		xfbml: true});
	
//    FB.login(function(response) {
// 		  if (response.authResponse) {
// 		  }
// 		}, {scope:'publish_stream'});
	
	FB.Event.subscribe('auth.login', function(response) {
		PogoFB._onStatusChange();
		if (response.authResponse) {
			FB.api('/me/permissions', function(response){
			var perms = response.data[0];
			for(var key in perms){
				if(perms[key] == 1){
					PogoFB._allowedPermissions += (key + ",");
				}
			}			
			});
		}
	});
/*
	FB.Event.subscribe('auth.statusChange', function(response) {
		PogoFB._onStatusChange();
	});

		PogoFB._onStatusChange();
	});
*/

	FB.Event.subscribe('edge.create', function(response) {
		//commenting/disabling linking after 'like' action.
		//PogoFB.login();        //To enable linking after 'like' just un-comment  this line
	});

	PogoFB._apiInitialized = true;
	PogoFB._onStatusChange(false);
	PogoFB._statusChangeInitialize();
	},

	/**
	* Array to store the functions that should be invoked on initialization.
	*/
	onInitialize: new Array(),

	/**
	* Function that calls any function stored into onInitialize array.
	*/
	_statusChangeInitialize: function() {
	if (PogoFB._statusChangeInitilized) {
		return;
	}
	for (var i = 0; i < PogoFB.onInitialize.length; i++) {
		PogoFB.onInitialize[i]();
	}
	PogoFB._statusChangeInitilized = true;
	},

	/**
	* Array to store the functions that should be invoked when the status is
	* verified so that the enclosing page can adapt to the new status.
	*
	* Functions pushed onto this array can optionally take as a parameter the
	* status details (a JSON representation of
	* com.pogo.html.struts.fbconnect.FacebookConnectStatusDetails).
	*/
	onStatusValidation: new Array(),

	onConnectCallback: null,

	/**
	* Function to be called as a callback on the FB.init method call, if a user
	* is connected. This function invokes all the functions that have been pushed
	* to the onStatusValidation array.
	*/
	_onStatusChange: function(showErrorPopup) {
	PogoFB._statusChangeInitialize();
	PogoFB.Status.getStatus(function(status) {
		for (var i = 0; i < PogoFB.onStatusValidation.length; i++) {
		PogoFB.onStatusValidation[i](status);
		}
		if (status.connected && !status.newLink) {
		if (typeof PogoFB.onConnectCallback == 'function') {
			PogoFB.onConnectCallback();
			PogoFB.onConnectCallback = null;
		}
		}
	}, showErrorPopup);
	},

	/**
	* Function that calls any function stored into onNewLinkFunctions array.
	*/
	onNewLink: function() {
	if (typeof PogoFB.onConnectCallback == 'function') {
		PogoFB.onConnectCallback();
		PogoFB.onConnectCallback = null;
	}
	},

	getAllowedPermissions: function() {
	return _allowedPermissions;
	},

	hasPermission: function(permission, callback) {
	var list = PogoFB._allowedPermissions.split(',');
	for(var i=0, size=list.length; i<size; i++) {
		if (list[i] == permission) {
			if (callback) {
				callback();
			}
			return true;
		}
	}
	return false;
	},

	/**
	* Method to request the current user to login. This method assumes that it
	* is not invoked if the current pogo user and facebook user are already
	* linked.
	*/
	login: function(alreadyPrompted) {
	if (window.ie6) {
		PogoFB.Popover.show('/fbconnect/upgradebrowser.do');
	} else {
		var functionToUse;
		if(alreadyPrompted=='undefined' || !alreadyPrompted){
			functionToUse = FB.login;
		} else {
			functionToUse = FB.getLoginStatus;
		}		
		functionToUse(function(response) {
				if (response.authResponse) {
					FB.api('/me/permissions', function(response){
					var perms = response.data[0];
					for(var key in perms){
						if(perms[key] == 1){
							PogoFB._allowedPermissions += (key + ",");
						}
					}			
					});
					PogoFB._Link.createLink();
				}
			}, {scope:'publish_stream'});
	}
	},

	/**
	* Function that calls FB API to show FB authentication popup.
	*/
	requireSession: function() {
	PogoFB.login();
	},

	/**
	* Method that logs out per request the current facebook user and asks the
	* user to log back in to facebook (with a different user).
	*/
	logout: function() {
	FB.logout(function() {
		PogoFB.requireSession();
		//PogoFB._Link.createLink();
	});
	},

	saveSettings: function(settingsForm) {
	var url = "/fbconnect/settings/save.do?facebookProfileVisible=" + settingsForm.elements['facebookProfileVisible'].checked;
	MootoolsUtils.request(url, {
		method: 'get',
		onSuccess: function(responseText){
		// nothing...
		},
		onFailure: PogoFB.Error.showServerErrorPopUp
	});
	},

	checkAutopublishPermission: function (callbackOnSuccess,callbackOnFail,callback) {
		// first check for the killswitch
		if (!PogoFBConstants.autoshareEnabled) {
			if ( typeof callbackOnFail =='function') {
				callbackOnFail();
			}
			return;
		}
		else {
		FB.login(function(response) {
			if (response.authResponse) {
					FB.api('/me/permissions', function(response){
					var perms = response.data[0];
					for(var key in perms){
						if(perms[key] == 1){
							PogoFB._allowedPermissions += (key + ",");
						}
					}			
					});
					var hasPerm = PogoFB.hasPermission('publish_stream');
					if (hasPerm) {
						if ( typeof callbackOnSuccess == 'function') {
							if(typeof callback == 'function'){
								callbackOnSuccess(callback);
							} else {
								callbackOnSuccess();
							}
						}
					} else {
						if ( typeof callbackOnFail == 'function') {
							callbackOnFail();
						}
					}				
				}
			}, {scope:'publish_stream'});
		}
		},
		
	hasAutopublishPermission: function (callbackOnSuccess,callbackOnFail) {
	// first check for the killswitch
	if (!PogoFBConstants.autoshareEnabled) {
		if ( typeof callbackOnFail =='function') {
			callbackOnFail();
		}
		return;
	}
	else {
		var hasPerm = PogoFB.hasPermission('publish_stream');
		if (hasPerm) {
			if ( typeof callbackOnSuccess == 'function') {
				callbackOnSuccess();
				}
		} else {
			if ( typeof callbackOnFail == 'function') {
				callbackOnFail();
				}
		}
	}
	},
	
	/**
	* Wrapper that ensures that the given callback will be invoked if and only
	* if the user has connected, and prompts the user to connect if he hasn't.
	*/
	requireConnected: function(callback, connectRequestedTag) {
	PogoFB.Status.getStatus(function (status) {
		if (status.connected) {
		callback();
		} else {
		PogoFB.onConnectCallback = callback;
		if (!status.isPogoUserLinked) {
			if (connectRequestedTag) {
			PogoFB.Utils.omnitureTagging(connectRequestedTag);
			}
		}
		PogoFB.login();
		}
	});
	},

	/**
	* Wrapper that ensures that the given callback will be invoked if and only
	* if the user has the required permission or grants it upon the request.
	* 
	* FIXME - used by publish mini - need to refactor to work with new API
	* (get response.perms on login and resync it with a login listener)
	*/
	requirePermission: function(permission, callback, page) {
	//FB.Facebook.apiClient.users_hasAppPermission(permission, function(result){
		var hasPerm = PogoFB.hasPermission(permission);
		if (hasPerm) {
		// user already has permission
		if ( typeof callback =='function') {
			callback();
		}
		} else {
			// track init autopublish grant
			PogoFB.Utils.omnitureTagging(PogoFB._getInitPermissionOmnitureTag(page));
			FB.login(function(response) {
			if (response.authResponse) {
					FB.api('/me/permissions', function(response){
					var perms = response.data[0];
					for(var key in perms){
						if(perms[key] == 1){
							PogoFB._allowedPermissions += (key + ",");
						}
					}			
				});
			}
			hasPerm = PogoFB.hasPermission(permission);
			if (hasPerm){
				PogoFB.Utils.omnitureTagging(PogoFB._getConfirmedPermissionOmnitureTag(page));
				callback();
			} else {
				PogoFB.Utils.omnitureTagging(PogoFB._getRejectedPermissionOmnitureTag(page));
			}
			}, {scope: permission});
		}
	},

	_getInitPermissionOmnitureTag: function(publishType) {
		if (publishType == 'popup') {
			return PogoFBConstants.Messages.popupSettingsInitAutopublish;
			} else {
			return PogoFBConstants.Messages.defaultSettingsInitAutopublish; 
			}
		},

	_getConfirmedPermissionOmnitureTag: function(publishType) {
		if (publishType == 'popup') {
		return PogoFBConstants.Messages.popupSettingsDoAutopublish;
		} else {
		return PogoFBConstants.Messages.defaultSettingsDoAutopublish; 
		}
	},
	_getRejectedPermissionOmnitureTag: function(publishType) {
	if (publishType == 'popup') {
		return PogoFBConstants.Messages.popupSettingsRejectAutopublish;
		} else {
		return PogoFBConstants.Messages.defaultSettingsRejectAutopublish; 
		}
	},
	/**
	* Wrapper that removes the autopublish permission.
	*/
	removeAutoPublishPermission: function(callbackIfSuccess, callbackIfFail) {
	var url = "/fbconnect/removeextperm.do";
	MootoolsUtils.request(url, {
			method: 'get',
			onSuccess: function(responseText){
			PogoFB.Utils.omnitureTagging(PogoFBConstants.Messages.settingsRemoveAutopublish);
			callbackIfSuccess();
			// removing permissions from javascript cache
			var hasPerm = PogoFB.hasPermission('publish_stream');
			if (hasPerm) {
				PogoFB._allowedPermissions = PogoFB._allowedPermissions.replace('publish_stream','');
			}
			},
			onFailure: function(){
			if (typeof callbackIfFail =='function') {
				callbackIfFail();
			} else {
			PogoFB.Error.showServerErrorPopUp();
			}
			}
		});
	},
	
	/**
	* Method to remove the link between the facebook and pogo user. It shows a 
	* confirmation popover and if the user confirms the link is removed.
	*
	* TODO(cdolan): Figure out how to make this look more elegant.
	*/
	removeLink: function(omnitureMessage) {
	var onclickFunctions = "PogoFB.Popover.close(this);PogoFB._Link.remove();"
	if (omnitureMessage) {
		onclickFunctions = "PogoFB.Utils.omnitureTagging('" + omnitureMessage + "'); " + onclickFunctions;
	}
	
	PogoFB.Popover.showContent(
		'<div id="mdBox">'
		+ '<div class="hdr">'
		+   '<img src="/img/fbconnect/popover/hd-lt-cnr.gif" class="inl" />'
		+   '<h3 class="inl">'
		+   PogoFBConstants.Messages.removeLinkConfirmTitle
		+   '</h3>'
		+   '<img src="/img/fbconnect/popover/hd-rt-cnr.gif" class="inl-r" />'
		+   '<div class="clear"></div>'
		+ '</div>'
		+ '<div class="withfblogo">'
		+    '<img src="/img/fbconnect/facebook-logo.gif" class="inl firstBtn" />'
		+    '<div class="desc inl">'
		+      PogoFBConstants.Messages.removeLinkConfirmMessage
		+    '</div>'
		+    '<div class="clear"></div>'
		+  '</div>'
		+  '<div class="ftr">'
		+    '<a href="javascript:void(0);" onclick="' + onclickFunctions + '">'
		+      PogoFBConstants.Images.disconnectButton
		+    '</a>'
		+    '<a href="javascript:void(0);" onclick="PogoFB.Popover.close(this)">'
		+      PogoFBConstants.Images.cancelButton
		+    '</a>'
		+  '</div>'
		+  '</div>', false);
	}
};

/**
	* Helper methods to handle the status of the current user. This is done this
	* way to allow reusing the recently looked up status, rather than making
	* multiple ajax calls.
	*/
PogoFB.Status = {
	_currentStatus: null,

	_currentShareStatus: null,

	/**
	* Invokes the callback with the _currentStatus. If none has been set as
	* current, it invokes an action to get the current one.
	*/
	getStatus: function(callback, showErrorPopup) {
	//if (PogoFB.Status._currentStatus != null ) {
	//  callback(PogoFB.Status._currentStatus);
	//  return;
	//}
	//FIXME

	var shouldShowError = typeof showErrorPopup == 'undefined' || showErrorPopup;

	MootoolsUtils.request("/fbconnect/getstatus.do", {
		method: 'get',
		onSuccess: function(responseText){
		PogoFB.Status._currentStatus = eval(responseText);
		callback(PogoFB.Status._currentStatus);
		},
		onFailure: function() {
		if (shouldShowError) {
			PogoFB.Error.showServerErrorPopUp();
		}
		}
	});
	},

	/**
	* Invokes the callback with the _currentStatus. If none has been set as
	* current, it invokes an action to get the current one.
	*/
	getShareStatus: function(callback, showErrorPopup) {
	var shouldShowError = typeof showErrorPopup == 'undefined' || showErrorPopup;

	MootoolsUtils.request("/fbconnect/getsharestatus.do", {
		method: 'get',
		onSuccess: function(responseText){
		PogoFB.Status._currentShareStatus = eval(responseText);
		callback(PogoFB.Status._currentShareStatus);
		},
		onFailure: function() {
		if (shouldShowError) {
			PogoFB.Error.showServerErrorPopUp();
		}
		}
	});
	},
	
	/**
	* Updates the current status object.
	*/
	updateCurrentStatus: function(status) {
	PogoFB.Status._currentStatus = status;
	}
};

/**
	* Handler for error messages.
	*/
PogoFB.Error = {

	/**
	* Generic error messaage shown within a popup. Hardcoded to be used as a
	* generic error popup.
	*
	* TODO(cdolan): Figure out how to make this look more elegant.
	*/
	showServerErrorPopUp: function() {
	PogoFB.Popover.showContent(
		'<div id="mdBox">'
		+ '<div class="hdr">'
		+   '<img src="/img/fbconnect/popover/hd-lt-cnr.gif" class="inl" />'
		+   '<h3 class="inl">'
		+   PogoFBConstants.Messages.errorInternalTitle
		+   '</h3>'
		+   '<img src="/img/fbconnect/popover/hd-rt-cnr.gif" class="inl-r" />'
		+   '<div class="clear"></div>'
		+ '</div>'
		+ '<div class="withfblogo">'
		+    '<img src="/img/fbconnect/facebook-logo.gif" class="inl firstBtn" />'
		+    '<div class="desc inl">'
		+      PogoFBConstants.Messages.errorFatalAjaxProblem
		+    '</div>'
		+    '<div class="clear"></div>'
		+  '</div>'
		+  '<div class="ftr">'
		+    '<a href="javascript:void(0)" onclick="if(typeof parentCallback == \'function\'){parentCallback(false);}PogoFB.Popover.close(this);">'
		+      PogoFBConstants.Images.cancelButton
		+    '</a>'
		+  '</div>'
		+  '</div>', true);
	}
};

	
/**
	* Set of methods associated to user linkage.
	*/
PogoFB._Link = {

	/**
	* Attempts to create a link between the current pogo user and the facebook
	* user (if none login, requires a login). This method assumes that it is not
	* invoked if the current pogo user and facebook user are already linked.
	*/
	createLink: function(fbstatus) {
	if (fbstatus == null) {
		FB.getLoginStatus( function(response) {
		fbstatus = response;
		});
	}

	if (fbstatus.authResponse) { // same as: fbstatus.status == "connected") {
		PogoFB.Status.getStatus(function(status) {
			// three conditions may occur here:
			// - the pogo user has a link and he's attempting to log in with
			//   another facebook user which means we must show the users
			//   mismatch error
			// - the current fb user is linked to someone else, and the current
			//   pogo user is trying to create a link to him; in this case we
			//   must show the already connected error
			// - the current fb user has granted the app but the link was
			//   removed (though not the grant), therefore the user is free to
			//   be linked, we try to go through the linking process
			if (status.connected) {
			// nothing to do
			} else if (status.isPogoUserLinked) {
			PogoFB.Popover.show('/fbconnect/error/usersmismatch.do');
			} else if (status.isFbUserLinked) {
			PogoFB.Popover.show('/fbconnect/error/alreadyconnected.do');
			} else {
			PogoFB._Link.callLinkAction();
			}
		});
	} 
	},

	/**
	* Effectively invokes the action that creates the link between the two users.
	*/
	callLinkAction: function() {
	MootoolsUtils.request("/fbconnect/link.do", {
		method: 'get',
		onSuccess: function(responseText){
			var status = eval(responseText);

			// status may have changed, so we have to update it
			PogoFB.Status.updateCurrentStatus(status);

			if (!status.connected && status.isPogoUserLinked) {
			//PogoFB.Popover.show('/fbconnect/error/usersmismatch.do');
			alert("user missmatch");
			} else if (!status.connected && status.isFbUserLinked) {
			//PogoFB.Popover.show('/fbconnect/error/alreadyconnected.do');
			alert("user already connected");
			}

			PogoFB._onStatusChange();

			// if it is a new link, we must show the settings dialog
			//if it is a new link then trigger a new omniture event to track
			//event10 == FACEBOOK_ACCT_LINK
			if (status.newLink) {
				if (typeof OmnitureEvent == 'function') {
				OmnitureEvent(s.pageName, 'event10');
				}
				PogoFB.Utils.openInviteFriendsPopUp();
			}
		},
		onFailure: function(response) {
			//FIXME PogoFB.Error.showServerErrorPopUp
			alert("FAILED to request /fbconnect/link.do");
		}
	});
	},

	/**
	* Action that removes the link between the current facebook and pogo user.
	*/
	remove: function() {
	MootoolsUtils.request("/fbconnect/removelink.do", {
		method: 'get',
		onSuccess: function(responseText){
			window.location = responseText;
		},
		onFailure: PogoFB.Error.showServerErrorPopUp
	});
	}
};

PogoFB.Popover = {

	show: function(url) {
		if (PogoFB.Popover.current) {
		// FB has a minor bug by which once a function is passed on to the require
		// session it will remain there. Therefore, if the user clicks on the
		// connect button, closes the window and clicks back on it, the
		// _callLinkAction will be invoked twice, and that could result in
		// duplicate popups
		return;
		}
		MootoolsUtils.request(url, {
			method: 'get',
			onSuccess: function(responseText){
			PogoFB.Popover.current =  new Popover(responseText);
			if(typeof parentCallback == 'function'){parentCallback(true);}
			},
			onFailure: PogoFB.Error.showServerErrorPopUp,
			evalScripts:true
		});
	},

	showContent: function(innerHTML, forceClose) {
		if(typeof parentCallback == 'function'){parentCallback(true);}
		if (PogoFB.Popover.current) {
		// FB has a minor bug by which once a function is passed on to the require
		// session it will remain there. Therefore, if the user clicks on the
		// connect button, closes the window and clicks back on it, the
		// _callLinkAction will be invoked twice, and that could result in
		// duplicate popups
		if (!forceClose) {
			return;
		}
		PogoFB.Popover.close();
		}
		PogoFB.Popover.current = new Popover(innerHTML);
		PogoFB.Popover.current._openModal();
	},

	close: function(element) {
		if(typeof parentCallback == 'function'){parentCallback(false);}
		if (element) {
		Popover.close(element);
		PogoFB.Popover.current = null;
		} else {
		if (PogoFB.Popover.current) {
			PogoFB.Popover.current.closeModal();
			PogoFB.Popover.current = null;
		}
		
		}
	}
};

/**
	* Set of utility methods.
	*/
PogoFB.Utils = {
	
	/**
		* Method that returns the html to be used to display the login button,
		* instead of Facebook's standard fbml tag. 
		*/
	getLoginButtonHtml: function(id, msg,size) {
		if (size == 'undefined') {
			size='large';
		}
		var htmlString = 
			'<div id="' + id +'"> <fb:login-button scope="publish_stream" v="2" size="'+ size +'" onlogin="PogoFB.login(true);" > '+
				msg + 
			'</fb:login-button> </div>';
		return htmlString;
	},

	/**
		* Adds the omniture tagging to the given element's onclick event.
		*/ 
	tagOnClick: function(element, message) {
		$(element).addEvent('click', function() {
		PogoFB.Utils.omnitureTagging(message);
		});
	},
	
	_addSourceId: function(url, tag) {
		return PogoFB.Utils._addParam(url,'sourceid',tag);
	},

	_addParam: function(url, param, value) {
		if (url.indexOf('?') < 0) {
		return url + '?' + param + '=' + value;
		} else {
		return url + '&' + param + '=' + value;
		}
	},
	
	/**
		* Sets the omniture tagging for a custom action.
		*
		* Preconditions: omniture s_gi function must be declared in the page that calls this utility class.
		*/ 
	omnitureTagging: function(message, events) {
		if (events) {
		if (typeof OmnitureEvent == 'function') {
			OmnitureEvent(message, events);
		}  
		} else {
		if(typeof OmnitureCustomLink == 'function') {
			OmnitureCustomLink(message);
		}
		}
	}, 

	/**
		* Returns the link with the standard 'What's this' message, that opens the
		* FAQ as a popover.
		*/
	getFaqLink: function() {
		var htmlString = 
			'<a href="javascript:void(0)" onclick="var win = window.open(\'/fbconnect/faq.do\', \'PogoFbHelp\', \'width=600,height=460,location=no,resizable=yes,toolbar=no,scrollbars=yes\');if (win) win.focus();" >'
			+ PogoFBConstants.Messages.commonWhatIsThis
			+ '</a>';
		return htmlString;
	},

	/**
		* Opens a pop up extracting the data from the anchor element received.
		*/
	openInviteFriendsPopUp: function() {
		window.open(PogoFBConstants.URLs.inviteFriends,
			'_blank', 'width=800px,height=600px');
	},
	/**
		* Parses the DOM tree to reflect Facebook XFBML dynamic changes and
		* after all elements are ready it executes the callback function.
		*/
	parseDom: function(callback) {
		FB.XFBML.parse();
		callback();
	}
};

/**
	* Formats a message following java's MessageFormat behavior.
	*/
var MsgFormat = MsgFormat || {
	format: function(s) {
	var i = 1;
	while (i < arguments.length) {
		s = s.replace("{" + (i-1) + "}", arguments[i++]);
	}
	return s;
	}
};

/**
	* Add an event so that the Facebook Api is initialized as soon as the DOM is
	* ready.
	*/
if (PogoFBConstants.facebookEnabled) {
	window.addEvent('load', function() {
	PogoFB.initializeFB();
	});
}

