// requires cg, event, util, jquery, jquery.jqmodal, jquery.json 
//closure to prevent $ conflict

require('CG.Event', 'CG.FacebookHelper');

(function($) {		

		//global CG object
		CG = typeof(CG) == 'undefined' ? {} : CG;
		
/***** BEGIN LOCAL PROPERTY DEFINITION *****/
		var _callback = null,
			_options  = {};
/***** END LOCAL PROPERTY DEFINITION *****/

/***** BEGIN LOCAL FUNCTION DEFINITION *****/

		var	_inviteFriends = function(options) {
			// display html elements only visible when logged into facebook
			FB_RequireFeatures(["XFBML"], function() {

				if (!FB.Facebook.get_sessionWaitable().get_isReady()) {
					manuallogin(window.location);
				} else {
					FB.Facebook.get_sessionState().waitUntilReady(function() {
				
						var inviteMessage     = (options.inviteMessage != null)    ? options.inviteMessage    : '',
							inviteType        = (options.inviteType != null)       ? options.inviteType       : 'Challenge Games',
							inviteAcceptUrl   = (options.inviteAcceptUrl != null)  ? options.inviteAcceptUrl  : '',
							inviteButtonText  = (options.inviteButtonText != null) ? options.inviteButtonText : 'Accept',
							friendSelectorTitle    = (options.friendSelectorTitle != null)    ? options.friendSelectorTitle    : '',
							friendSelectorMessage  = (options.friendSelectorMessage != null)  ? options.friendSelectorMessage  : 'Challenge Games',
							friendSelectorCloseUrl = (options.friendSelectorCloseUrl != null) ? options.friendSelectorCloseUrl : '',
							friendSelectorWidth    = (options.friendSelectorWidth != null)    ? options.friendSelectorWidth    : 640,
							friendSelectorCols     = (options.friendSelectorCols != null)     ? options.friendSelectorCols     : 4,
							friendSelectorRows     = (options.friendSelectorRows != null)     ? options.friendSelectorRows     : 3,
							friendSelectorExcludeIds = (options.friendSelectorExcludeIds != null) ? options.friendSelectorExcludeIds : null,
							canvasUrl  = (options.canvasUrl != null)  ? options.canvasUrl  : '',
							serverName = (options.serverName != null) ? options.serverName : '',
	
							// forward response to external accounts plugin
							friendSelectorCloseUrl = _buildFBUrl('http://' + window.location.host +'/external_accounts/facebook/processinvites?next=' + encodeURIComponent(_buildFBUrl(friendSelectorCloseUrl)));
						
							// if we are in a facebook iframe, replace the canvas url with the server name
							// otherwise the skip button in the invite form will display the full facebook page inside the facebook iframe
							var fbParams = _getFBQueryParameters();
							if (fbParams['fb_sig_in_iframe'] && canvasUrl.length > 0 && serverName.length > 0) {
								canvasUrl  = canvasUrl.replace(/^\s+|\s+$/g,"");
								serverName = ((serverName.indexOf('http://') < 0) ? 'http://' : '') + serverName.replace(/^\s+|\s+$/g,"");
								friendSelectorCloseUrl = friendSelectorCloseUrl.replace(canvasUrl, serverName).replace(encodeURIComponent(canvasUrl), encodeURIComponent(serverName));
							}
							
							invitationFBML = 
								'<fb:fbml>' +
									'<fb:request-form action="' + friendSelectorCloseUrl + '" close_dialog="1" method="POST" invite="true" type="' + inviteType + '" content="' + inviteMessage + 
										'<fb:req-choice url=\'' + inviteAcceptUrl + '\' label=\'' + inviteButtonText + '\' />">' + 
										'<fb:multi-friend-selector rows="' + friendSelectorRows + '" cols="' + friendSelectorCols + '" showborder="false" actiontext="' + friendSelectorMessage + '" exclude_ids="' + friendSelectorExcludeIds + '" />' + 
									'</fb:request-form>' + 
								'</fb:fbml>',
				
							dialog = new FB.UI.FBMLPopupDialog(friendSelectorTitle, invitationFBML);
				
						dialog.set_placement(FB.UI.PopupPlacement.topCenter);
						dialog.setContentWidth(friendSelectorWidth);
						dialog.show();
					});
				}
			});
		},
		
		_inviteFriendsInline = function(options) {
			// display html elements only visible when logged into facebook
			FB_RequireFeatures(["XFBML"], function() {

				if (!FB.Facebook.get_sessionWaitable().get_isReady()) {
					manuallogin(window.location);
				} else {
					FB.Facebook.get_sessionState().waitUntilReady(function() {
				
						var parentElementId   = options.parentElementId,
							inviteMessage     = (options.inviteMessage != null)    ? options.inviteMessage    : '',
							inviteType        = (options.inviteType != null)       ? options.inviteType       : 'Challenge Games',
							inviteAcceptUrl   = (options.inviteAcceptUrl != null)  ? options.inviteAcceptUrl  : '',
							inviteButtonText  = (options.inviteButtonText != null) ? options.inviteButtonText : 'Accept',
							friendSelectorTitle    = (options.friendSelectorTitle != null)    ? options.friendSelectorTitle    : '',
							friendSelectorMessage  = (options.friendSelectorMessage != null)  ? options.friendSelectorMessage  : 'Challenge Games',
							friendSelectorCloseUrl = (options.friendSelectorCloseUrl != null) ? options.friendSelectorCloseUrl : '',
							friendSelectorWidth    = (options.friendSelectorWidth != null)    ? options.friendSelectorWidth    : 640,
							friendSelectorCols     = (options.friendSelectorCols != null)     ? options.friendSelectorCols     : 4,
							friendSelectorRows     = (options.friendSelectorRows != null)     ? options.friendSelectorRows     : 3,
							friendSelectorExcludeIds = (options.friendSelectorExcludeIds != null) ? options.friendSelectorExcludeIds : null,
							canvasUrl  = (options.canvasUrl != null)  ? options.canvasUrl  : '',
							serverName = (options.serverName != null) ? options.serverName : '',

							// forward response to external accounts plugin
							friendSelectorCloseUrl = _buildFBUrl('http://' + window.location.host +'/external_accounts/facebook/processinvites?next=' + encodeURIComponent(_buildFBUrl(friendSelectorCloseUrl)));
							
							// if we are in a facebook iframe, replace the canvas url with the server name
							// otherwise the skip button in the invite form will display the full facebook page inside the facebook iframe
							var fbParams = _getFBQueryParameters();
							if (fbParams['fb_sig_in_iframe'] && canvasUrl.length > 0 && serverName.length > 0) {
								canvasUrl  = canvasUrl.replace(/^\s+|\s+$/g,"");
								serverName = ((serverName.indexOf('http://') < 0) ? 'http://' : '') + serverName.replace(/^\s+|\s+$/g,"");
								friendSelectorCloseUrl = friendSelectorCloseUrl.replace(canvasUrl, serverName).replace(encodeURIComponent(canvasUrl), encodeURIComponent(serverName));
							}
							
							var inviteXFBML = 
								'<fb:serverfbml style="width: ' + friendSelectorWidth + '">' + 
									'<' + 'script type="text/fbml">' +
										'<fb:fbml>' +
											'<fb:request-form action="' + friendSelectorCloseUrl + '" close_dialog="1" method="POST" invite="true" type="' + inviteType + '" content="' + inviteMessage + ' <fb:req-choice url=\'' + inviteAcceptUrl + '\' label=\'' + inviteButtonText + '\' />">' +
												'<fb:multi-friend-selector cols="' + friendSelectorCols + '" rows="' + friendSelectorRows + '" showborder="false" actiontext="' + friendSelectorMessage + '" exclude_ids="' + friendSelectorExcludeIds + '" />' + 
											'</fb:request-form>' + 
										'</fb:fbml>' +
									'</' + 'script>' +
								'</fb:serverfbml>';
								
							inviteXFBML = inviteXFBML.replace('/', '\/').replace("\n", "").replace("\t", "");
						
							// prompt the user to log onto Facebook
							if (!FB.Facebook.get_sessionWaitable().get_isReady()) {
								manuallogin(window.location);
							}
							
							FB.Facebook.get_sessionWaitable().waitUntilReady(function() {
								document.getElementById(parentElementId).innerHTML = inviteXFBML;
								if(FB.XFBML.Host.parseDomTree) {
									setTimeout(FB.XFBML.Host.parseDomTree, 100);
								}
							});
					});
				}
			});
		},

		_testFeedDialog = function(key) {
			var serverName = _getServerName();
			// load feed data by key
			$.ajax({
				type: 'POST',
				url: _buildFBUrl(serverName + '/external_accounts/facebook_feed_templates/retrievebykey'),
				data: 'key=' + key,
				success: function(jsonData) {
					if (jsonData == '') {
						alert('Unabled to load data for template key "' + key + '"');
						return;
					}
					var data = (typeof (JSON) !== 'undefined' && typeof(JSON.parse) === 'function') ? JSON.parse(jsonData) : eval('(' + jsonData + ')');
					data = (data.FacebookFeedTemplate != null) ? data.FacebookFeedTemplate : data;
//var str = '';
//for (var key in data) {
//	str += key + ': ' + data[key] + '  |  ';
//}
//alert(str);
					options = {};
					options.prompt = data.default_prompt;
					options.userMessage = data.default_message;
					options.key = data.key;
					options.templateData = data.test_template_data;

					_feedDialog(options);
				}
			});
		},

		_feedDialog = function(options, defaultData) {
			var serverName = _getServerName();

			if (options.key != null) {
				// load feed data by key
				$.ajax({
					type: 'POST',
					url: _buildFBUrl(serverName + '/external_accounts/facebook_feed_templates/retrievebykey'),
					data: 'key=' + options.key,
					success: function(data) {
						_displayFeedDialog(options, data);
					}
				});
			} else {
				_displayFeedDialog(options, defaultData);
			}
		},

		_displayFeedDialog = function(options, defaultData) {
			var data = {};
			if (typeof(defaultData) === 'object') {
				// defaultData is an object
				data = defaultData;
			} else if (typeof(defaultData) === 'string') {
				// defaultData is a JSON string
				data = (typeof(JSON) !== 'undefined' && typeof(JSON.parse) === 'function') ? JSON.parse(defaultData) : eval('(' + defaultData + ')');
			}
			
			FB_RequireFeatures(["XFBML"], function()
			{
				if (!FB.Facebook.get_sessionWaitable().get_isReady()) {
					manuallogin(window.location);
				} else {
					FB.Facebook.get_sessionState().waitUntilReady(function()
					{
						// extract default data
						data = (data.FacebookFeedTemplate != null) ? data.FacebookFeedTemplate : data;
						var defaultPrompt    = (data.default_prompt != null)  ? data.default_prompt  : '',
							defaultMessage   = (data.default_message != null) ? data.default_message : '',
							templateId       = (data.value != null)           ? data.value           : '',
							baseTemplateData = (data.base_template_data != null && data.base_template_data != '') ? data.base_template_data : null;
							baseTemplateData = (baseTemplateData != null && typeof(JSON) !== 'undefined' && typeof(JSON.parse) === 'function') ? JSON.parse(baseTemplateData) : eval('(' + baseTemplateData + ')');
						
						// extract override options
						var prompt       = (options.prompt != null)       ? options.prompt       : defaultPrompt,
							userMessage  = (options.userMessage != null)  ? options.userMessage  : defaultMessage,
							templateId   = (options.templateId != null)   ? options.templateId   : templateId,
							bodyGeneral  = (options.bodyGeneral != null)  ? options.bodyGeneral  : null,
							targetIds    = (options.targetIds != null)    ? options.targetIds    : null,
							templateData = (options.templateData != null && options.templateData != '') ? options.templateData : null;
						
						if (templateData != null && typeof(templateData) === 'string') {
							// templateData is a JSON string
							templateData = (typeof(JSON) !== 'undefined' && typeof(JSON.parse) === 'function') ? JSON.parse(templateData) : eval('(' + templateData + ')');
						}
						
						_callback    = (options.callback != null)     ? function(){options.callback();} : function(){};
							
						// merge templateData and baseTemplateData
						for (var name in baseTemplateData) {
							if (name != 'images' && !(templateData.hasOwnProperty(name))) {
								templateData[name] = baseTemplateData[name];
							}
						}
						
						// merge image data from templateData and baseTemplateData
						if (templateData != null) {
							var i = (templateData.hasOwnProperty('images')) ? templateData['images'].length : 0;
							if (baseTemplateData != null && baseTemplateData.hasOwnProperty('images')) {
								for (var img in baseTemplateData['images']) {
									if (!templateData.hasOwnProperty('images')) {
										templateData['images'] = {};
									}
									templateData['images'][i++] = baseTemplateData['images'][img];
								}
							}
						}
						
						// generate tracking code parameters
						var trackingParams = _getTrackingParams('stream');
						templateData['trackingparams'] = trackingParams;
						
						// append tracking codes to image hrefs
						if (templateData != null && templateData.hasOwnProperty('images')) {
							for (var img in templateData['images']) {
								var imgData = templateData['images'][img];
								if (imgData.hasOwnProperty('href')) {
									imgData['href'] = _appendParams(imgData['href'], trackingParams);
									templateData['images'][img] = imgData;
								}
							}
						}

						// show feed dialog
						FB.Connect.showFeedDialog(templateId, templateData, targetIds, bodyGeneral, null, FB.RequireConnect.promptConnect, _feedDialogCallback, prompt, userMessage);
					});
				}
			});
		},
/*
		_feedDialog = function(options) {
			FB_RequireFeatures(["XFBML"], function()
			{
				if (!FB.Facebook.get_sessionWaitable().get_isReady()) {
					manuallogin(window.location);
				} else {
					FB.Facebook.get_sessionState().waitUntilReady(function()
					{
						var prompt       = (options.prompt != null)       ? options.prompt       : '',
							userMessage  = (options.userMessage != null)  ? options.userMessage  : '',
							templateId   = (options.templateId != null)   ? options.templateId   : null,
							templateData = (options.templateData != null) ? options.templateData : null,
							bodyGeneral  = (options.bodyGeneral != null)  ? options.bodyGeneral  : null,
							targetId     = (options.targetId != null)     ? options.targetId     : null;
							_callback     = (options.callback != null)     ? function(){options.callback();} : function(){},
							
							FB.Connect.showFeedDialog(templateId, templateData, targetId, bodyGeneral, null, FB.RequireConnect.promptConnect, _feedDialogCallback, prompt, userMessage);
					});
				}
			});
		},
*/
		_feedDialogCallback = function() {
			var tmp = _callback;
			_callback = null;

			if (typeof(tmp) == 'function') tmp();

			// TODO: figure out how to securely reward players for posting to facebook when we don't know if they actually posted
			//var url = '/external_accounts/facebook/processpermissionupdate';
			//$.post(url, {permission: permission}, tmp);
		},
		
		_streamPublish = function(message, attachment, links, message_prompt, target) {
			var message = message || '', attachment = attachment || {}, action_links = links || [], prompt = message_prompt || null, target = target || null;
			
			FB_RequireFeatures(["XFBML"], function() {
				if (!FB.Facebook.get_sessionWaitable().get_isReady()) {
					manuallogin(window.location);
				} else {
					FB.Facebook.get_sessionState().waitUntilReady(function() {
						if(target)
						{
							FB.Facebook.apiClient.friends_areFriends(FB.Facebook.apiClient.get_session().uid, target, function(result) {
								if(result[0].are_friends)
								{
									FB.Connect.streamPublish(message, attachment, action_links, target, prompt, _onStreamDialogClosed);
								}
								else
								{
									_onStreamDialogClosed();
								}	
							});
						}
						else
						{
							FB.Connect.streamPublish(message, attachment, action_links, target, prompt, _onStreamDialogClosed);
						}
					});
				}
			});
		},
		
		_onStreamDialogClosed = function(id, error) {
			CG.FacebookHelper.events.streamDialogClosed.fire();
		},

		_promptOfflineAccessPermission = function(callback) {
			_promptPermission('offline_access', callback);
		},

		_promptPublishStreamPermission = function(callback) {
			_promptPermission('publish_stream', callback);
		},

		_promptEmailPermission = function(callback) {
			_promptPermission('email', callback);
		},

		_promptPermission = function(permission, callback) {
			if (!FB.Facebook.get_sessionWaitable().get_isReady()) {
				manuallogin(window.location);
			} else {
				_callback = callback;
				FB_RequireFeatures(["XFBML"], function() {
					FB.Facebook.get_sessionState().waitUntilReady(function() {
						FB.Connect.showPermissionDialog(permission, _permissionCallback);
					});
				});
			}
		},
		
		_permissionCallback = function(permission) {
			var tmp = _callback;
			_callback = null;

			var url = _buildFBUrl('/external_accounts/facebook/processpermissionupdate');
			$.post(url, {permission: permission}, tmp);
		},
		
		_buildFBUrl = function(url) {
			var r = {};
			var q = (url.indexOf('?') > -1) ? url.substring(url.indexOf('?') + 1) : ''; // remove everything up to the ?
			q = q.replace(/\&$/, ''); // remove the trailing &
			jQuery.each(q.split('&'), function() {
				if (this.length > 0) {
					var splitted = this.split('=');
					var key = splitted[0];
					var val = (splitted.length > 1) ? splitted[1] : '';
					// convert floats
					if (/^[0-9.]+$/.test(val)) {
						val = parseFloat(val);
					}
					r[key] = val;
				}
			});
			
			var fbParams = _getFBQueryParameters();
			for (var key in fbParams) {
				if (r[key] == undefined) {
					r[key] = fbParams[key];
				}
			}
			
			q = (url.indexOf('?') > -1) ? url.substring(0, url.indexOf('?') + 1) : url + '?';
			for (var key in r) {
				q += '&' + key + '=' + r[key];
			}
			
			return q;
		},
		
		_getFBQueryParameters = function() {
			var r = {};
			var s = window.location.toString();
			var q = s.substring(s.indexOf('?') + 1); // remove everything up to the ?
			q = q.replace(/\&$/, ''); // remove the trailing &
			jQuery.each(q.split('&'), function() {
				var splitted = this.split('=');
				var key = splitted[0];
				var val = splitted[1];
				// convert floats
				if (/^[0-9.]+$/.test(val)) {
					val = parseFloat(val);
				}
				// ignore parameters that don't start with fb_
				if (key.indexOf('fb_') == 0) {
					r[key] = val;
				}
			});
			
			return r;
		},

		_getServerName = function() {
			var serverName = location.toString().replace('http://', '');
			serverName = (serverName.indexOf('/') > -1) ? serverName.substring(0, serverName.indexOf('/')) : serverName;
			serverName = (serverName.indexOf('?') > -1) ? serverName.substring(0, serverName.indexOf('?')) : serverName;
			serverName = 'http://' + serverName;
			return serverName;
		},
		
		_appendParams = function(url, params) {
			return url + ((url.indexOf('?') > -1) ? '&' : '?') + params;
		},
		
		_getTrackingParams = function(type) {
			return 'posterid=' + FB.Facebook.apiClient.get_session().uid + '&posttype=' + type;
		};

/***** END LOCAL FUNCTION DEFINITION *****/

/***** BEGIN LOCAL CLASS DEFINITION *****/
/***** END LOCAL CLASS DEFINITION *****/
		
/***** BEGIN GLOBAL CG.FACEBOOKHELPER OBJECT DEFINITION *****/
		
		//CG.Facebook object
		CG.FacebookHelper = {
			inviteFriends: _inviteFriends,
			inviteFriendsInline: _inviteFriendsInline,
			testFeedDialog : _testFeedDialog,
			feedDialog : _feedDialog,
			promptOfflineAccessPermission: _promptOfflineAccessPermission,
			promptPublishStreamPermission: _promptPublishStreamPermission,
			promptEmailPermission: _promptEmailPermission,
			streamPublish: _streamPublish,
			buildFBUrl: _buildFBUrl,
			getServerName: _getServerName,
			
			events: {
				streamDialogClosed: new CG.Event()
			}
		};

/***** END GLOBAL CG.FACEBOOKHELPER OBJECT DEFINITION *****/

})(jQuery);
