/**
 * Facebook feed publishing API
 */
FbPublish = {
	/** 
	 * Publishes a story to the profile of user identified by the target.
	 * If target is null, it publishes to the current user's profile (mini-feed or Wall).
	 * For more info on args, visit http://wiki.developers.facebook.com/index.php/Facebook.streamPublishg
	 * @param data (Object) (See createAttachment func for args)
	 * @param target (Object) => {id,name}
	 * @param auto_publish (Boolean) => true | false ( if permission for auto publish is granted by user this will publish without a preview modal )
	 * @param beforePost (function) => called before publishing feed
	 * @param callback (function) => called after streamPublish
	 */
	publishFeed: function (data, target, auto_publish, beforePost, callback) {
		if( FbPublish.isWithinAllowedPublishCount() ) {//Be sure to set the maxPostCount var in the config
			try {
				//process any pre post functions
				if (typeof beforePost == "function")
					beforePost(data, target);
				var postData = FbPublish.createAttachment(data);
				FB.Connect.streamPublish('', postData.attachment, postData.action_links, ( (target)?target.id:null ), data.modal_message,
					function(post_id, exception) {
						if (exception) FwpConnect.logError("Facebook", "FB.Connect.streamPublish:"+data.action, exception.message || exception);
						else if (post_id != 'null') FbPublish.updatePublishCount();
						else FwpConnect.logError("Facebook", "FB.Connect.streamPublish:"+data.action, "cancel publish");
						
						if (typeof callback == "function")
							callback(post_id, target, null);
					}, auto_publish);
			} catch (exception) {
				FwpConnect.logError("Facebook", "publishFeed:"+data.action, exception.message || exception);
			}
		} else alert("Sorry, you have exceeded the daily Facebook feed posting limits.");
	},
	/**
	 * Helper function to create appropriate media data object
	 */
	createMediaObj: function(mData) {
		if (mData.type=='image') {
			return {
				'type': mData.type,
				'src':	mData.imgSrc.replace(" ",""),
				'href':	mData.href
			};
		} else {
			return {
				'type':	  		  mData.type,
				'swfsrc': 		  mData.swfSrc,
				'imgsrc': 		  mData.imgSrc,
				'width':  		  mData.width,
				'height': 		  mData.height,
				'expanded_width': mData.expanded_width,
				'expanded_height': mData.expanded_height
			};
		}
	},
	/**
	 * Generates the attachment data - populates all template tokens with appropriate data
	 * For more info - http://wiki.developers.facebook.com/index.php/Attachment_(Streams)
	 */
	createAttachment: function(_data) {
		//Facebook attachment data
		var data = {
			"attachment": {
				"name": _data.name,
				"href": _data.href,
				"subject": _data.subject,
				"caption": _data.caption,
				"description": _data.description,
				"properties": _data.properties
			}
		}
		//insert action links data
		if (_data.action_links) {
			data.action_links = [];
			for (var link in _data.action_links) {
				if (_data.action_links.hasOwnProperty(link))
					data.action_links.push({"text": _data.action_links[link].text, "href": _data.action_links[link].href});	
			}
		}
		//insert media data
		if (_data.media) {
			data.attachment.media = [];
			for (var media in _data.media) {
				if (_data.media.hasOwnProperty(media))
					data.attachment.media.push( FbPublish.createMediaObj( _data.media[media] ) );
			}
		}
		return data;
	},
	
	/**
	 * Retrieves friends list for the current logged-in user 
	 * http://wiki.developers.facebook.com/index.php/JS_API_M_FB.ApiClient.Friends_get
	 */  
	getFriends: function(callback) {
		try {
			FB.ensureInit(function(exception) {
				if (exception)
					FwpConnect.logError("Facebook", "FB.ensureInit", exception.message || exception);
					
				try {
					FB.Facebook.apiClient.friends_get(null, function(friendsList, exception) {
						if (exception)
							FwpConnect.logError("Facebook", "FB.friendsGet", exception.message || exception);

						callback(friendsList);
					});
				} catch (exception) {
					FwpConnect.logError("Facebook", "friendsGet", exception.message || exception);
				}
			});
		} catch (exception) {
			FwpConnect.logError("Facebook", "ensureInit", exception.message || exception);
		}
	},
	
	/**
	 * Gets information of friends in the given list for the fields as asked for in 
	 * the comma separated list. For info: http://wiki.developers.facebook.com/index.php/Users.getInfo
	 * To be cautious it will retrieve user information 
	 */
	getInfo: function(friendsList, fields, callback) {
		try {
			(function getFriends(friendsInfo, beg, step) {
				var end = ((beg+step)<friendsList.length?(beg+step):friendsList.length);
				var newfriendsList = friendsList.slice(beg,end);
				FB.Facebook.apiClient.users_getInfo(newfriendsList, fields, function(newfriendsInfo, exception) {
					if (exception) FwpConnect.logError("Facebook", "FB.getInfo", exception.message || exception);
					else friendsInfo = friendsInfo.concat(newfriendsInfo);
					if (end == friendsList.length) callback(friendsInfo);
					else getFriends(friendsInfo,(beg+step), step);
				});
			})([], 0, 25);
		} catch (exception) {
			FwpConnect.logError("Facebook", "getInfo", exception.message || exception);
		}
	},
	
	/**
	 * Checks if the user is still within the daily limits allowed for publishing.
	 * This parameter is set in the product config. If 0 then no limit exist.
	 */
	isWithinAllowedPublishCount: function() {
		if (FwpConnect.config.maxPostCount) {
			var publishCountCookie = getCookie("fb_pub_counter");		
			if (publishCountCookie && publishCountCookie.length > 0 ) {
				var cookieData = publishCountCookie.parseJSON();
				return cookieData.count < FwpConnect.config.maxPostCount;
			}
		}
		return true;
	},
	
	/**
	 * Update the publish count and store it in a cookie; if the user clears the 
	 * cookie we lose the count.
	 */
	updatePublishCount: function() {
		if (FwpConnect.config.maxPostCount) {
			var publishCountCookie = getCookie("fb_pub_counter");
			var dataObj;
			if (publishCountCookie && publishCountCookie.length > 0) {
				var cookieData = publishCountCookie.parseJSON();
				dataObj = {count: (cookieData.count) + 1};
			} else dataObj = {count: 1};
		}
	},
	
	/**
	 * Sends notification to friends 
	 * http://wiki.developers.facebook.com/index.php/JS_API_M_FB.ApiClient.Notifications_send
	 */
	notifyFriends: function(arrFriendIds, message, callback) {
		try {
			FB.Facebook.apiClient.notifications_send (arrFriendIds, message, function(result, exception) {
				// result param will have the comma separated list of recipients
				if (exception)
					FwpConnect.logError("Facebook", "FB.notify", exception.message || exception);

				callback();
			});
		} catch (exception) {
			FwpConnect.logError("Facebook", "notify", exception.message || exception);
		}
	},
	
	/**
	 * Invite friends dialog generator
	 */
	inviteFriends: function (type, actionUrl, content, apiKey, labelText, actionText, inviteText) {
		var box_fbml = 
			"<fb:fbml>" +
			"<fb:request-form method=\"post\" type=\""+type+"\" action=\""+actionUrl+"\" invite=\"true\" " +
			"content=\""+content+" \<fb:req-choice url='http://www.facebook.com/add.php?api_key="+apiKey+"' label='"+labelText+"'/\>\">" +
			"<fb:multi-friend-selector showborder=\"false\" actiontext=\""+actionText+"\" cols=\"4\">" +
			"</fb:multi-friend-selector>" +
			"</fb:request-form>" +
			"</fb:fbml>";
		var inviteDialog = new FB.UI.FBMLPopupDialog (inviteText, box_fbml);
		inviteDialog.set_placement(FB.UI.PopupPlacement.center);
		inviteDialog.setContentWidth(650);
		inviteDialog.setContentHeight(600);
		inviteDialog.show();
	},
	
	/**
	 * Send email given friend ID, email subject and body. The body can be html or fbml. Atleast one param can not be null.
	 * return results to callback
	 */
	sendEmail: function (arrFriendIds, mail_subject, html_body, fbml_body, callback) {
		try {
		 	FbPublish.checkPermission( "email", false, function(hasPermission) {
				if (hasPermission != 0) {
					try {
						FB.Facebook.apiClient.notifications_sendEmail(arrFriendIds, mail_subject, html_body, fbml_body, function(result, exception) {
							// result param will have the comma separated list of recipients
							if (exception)
								FwpConnect.logError("Facebook", "FB.notifications_sendEmail", exception.message || exception);
							callback(result);
						});
					} catch (exception) {
						FwpConnect.logError("Facebook", "notifications_sendEmail", exception.message || exception);
					}
				}
			});
		} catch (exception) {
			FwpConnect.logError("Facebook", "checkPermission", exception.message || exception);
		}
	},
	
	/**
	 * Check FB App permission. Bypass show Permissions dialog if needed 
	 * In case you only want to check the status of the permission
	 * http://wiki.developers.facebook.com/index.php/JS_API_M_FB.ApiClient.Users_hasAppPermission
	 */
	checkPermission: function (permission, showPermDialog, callback) {
		try {
			FB.Facebook.apiClient.users_hasAppPermission(permission,
				function(result) {
					if (showPermDialog && result == 0) { //prompt offline permission
						try {
			            	FB.Connect.showPermissionDialog(permission, function(result) { 
			            		result = (result==permission||result?true:false);
			            		callback(result);
			            	}); //render the permission dialog
			            } catch (exception) {
							FwpConnect.logError("Facebook", "FB.Connect.showPermissionDialog", exception.message || exception);
						}
			        } else callback(result); //permission already granted or we have bypassed dialog.
				}
			);
		} catch (exception) {
			FwpConnect.logError("Facebook", "FB.Facebook.apiClient.users_hasAppPermission", exception.message || exception);
		}
	}
};