/*
 * -----------------------------------------------------------------
 * Copyright (c) 2009 Fluid, Inc. All Right Reserved.
 * This software is the proprietary information of Fluid, Inc.
 * Use is subject to strict licensing terms.
 * -----------------------------------------------------------------
 *
 * CVS Information:
 * $Id: fluid.facebook-pdp.js.php,v 1.77 2009/12/23 15:24:56 akerr Exp $
 * $Author: akerr $
 * $Date: 2009/12/23 15:24:56 $
 */

var FluidSocialPDP = function () {};
FluidSocialPDP.userInitiatedLogin = false;

FluidSocialPDP.prototype = {
	
	// Configuration parameters:
	divId: "fluid-social-facebook",
	favoritesDivId: null,
	productId: null,
	productName: null,
	thumbnailUrl: null,
	pdpUrl: null,
	mainImageUrl: null,
	
	visibleTab: null,
	alreadyConnected: false,
	sendInviteDialog: null,
	statusDialog: null,
	facebookUser: null,
	friendIds: null,
	
	singleProductMode: false,
	standaloneFavoritesOnly: false,
	
	favoritesScrollerSize: 2,
	standaloneFavoritesScrollerSize: 2,
	
	connector: null,
	
	init: function() {
		var fluidSocial = this;
		this.connector = new FluidSocialPDPConnector();

		jQuery.fn.center = function() {
			var w = $(window);
			this.css("position","fixed");
			fluidSocial.debug([w.scrollTop(), w.scrollLeft()]);
			this.css("top",(w.height()-this.height())/2 + "px");
			this.css("left",(w.width()-this.width())/2 + "px");
			return this;
		};			
		
		// Add the Fluid Social for Facebook content to the specified div.
		if (this.divId != null)
			this.createFacebookContent();
		if (this.favoritesDivId != null)
			this.createStandaloneFavoritesContent();

		$(".fluid-fbLoggedIn").hide();
		$(".fluid-fbNotLoggedIn").show();
		
		// Initialize the client-side Facebook API.
		FB_RequireFeatures(["XFBML", "Api", "Connect"], function() {
			//FB.FBDebug.isEnabled = true;
			//FB.FBDebug.logLevel = 4;
			fluidSocial.initializeFacebook();
		});

		$("a.fluid-fbLogin").click(function(event) {
			event.preventDefault();
			fluidSocial.closeDialogs();
			FluidSocialPDP.userInitiatedLogin = true;
			FB.Connect.requireSession();
		});
		
		$("a.fluid-fbLogout").click(function(event) {
			event.preventDefault();
			fluidSocial.closeDialogs();

			// Show the Share Button.
			$('#fluid-fbShareMessage').hide();
			$('#fluid-fbShareProduct').show();

			FB.Connect.logout();
		});
		
		$("a.fluid-fbAddProduct").click(function(event) {
			event.preventDefault();
			fluidSocial.closeDialogs();
			
			FB.Connect.requireSession(function() {
				// Add the product.
				fluidSocial.addProduct();
			});
		});
		
		$("a.fluid-fbcloselink, .fluid-fbclosebutton").click(function(event) {
			event.preventDefault();
			fluidSocial.closeDialogs();
		});
		
		$("#fluid-feedback_form_send").click(function(event) {
			event.preventDefault();
			fluidSocial.sendFeedback();
		});
		
		// Some links appear in dynamically generated content, so we need
		// to reattach them sometimes.
		this.reattachEventHandlers();
		
		if (location.search.indexOf('fluid-showFBComments=1') != -1)
			this.tabSwap('fluid-fbTab2Content');
			
		if (!$.browser.msie && !this.standaloneFavoritesOnly) $("#fluid-firstVisitPopupWrapper").show();	},
	
	initializeFacebook: function() {
		var fluidSocial = this;
		
		FB.init("e3ff5bd3940ef42520276d10b087700d",
			"xd_receiver.html",
			{
				"ifUserConnected": function(userId) {
					fluidSocial.debug("Facebook User Connected: " + userId +
						", User Initiated Login: " + FluidSocialPDP.userInitiatedLogin);
					if (userId == null)
					{
						// Something's wrong with the user's session.
						FB.Connect.logout();
						return;
					}
						
					if (!fluidSocial.alreadyConnected)
					{
						$(".fluid-fbLoggedIn").show();
						$(".fluid-fbNotLoggedIn").hide();
						
						$("#fluid-fbProfilePic").html('<fb:profile-pic uid="' + userId + '" facebook-logo="true" size="square"></fb:profile-pic>');
						$(".fluid-fbUserName").html('<fb:name uid="' + userId + '" firstnameonly="true" useyou="false" linked="false"></fb:name>');
						fluidSocial.parseDomElement('fluid-fbShareContent');

						// Get some information about the user for later use.
						// Use a sequencer for performance reasons.

						var sequencer = new FB.BatchSequencer();
						var pendingUserInfo = FB.Facebook.apiClient.users_getInfo([userId], ['timezone'], sequencer); 
						var pendingFriends = FB.Facebook.apiClient.fql_query(
							"SELECT uid FROM user WHERE is_app_user=1 AND uid IN (SELECT uid2 FROM friend WHERE uid1 = " + userId + ")", sequencer); 

						sequencer.execute(function(result) {
							if (pendingUserInfo.result == null)
							{
								// Something's wrong with the user's session.
								FB.Connect.logout();
								return;
							}
						
							fluidSocial.debug(["User Info", pendingUserInfo.result[0]]);
							fluidSocial.debug(["Friends that use app", pendingFriends.result]);
							
							fluidSocial.facebookUser = pendingUserInfo.result[0];
							fluidSocial.friendIds = [];
							
							for (var i in pendingFriends.result)
							{
								fluidSocial.friendIds.push(pendingFriends.result[i].uid);
							}

							fluidSocial.postConnect();
						});						
					}
					
					fluidSocial.alreadyConnected = true;
				},
					
				"ifUserNotConnected": function() {
					fluidSocial.debug("Facebook User Disconnected");
						
					$(".fluid-fbLoggedIn").hide();
					$(".fluid-fbNotLoggedIn").show();
						
					fluidSocial.alreadyConnected = false;
					fluidSocial.facebookUser = null;
					fluidSocial.friendIds = null;
				}
			}
		);
	},
	
	postConnect: function() {
		var fluidSocial = this;
		
		fluidSocial.getNewestReview();
		fluidSocial.getFriendReviews();

		if (!fluidSocial.singleProductMode)
			fluidSocial.getFriendFavorites();							

		if (FluidSocialPDP.userInitiatedLogin)
		{
			// Ask the user if we can update their status area on Facebook.
			FB.Facebook.apiClient.users_hasAppPermission('status_update', function(result) {
				fluidSocial.debug("Permission to update status: " + result);
				if (result == 0)
				{
					FB.Connect.showPermissionDialog('status_update', function(result) {
						fluidSocial.debug("Permission granted on prompt: " + result);
						if (result == 'status_update')
							fluidSocial.updateUserStatus();
						if (!fluidSocial.standaloneFavoritesOnly)
							fluidSocial.addProduct();									
					});
				}
				else
				{
					fluidSocial.updateUserStatus();
					if (!fluidSocial.standaloneFavoritesOnly)
						fluidSocial.addProduct();
				}
			});
		}
	},
	
	createFacebookContent: function() {
		var fluidSocial = this;
		var html = '';
		
		if (!this.standaloneFavoritesOnly)
		{		
			html += '<div id="fluid-fbTab1Content">\n';
			html += '	<div style="position:relative;"><div class="fluid-fbCommentCount fluid-fbCommentCountDefault fluid-fbLoggedIn"></div></div>\n';
			if (!this.singleProductMode)
			{
				html += '	<div style="position:relative;"><div class="fluid-fbFavoritesCount fluid-fbFavoritesCountDefault fluid-fbLoggedIn"></div></div>\n';
			}
			html += '	<div id="fluid-fbTab1Wrapper">\n';
			html += '		<div id="fluid-fbShareTabActive">\n';
			html += '			<ul>\n';
			html += '				<li id="fluid-fbTab1Share"><a href="#" class="fluid-fbLogin"></a></li>\n';
			html += '				<li id="fluid-fbTab1Friends"><a href="#"></a></li>\n';
			if (!this.singleProductMode)
			{
				html += '				<li id="fluid-fbTab1Favorites"><a href="#"></a></li>\n';
			}
			html += '			</ul>\n';
			html += '		</div>\n';
			html += '	</div>\n';
			html += '	<div class="fluid-fbContentTop"></div>\n';
			html += '	<div id="fluid-fbShareContentWrapper">\n';
			html += '		<div id="fluid-fbShareContent">\n';
			html += '			<div class="fluid-fbLoggedIn" style="display: none;">\n';
			html += '				<div id="fluid-fbProfilePic"></div>\n';		
			html += '				<div id="fluid-fbWelcomeText">Welcome,<br/><span class="fluid-fbUserName"></span>!</div><br/>\n';		
			html += '				<div id="fluid-fbShareMessage">You shared this product successfully!</div>\n';		
			html += '				<div id="fluid-fbShareProduct">\n';
			html += '					<a class="fluid-fbAddProduct" href="#"></a>\n';
			html += '				</div>\n';
			html += '			</div>\n';
			html += '			<div class="fluid-fbNotLoggedIn" style="display: none;">\n';
			html += '				<div class="fluid-fbConnectText">Share this product with<br/>your Facebook friends!</div>\n';
			html += '				<div class="fluid-fbConnectButton"><fb:login-button onlogin="FluidSocialPDP.userInitiatedLogin = true;" size="medium" background="dark" length="long"></fb:login-button></div>\n';
			html += '			</div>\n';
			html += '			<div style="clear: both;"/>\n';		
			html += '		</div>\n';
			html += '	</div>\n';
			html += '	<div class="fluid-fbTellMeHow">\n';
			html += '		<a href="#" class="fluid-fbShowInstructions">Tell me how this works</a>&nbsp;|&nbsp;<a href="#" class="fluid-fbSendFeedback">Tell us what you think</a><span class="fluid-fbLoggedIn">&nbsp;|&nbsp;<a class="fluid-fbLogout" href="#">Logout of Facebook</a></span>\n';
			html += '	</div>\n';
			html += '</div>\n';

			html += '<div id="fluid-fbTab2Content" style="display:none;">\n';
			html += '	<div style="position:relative;"><div class="fluid-fbCommentCount fluid-fbCommentCountActive fluid-fbLoggedIn"></div></div>\n';
			if (!this.singleProductMode)
			{
				html += '	<div style="position:relative;"><div class="fluid-fbFavoritesCount fluid-fbFavoritesCountDefault fluid-fbLoggedIn"></div></div>\n';
			}
			html += '	<div id="fluid-fbTab2Wrapper">\n';
			html += '		<div id="fluid-fbFriendsTabActive">\n';
			html += '			<ul>\n';
			html += '				<li id="fluid-fbTab2Share"><a href="#" class="fluid-fbLogin"></a></li>\n';
			html += '				<li id="fluid-fbTab2Friends"><a href="#"></a></li>\n';
			if (!this.singleProductMode)
			{
				html += '				<li id="fluid-fbTab2Favorites"><a href="#"></a></li>\n';
			}			
			html += '			</ul>\n';
			html += '		</div>\n';
			html += '	</div>\n';
			html += '	<div class="fluid-fbContentTop"></div>\n';
			html += '	<div id="fluid-fbFriendsContentWrapper">\n';
			html += '		<div id="fluid-fbFriendsContentNotLoggedIn" class="fluid-fbNotLoggedIn">\n';
			html += '			<div class="fluid-fbConnectText">See what your Friends are<br/>saying about this product!</div>\n';
			html += '			<div class="fluid-fbConnectButton"><fb:login-button onlogin="FluidSocialPDP.userInitiatedLogin = true;" size="medium" background="dark" length="long"></fb:login-button></div>\n';
			html += '			<br style="clear: both;"/>\n';
			html += '		</div>';
			html += '		<div id="fluid-fbFriendsContent" class="fluid-fbLoggedIn" style="display: none;"></div>\n';
			html += '	</div>\n';
			html += '	<div class="fluid-fbTellMeHow fluid-fbNotLoggedIn">\n';
			html += '		<a href="#" class="fluid-fbShowInstructions">Tell me how this works</a>&nbsp;|&nbsp;<a href="#" class="fluid-fbSendFeedback">Tell us what you think</a>\n';
			html += '	</div>\n';
			html += '</div>\n';

			if (!this.singleProductMode)
			{
				html += '<div id="fluid-fbTab3Content" style="display:none;">\n';
				html += '	<div style="position:relative;"><div class="fluid-fbCommentCount fluid-fbCommentCountDefault fluid-fbLoggedIn"></div></div>\n';
				html += '	<div style="position:relative;"><div class="fluid-fbFavoritesCount fluid-fbFavoritesCountActive fluid-fbLoggedIn"></div></div>\n';
				html += '	<div id="fluid-fbTab3Wrapper">\n';
				html += '		<div id="fluid-fbFavoritesTabActive">\n';
				html += '			<ul>';
				html += '				<li id="fluid-fbTab3Share"><a href="#" class="fluid-fbLogin"></a></li>\n';
				html += '				<li id="fluid-fbTab3Friends"><a href="#"></a></li>\n';
				html += '				<li id="fluid-fbTab3Favorites"><a href="#"></a></li>\n';
				html += '			</ul>\n';
				html += '		</div>\n';
				html += '	</div>\n';
				html += '	<div class="fluid-fbContentTop"></div>\n';
				html += '	<div id="fluid-fbFavoritesContentWrapper">\n';
				html += '		<div id="fluid-fbFavoritesContentNotLoggedIn" class="fluid-fbNotLoggedIn">\n';
				html += '			<div class="fluid-fbConnectText">See what other JanSport<br/>products your Friends like!</div>\n';
				html += '			<div class="fluid-fbConnectButton"><fb:login-button onlogin="FluidSocialPDP.userInitiatedLogin = true;" size="medium" background="dark" length="long"></fb:login-button></div>\n';
				html += '			<br style="clear: both;"/>\n';
				html += '		</div>\n';
				html += '		<div id="fluid-fbFavoritesContent" class="fluid-fbLoggedIn" style="display: none;"></div>\n';
				html += '	</div>\n';
				html += '	<div class="fluid-fbTellMeHow fluid-fbNotLoggedIn">\n';
				html += '		<a href="#" class="fluid-fbShowInstructions">Tell me how this works</a>&nbsp;|&nbsp;<a href="#" class="fluid-fbSendFeedback">Tell us what you think</a>\n';
				html += '	</div>\n';
				html += '</div>\n';
			}
		
			html += '<div id="fluid-fbCommentBubbleWrapper" class="fluid-fbLoggedIn" style="display: none;"></div>\n';
			html += '<div id="fluid-fbContentBottom"></div>\n';
		}

		html += '<div id="fluid-howitworks">\n';
		html += '	<div id="fluid-howitworks_top"></div>\n';
		html += '	<div id="fluid-howitworks_mid">\n';
		html += '		<div id="fluid-howitworks_close">\n';
		html += '			<a href="#" class="fluid-fbcloselink">Close</a> <a href="#" class="fluid-fbclosebutton"></a>\n';
		html += '		</div>\n';
		html += '		<div id="fluid-howitworks_main_img"></div>\n';
		html += '		<table>\n';
		html += '			<tr>\n';
		html += '				<td id="fluid-hiw_td_left">Click the <b>&#39;Connect with Facebook&#39;</a></b> button to add the Application. <br/><br/>Once added, you can share as many products as you&#39;d like!</td>\n';
		html += '				<td id="fluid-hiw_td_mid">Without leaving this site, you can <b>view the ratings and comments from your friends</b> on your products (as long as you are logged into Facebook). <br/><br/>You can even see the products your friends added to their own lists!</td>\n';
		html += '				<td id="fluid-hiw_td_right">To get the full benefit of our Social Shopping feature, don&#39;t forget to <b>Invite Your Friends</b> to rate, comment and create their own list of favorites after you add your application!</td>\n';
		html += '			</tr>\n';
		html += '		</table>\n';
		html += '	</div>';
		html += '	<div id="fluid-howitworks_bot"></div>\n';
		html += '</div>\n';

		html += '<div id="fluid-feedback">\n';
		html += '	<div id="fluid-feedback_top"></div>\n';
		html += '	<div id="fluid-feedback_mid">\n';
		html += '		<div id="fluid-feedback_close">\n';
		html += '			<a href="#" class="fluid-fbcloselink">Close</a> <a href="#" class="fluid-fbclosebutton"></a>\n';
		html += '		</div>\n';
		html += '		<div id="fluid-feedback_content">\n';
		html += '			<h1>TELL US WHAT YOU THINK!</h1>\n';
		html += '			<p>Your feedback is important to us, so let us know what you think about the Facebook integration features on the JanSport product detail page!</p>\n';
		html += '			<p>You can also report any problems or bugs you find here.</p>\n';
		html += '			<form id="fluid-feedback_form" method="post" action="#">\n';
		html += '				<div>All fields are required unless indicated.</div>\n';
		html += '				<div class="fluid-feedback_form_row"><label for="fluid-feedback_form_to">To</label><div class="fluid-feedback_form_value">JanSport Dev Team</div></div>\n';
		html += '				<div class="fluid-feedback_form_row"><label for="fluid-feedback_form_reason">Reason</label><div class="fluid-feedback_form_value"><select id="fluid-feedback_form_reason"><option value="">Please choose a topic</option><option value="suggestion">Make a suggestion</option><option value="bug">Report a bug</option><option value="question">Ask a question</option><option value="complaint">File a complaint</option></select></div></div>\n';
		html += '				<div class="fluid-feedback_form_row"><label for="fluid-feedback_form_email">Your Email</label><div class="fluid-feedback_form_value"><input id="fluid-feedback_form_email" /> (optional)<br/>If you want a reply, please enter your email here.  We will not disclose your information to anyone.</div></div>\n';
		html += '				<div class="fluid-feedback_form_row"><label for="fluid-feedback_form_subject">Subject</label><div class="fluid-feedback_form_value"><input id="fluid-feedback_form_subject" /> (optional)</div></div>\n';
		html += '				<div class="fluid-feedback_form_row"><label for="fluid-feedback_form_message">Message</label><div class="fluid-feedback_form_value"><textarea id="fluid-feedback_form_message"></textarea></div></div>\n';
		html += '				<div class="fluid-feedback_form_row"><div class="fluid-feedback_form_value"><input id="fluid-feedback_form_send" class="fluid-fbbutton" type="button" value="Send" />&nbsp;<input class="fluid-fbbutton fluid-fbclosebutton" type="button" value="Cancel" /></div></div>\n';
		html += '				<div style="clear: both;"></div>\n';
		html += '			</form>\n';
		html += '		</div>\n';
		html += '	</div>';
		html += '	<div id="fluid-feedback_bot"></div>\n';
		html += '</div>\n';

		html += '<div id="fluid-firstVisitPopupWrapper">\n';
		html += '	<div id="fluid-firstVisitPopupTop"><a id="fluid-firstVisitPopupClose" class="fluid-fbclosebutton" href="#"></a></div>\n';
		html += '	<div id="fluid-firstVisitPopupMiddle">\n';
		html += '		<div id="fluid-firstVisitPopupHead"></div>\n';
		html += '		<div id="fluid-firstVisitPopupText"><b>Share, Rate</b> and <b>Comment</b> on JanSport products with your Facebook friends <i>while you shop!</i></div>\n';
		html += '		<a class="fluid-fbLogin" href="#"><div id="fluid-firstVisitPopupButton"></div></a>\n';
		html += '	</div>\n';
		html += '	<div id="fluid-firstVisitPopupBottom"></div>\n';
		html += '</div>\n';
		
		$('#' + this.divId).html(html);
	
		$('#fluid-fbTab1Share > a').click(function(event) {
			event.preventDefault();
		});
		$('#fluid-fbTab1Friends > a').click(function(event) {
			event.preventDefault();
			fluidSocial.tabSwap('fluid-fbTab2Content');
		});
		$('#fluid-fbTab1Favorites > a').click(function(event) {
			event.preventDefault();
			fluidSocial.tabSwap('fluid-fbTab3Content');
		});
		$('#fluid-fbTab2Share > a').click(function(event) {
			event.preventDefault();
			fluidSocial.tabSwap('fluid-fbTab1Content');
		});
		$('#fluid-fbTab2Friends > a').click(function(event) {
			event.preventDefault();
		});
		$('#fluid-fbTab2Favorites > a').click(function(event) {
			event.preventDefault();
			fluidSocial.tabSwap('fluid-fbTab3Content');
		});		
		$('#fluid-fbTab3Share > a').click(function(event) {
			event.preventDefault();
			fluidSocial.tabSwap('fluid-fbTab1Content');
		});
		$('#fluid-fbTab3Friends > a').click(function(event) {
			event.preventDefault();
			fluidSocial.tabSwap('fluid-fbTab2Content');
		});
		$('#fluid-fbTab3Favorites > a').click(function(event) {
			event.preventDefault();
		});		
	},
	
	createStandaloneFavoritesContent: function() {
		var fluidSocial = this;
		var html = '';
		
		html += '<div id="fluid-fbStandaloneFavoritesContentWrapper">\n';
		html += '	<div id="fluid-fbStandaloneFavoritesContentNotLoggedIn" class="fluid-fbNotLoggedIn">\n';
		html += '		<div class="fluid-fbConnectText">See what other JanSport<br/>products your Friends like!</div>\n';
		html += '		<div class="fluid-fbConnectButton"><fb:login-button onlogin="FluidSocialPDP.userInitiatedLogin = true;" size="medium" background="dark" length="long"></fb:login-button></div>\n';
		html += '		<br style="clear: both;"/>\n';
		html += '	</div>\n';
		html += '	<div id="fluid-fbStandaloneFavoritesContent" class="fluid-fbLoggedIn" style="display: none;"></div>\n';
		html += '</div>\n';
		html += '<div class="fluid-fbTellMeHow fluid-fbNotLoggedIn">\n';
		html += '	<a href="#" class="fluid-fbShowInstructions">Tell me how this works</a>&nbsp;|&nbsp;<a href="#" class="fluid-fbSendFeedback">Tell us what you think</a>\n';
		html += '</div>\n';
			
		$('#' + this.favoritesDivId).html(html);		
	},
	
	reattachEventHandlers: function() {
		var fluidSocial = this;
		
		$("a.fluid-fbShowInstructions").unbind("click").click(function(event) {
			event.preventDefault();
			fluidSocial.closeDialogs();
			$('#fluid-howitworks').center().show();
		});

		$("a.fluid-fbSendFeedback").unbind("click").click(function(event) {
			event.preventDefault();
			fluidSocial.closeDialogs();
			$('#fluid-feedback *').removeClass("fluid-feedback_form_value_error fluid-feedback_form_label_error");
			$('#fluid-feedback_form')[0].reset();
			$('#fluid-feedback').center().show();
		});

		$("a.fluid-fbInviteFriends").unbind("click").click(function(event) {
			event.preventDefault();
			fluidSocial.closeDialogs();
			fluidSocial.showInviteDialog();
		});
	},
	
	tabSwap: function(id) {
		var tabToSwapWith = $('#' + id);
		if (!this.visibleTab)
		{   
			this.visibleTab = $('#fluid-fbTab1Content');
		}
		this.visibleTab.hide();
		tabToSwapWith.show();
		this.visibleTab = tabToSwapWith;
		
		// Track events in GA.
		if (this.analyticsPresent())
		{
			if (id == 'fluid-fbTab2Content')
			{
				pageTracker._trackEvent("PDP Events", "Friend Comments Opened", this.productId);
			}
			else if (id == 'fluid-fbTab3Content')
			{
				pageTracker._trackEvent("PDP Events", "Friend Favorites Opened", this.productId);
			}
		}
	},
	
	addProduct: function() {
		var fluidSocial = this;
		fluidSocial.debug("addProduct()");
		this.connector.addProduct(
			this.facebookUser.uid, this.productId, this.productName, this.pdpUrl, this.thumbnailUrl, this.mainImageUrl, function(response) {
			if (!fluidSocial.validateResponse(response))
				return;

			if (fluidSocial.analyticsPresent())
			{
				// Inform GA that the product was added.
				pageTracker._trackEvent("PDP Events", "Add Product", fluidSocial.productId);
			}

			// Remove the Share Button.
			$('#fluid-fbShareMessage').show();
			$('#fluid-fbShareProduct').hide();
			
			// Allow the user to post to their FB feed.
			var attachment = {
				'name': fluidSocial.productName + ' on www.jansport.com',
				'href': fluidSocial.pdpUrl,
				'caption': '{*actor*} just added \'' + fluidSocial.productName + '\' as a favorite product.',
				'media': [{'type': 'image', 'src': fluidSocial.thumbnailUrl.replace(/%20/, ' '), 'href': fluidSocial.pdpUrl}]
			};
			
			FB.Connect.streamPublish('', attachment, null, null, 'What do you think about ' + fluidSocial.productName + '?');
		});
	},
	
	updateUserStatus: function() {
		var fluidSocial = this;
		FB.Facebook.apiClient.users_setStatus('is currently shopping on www.jansport.com.  Join me: ' + fluidSocial.pdpUrl, false, true, function() {
			fluidSocial.debug("Status Updated");
		});
	},
	
	showInviteDialog: function() {
		var fluidSocial = this;

		var addProductUrl = 'http://apps.facebook.com/jansportfaves/' + 
			'?productId=' + encodeURIComponent(this.productId) + '&productName=' + encodeURIComponent(this.productName) +
			'&thumbnailUrl=' + encodeURIComponent(this.thumbnailUrl) + '&pdpUrl=' + encodeURIComponent(this.pdpUrl) +
			'&action=addProduct';
		if (this.mainImageUrl != null)
			addProductUrl += '&mainImageUrl=' + encodeURIComponent(this.mainImageUrl);
			
		var content = '<fb:name uid="' + this.facebookUser.uid + '" firstnameonly="true" shownetwork="false"/> has a favorite product on <a href="http://apps.facebook.com/jansportfaves/">My JanSport Favorites</a> and would like to share it with you!\n' +
			'<fb:req-choice url="' + addProductUrl + '" label="View the Product Now!"/>';
		fbml = '<fb:request-form action="' + window.location.href + '" method="post" type="My JanSport Favorites" content="' + fluidSocial.htmlentities(content) + '" invite="true">' +
			'<fb:multi-friend-selector rows="3" bypass="cancel" actiontext="Select some friends to share this product with using My JanSport Favorites."/>' +
			'</fb:request-form>';

		this.sendInviteDialog = new FB.UI.FBMLPopupDialog('Invite Friends', fbml, false, false);
		this.sendInviteDialog.setContentWidth(760);
		this.sendInviteDialog.setContentHeight(560);
		this.sendInviteDialog.set_placement(FB.UI.PopupPlacement.topCenter);
		this.sendInviteDialog.add_closing(function() {
			fluidSocial.sendInviteDialog = null;
		});
		this.sendInviteDialog.show();
	},
	
	getNewestReview: function() {
		var fluidSocial = this;

		this.connector.getNewestReview(
			this.facebookUser.uid, this.friendIds, this.productId, function(response) {
			if (!fluidSocial.validateResponse(response))
				return;

			$("#fluid-fbCommentBubbleWrapper").html(response);
			
			$(".fluid-fbGoToReviewFormLink").click(function(event) {
				event.preventDefault();
				fluidSocial.tabSwap('fluid-fbTab2Content');
				$("#fluid-toggleFriendReviewsLink").text('Hide');
				$("#fluid-reviewsBox").slideDown();
				$('#fluid-friendsTabReviewText').focus();
			});
			
			fluidSocial.parseDomElement('fluid-fbCommentBubbleWrapper');
		});
	},
	
	getFriendReviews: function() {
		var fluidSocial = this;

		this.connector.getFriendReviews(
			this.facebookUser.uid, this.facebookUser.timezone, this.friendIds, this.productId, function(response) {
			if (!fluidSocial.validateResponse(response))
				return;

			$("#fluid-fbFriendsContent").html(response);
			$('input[type=radio].star', $('#fluid-fbFriendsContent')).rating();
			
			var commentCount = $('#fluid-fbFriendsContent .fluid-friendsTabPost').length;
			fluidSocial.debug("Friend Comment Count: " + commentCount);
			$('.fluid-fbCommentCount').html('(' + commentCount + ')');

			$("#fluid-toggleFriendReviewsLink").click(function(event) {
				event.preventDefault();
				
				if ($("#fluid-reviewsBox").is(":hidden"))
				{
					$("#fluid-toggleFriendReviewsLink").text('Hide');
					$("#fluid-reviewsBox").slideDown();
				}
				else
				{
					$("#fluid-toggleFriendReviewsLink").text('Show');
					$("#fluid-reviewsBox").slideUp();
				}
			});
			
			$("#fluid-friendsTabPostingSubmit a").click(function(event) {
				event.preventDefault();
				fluidSocial.postFriendsTabReview();
			});
			
			fluidSocial.reattachEventHandlers();
			fluidSocial.parseDomElement('fluid-fbFriendsContent');
		});
	},
	
	getFriendFavorites: function() {
		var fluidSocial = this;

		this.connector.getFriendFavorites(
			this.facebookUser.uid, this.friendIds, function(response) {
			if (!fluidSocial.validateResponse(response))
				return;

			$("#fluid-fbFavoritesContent").html(response);
			
			// Ensure that the standalone version has unique ids.
			response = response.replace('fluid-favoritesTabCountMessage', 'fluid-standaloneFavoritesTabCountMessage');
			response = response.replace('fluid-toggleFriendFavoritesLink', 'fluid-toggleFriendStandaloneFavoritesLink');
			response = response.replace('fluid-favoritesBox', 'fluid-standaloneFavoritesBox');
			response = response.replace('fluid-favoritesScroller', 'fluid-standaloneFavoritesScroller');

			$("#fluid-fbStandaloneFavoritesContent").html(response);

			$("#fluid-favoritesScroller .scrollable").scrollable({
				size: fluidSocial.favoritesScrollerSize,
				clickable: false
			}).mousewheel();
			$("#fluid-standaloneFavoritesScroller .scrollable").scrollable({
				size: fluidSocial.standaloneFavoritesScrollerSize,
				clickable: false
			}).mousewheel();

			var favoritesCount = $('#fluid-fbFavoritesContent .fluid-scrollerItem').length;
			fluidSocial.debug("Friend Favorites Count: " + favoritesCount);
			$('.fluid-fbFavoritesCount').html('(' + favoritesCount + ')');

			if (favoritesCount <= fluidSocial.favoritesScrollerSize)
			{
				$("#fluid-favoritesScroller .next").addClass("disabled");
			}
			
			var standaloneFavoritesCount = $('#fluid-fbStandaloneFavoritesContent .fluid-scrollerItem').length;
			fluidSocial.debug("Standalone Friend Favorites Count: " + standaloneFavoritesCount);

			if (standaloneFavoritesCount <= fluidSocial.standaloneFavoritesScrollerSize)
			{
				$("#fluid-standaloneFavoritesScroller .next").addClass("disabled");
			}

			$("#fluid-toggleFriendFavoritesLink").click(function(event) {
				event.preventDefault();
				
				if ($("#fluid-favoritesBox").is(":hidden"))
				{
					$("#fluid-toggleFriendFavoritesLink").text('Hide');
					$("#fluid-favoritesBox").slideDown();
				}
				else
				{
					$("#fluid-toggleFriendFavoritesLink").text('Show');
					$("#fluid-favoritesBox").slideUp();
				}
			});
			
			$("#fluid-toggleFriendStandaloneFavoritesLink").click(function(event) {
				event.preventDefault();
				
				if ($("#fluid-standaloneFavoritesBox").is(":hidden"))
				{
					$("#fluid-toggleStandaloneFriendFavoritesLink").text('Hide');
					$("#fluid-standaloneFavoritesBox").slideDown();
				}
				else
				{
					$("#fluid-toggleFriendStandaloneFavoritesLink").text('Show');
					$("#fluid-standaloneFavoritesBox").slideUp();
				}
			});
			
			$("a.fluid-friendFavoriteLink").click(function(event) {
				event.preventDefault();
	
				// Inform GA that the user clicked on a friend's favorite.
				if (fluidSocial.analyticsPresent())
				{
					pageTracker._trackEvent("PDP Events", "Friend Favorite Clicked");
				}		
				
				location.href = $(this).attr("href");
			});
			
			fluidSocial.reattachEventHandlers();
			fluidSocial.parseDomElement('fluid-fbFavoritesContent');
			fluidSocial.parseDomElement('fluid-fbStandaloneFavoritesContent');
		});
	},
	
	postFriendsTabReview: function() {
		var fluidSocial = this;
		
		$("#fluid-friendsTabPostingErrorMessage").hide();
		$("#fluid-friendsTabPostingProgressMessage").show();
				
		var rating = $("input[name='friendsTabRating']:checked").attr("value");
		var review = $("#fluid-friendsTabReviewText").attr("value");
		this.debug("postFriendsTabReview: " + this.productId + ", " + rating + ", " + review);
		
		if (rating == undefined && review == '')
		{
			$("#fluid-friendsTabPostingProgressMessage").hide();
			alert('Please enter a rating or a review.');
			return;
		}
		
		if (rating == undefined)
			rating = 0;

		this.connector.postReview(
			this.facebookUser.uid,
			this.productId,
			this.productName,
			this.pdpUrl,
			this.thumbnailUrl,
			this.mainImageUrl,
			rating,
			review,
			
			function(response) {
				if (!fluidSocial.validateResponse(response))
					return;
					
				// success callback
				$("#fluid-friendsTabPostingProgressMessage").hide();
				fluidSocial.getFriendReviews();
				
				// Inform GA that the product was commented on and rated.
				if (fluidSocial.analyticsPresent())
				{
					pageTracker._trackEvent("PDP Events", "Review and Rate Product", this.productId, Number(rating));
				}
				
				var caption = '';
				if (review != '' && rating == 0)
					caption = "{*actor*} commented on '" + fluidSocial.productName + "'.";
				else if (review == '' && rating > 0)
					caption = "{*actor*} gave '" + fluidSocial.productName + "' a rating of " + rating + " star" + ((rating != 1) ? "s" : "") + ".";
				else if (review != '' && rating > 0)
					caption = "{*actor*} commented on '" + fluidSocial.productName + "' and gave it a rating of " + rating + " star" + ((rating != 1) ? "s" : "") + ".";
				
				var attachment = {
					'name': fluidSocial.productName + ' on www.jansport.com',
					'href': fluidSocial.pdpUrl,
					'caption': caption,
					'media': [{'type': 'image', 'src': fluidSocial.thumbnailUrl.replace(/%20/, ' '), 'href': fluidSocial.pdpUrl}]
				};
			
				FB.Connect.streamPublish(review, attachment, null, null, 'What do you think about ' + fluidSocial.productName + '?');
			},
			
			function() {
				// error callback
				$("#fluid-friendsTabPostingProgressMessage").hide();
				$("#fluid-friendsTabPostingErrorMessage").show();
			}
		);
	},
	
	sendFeedback: function() {		
		// Validate the form.
		var reason = $("#fluid-feedback_form_reason").attr("value");
		var email = $("#fluid-feedback_form_email").attr("value");
		var subject = $("#fluid-feedback_form_subject").attr("value");
		var message = $("#fluid-feedback_form_message").attr("value");
		
		this.debug("sendFeedback: " + reason + ", " + email + ", " + subject + ", " + message);
		var valid = true;
		
		if (reason == '')
		{
			valid = false;
			$("#fluid-feedback_form_reason").addClass("fluid-feedback_form_value_error");
			$("label[for=fluid-feedback_form_reason]").addClass("fluid-feedback_form_label_error");
		}
		else
		{
			$("#fluid-feedback_form_reason").removeClass("fluid-feedback_form_value_error");
			$("label[for=fluid-feedback_form_reason]").removeClass("fluid-feedback_form_label_error");
		}
		
		if (message == '')
		{
			valid = false;
			$("#fluid-feedback_form_message").addClass("fluid-feedback_form_value_error");
			$("label[for=fluid-feedback_form_message]").addClass("fluid-feedback_form_label_error");
		}
		else
		{
			$("#fluid-feedback_form_message").removeClass("fluid-feedback_form_value_error");
			$("label[for=fluid-feedback_form_message]").removeClass("fluid-feedback_form_label_error");
		}
		
		if (!valid) return;
		this.closeDialogs();
		
		// Submit the feedback to the server.
		this.connector.sendFeedback(
			reason,
			email,
			subject,
			message,
			
			function(response) {
				if (!fluidSocial.validateResponse(response))
					return;
					
				// Inform GA that feedback was submitted.
				if (fluidSocial.analyticsPresent())
				{
					pageTracker._trackEvent("PDP Events", "Feedback Submitted", this.productId);
				}
				
				// Show confirmation.
				var message = $('<div class="fluid-fbinfobox">Thanks for your feedback!</div>');

				fluidSocial.statusDialog = new FB.UI.PopupDialog('Feedback Received', message.get(0), false, false);
				fluidSocial.statusDialog.setContentWidth(400);
				fluidSocial.statusDialog.set_placement(FB.UI.PopupPlacement.topCenter);
				fluidSocial.statusDialog.add_closing(function() {
					fluidSocial.statusDialog = null;
				});
				fluidSocial.statusDialog.show();
			}
		);
	},
	
	closeDialogs: function() {
		if (this.sendInviteDialog != null)
		{
			this.sendInviteDialog.close(false);
			this.sendInviteDialog = null;
		}
		if (this.statusDialog != null)
		{
			this.statusDialog.close(false);
			this.statusDialog = null;
		}
		$('#fluid-howitworks').hide();
		$('#fluid-firstVisitPopupWrapper').hide();
		$('#fluid-feedback').hide();
	},

	validateResponse: function(response) {
		var valid;
		
		if (response == null || response.indexOf('top.location.href') == -1)
		{
			valid = true;
		}
		else
		{
			// The user logged into the FB app first, and Facebook
			// has messed up the session cookies.  No choice but 
			// to logout of Facebook and start over.
			this.closeDialogs();
			FB.Connect.logout();
			valid = false;
		}
		
		return valid;
	},
	
	debug: function(message) {
		if (window.console)
			console.log(message);
	},
	
	analyticsPresent: function() {
		return (typeof(pageTracker) != 'undefined' && pageTracker != null);
	},
	
	parseDomElement: function(elementId) {
		var element = $('#' + elementId);
		if (element.length > 0)
			FB.XFBML.Host.parseDomElement(element.get(0));
	},
	
	get_html_translation_table: function(table, quote_style) {
	    // http://kevin.vanzonneveld.net
	    // +   original by: Philip Peterson
	    // +    revised by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
	    // +   bugfixed by: noname
	    // +   bugfixed by: Alex
	    // +   bugfixed by: Marco
	    // +   bugfixed by: madipta
	    // +   improved by: KELAN
	    // +   improved by: Brett Zamir (http://brett-zamir.me)
	    // +   bugfixed by: Brett Zamir (http://brett-zamir.me)
	    // +      input by: Frank Forte
	    // +   bugfixed by: T.Wild
	    // +      input by: Ratheous
	    // %          note: It has been decided that we're not going to add global
	    // %          note: dependencies to php.js, meaning the constants are not
	    // %          note: real constants, but strings instead. Integers are also supported if someone
	    // %          note: chooses to create the constants themselves.
	    // *     example 1: get_html_translation_table('HTML_SPECIALCHARS');
	    // *     returns 1: {'"': '&quot;', '&': '&amp;', '<': '&lt;', '>': '&gt;'}
	    
	    var entities = {}, hash_map = {}, decimal = 0, symbol = '';
	    var constMappingTable = {}, constMappingQuoteStyle = {};
	    var useTable = {}, useQuoteStyle = {};
	    
	    // Translate arguments
	    constMappingTable[0]      = 'HTML_SPECIALCHARS';
	    constMappingTable[1]      = 'HTML_ENTITIES';
	    constMappingQuoteStyle[0] = 'ENT_NOQUOTES';
	    constMappingQuoteStyle[2] = 'ENT_COMPAT';
	    constMappingQuoteStyle[3] = 'ENT_QUOTES';
	
	    useTable       = !isNaN(table) ? constMappingTable[table] : table ? table.toUpperCase() : 'HTML_SPECIALCHARS';
	    useQuoteStyle = !isNaN(quote_style) ? constMappingQuoteStyle[quote_style] : quote_style ? quote_style.toUpperCase() : 'ENT_COMPAT';
	
	    if (useTable !== 'HTML_SPECIALCHARS' && useTable !== 'HTML_ENTITIES') {
	        throw new Error("Table: "+useTable+' not supported');
	        // return false;
	    }
	
	    entities['38'] = '&amp;';
	    if (useTable === 'HTML_ENTITIES') {
	        entities['160'] = '&nbsp;';
	        entities['161'] = '&iexcl;';
	        entities['162'] = '&cent;';
	        entities['163'] = '&pound;';
	        entities['164'] = '&curren;';
	        entities['165'] = '&yen;';
	        entities['166'] = '&brvbar;';
	        entities['167'] = '&sect;';
	        entities['168'] = '&uml;';
	        entities['169'] = '&copy;';
	        entities['170'] = '&ordf;';
	        entities['171'] = '&laquo;';
	        entities['172'] = '&not;';
	        entities['173'] = '&shy;';
	        entities['174'] = '&reg;';
	        entities['175'] = '&macr;';
	        entities['176'] = '&deg;';
	        entities['177'] = '&plusmn;';
	        entities['178'] = '&sup2;';
	        entities['179'] = '&sup3;';
	        entities['180'] = '&acute;';
	        entities['181'] = '&micro;';
	        entities['182'] = '&para;';
	        entities['183'] = '&middot;';
	        entities['184'] = '&cedil;';
	        entities['185'] = '&sup1;';
	        entities['186'] = '&ordm;';
	        entities['187'] = '&raquo;';
	        entities['188'] = '&frac14;';
	        entities['189'] = '&frac12;';
	        entities['190'] = '&frac34;';
	        entities['191'] = '&iquest;';
	        entities['192'] = '&Agrave;';
	        entities['193'] = '&Aacute;';
	        entities['194'] = '&Acirc;';
	        entities['195'] = '&Atilde;';
	        entities['196'] = '&Auml;';
	        entities['197'] = '&Aring;';
	        entities['198'] = '&AElig;';
	        entities['199'] = '&Ccedil;';
	        entities['200'] = '&Egrave;';
	        entities['201'] = '&Eacute;';
	        entities['202'] = '&Ecirc;';
	        entities['203'] = '&Euml;';
	        entities['204'] = '&Igrave;';
	        entities['205'] = '&Iacute;';
	        entities['206'] = '&Icirc;';
	        entities['207'] = '&Iuml;';
	        entities['208'] = '&ETH;';
	        entities['209'] = '&Ntilde;';
	        entities['210'] = '&Ograve;';
	        entities['211'] = '&Oacute;';
	        entities['212'] = '&Ocirc;';
	        entities['213'] = '&Otilde;';
	        entities['214'] = '&Ouml;';
	        entities['215'] = '&times;';
	        entities['216'] = '&Oslash;';
	        entities['217'] = '&Ugrave;';
	        entities['218'] = '&Uacute;';
	        entities['219'] = '&Ucirc;';
	        entities['220'] = '&Uuml;';
	        entities['221'] = '&Yacute;';
	        entities['222'] = '&THORN;';
	        entities['223'] = '&szlig;';
	        entities['224'] = '&agrave;';
	        entities['225'] = '&aacute;';
	        entities['226'] = '&acirc;';
	        entities['227'] = '&atilde;';
	        entities['228'] = '&auml;';
	        entities['229'] = '&aring;';
	        entities['230'] = '&aelig;';
	        entities['231'] = '&ccedil;';
	        entities['232'] = '&egrave;';
	        entities['233'] = '&eacute;';
	        entities['234'] = '&ecirc;';
	        entities['235'] = '&euml;';
	        entities['236'] = '&igrave;';
	        entities['237'] = '&iacute;';
	        entities['238'] = '&icirc;';
	        entities['239'] = '&iuml;';
	        entities['240'] = '&eth;';
	        entities['241'] = '&ntilde;';
	        entities['242'] = '&ograve;';
	        entities['243'] = '&oacute;';
	        entities['244'] = '&ocirc;';
	        entities['245'] = '&otilde;';
	        entities['246'] = '&ouml;';
	        entities['247'] = '&divide;';
	        entities['248'] = '&oslash;';
	        entities['249'] = '&ugrave;';
	        entities['250'] = '&uacute;';
	        entities['251'] = '&ucirc;';
	        entities['252'] = '&uuml;';
	        entities['253'] = '&yacute;';
	        entities['254'] = '&thorn;';
	        entities['255'] = '&yuml;';
	    }
	
	    if (useQuoteStyle !== 'ENT_NOQUOTES') {
	        entities['34'] = '&quot;';
	    }
	    if (useQuoteStyle === 'ENT_QUOTES') {
	        entities['39'] = '&#39;';
	    }
	    entities['60'] = '&lt;';
	    entities['62'] = '&gt;';
	
	
	    // ascii decimals to real symbols
	    for (decimal in entities) {
	        symbol = String.fromCharCode(decimal);
	        hash_map[symbol] = entities[decimal];
	    }
	    
	    return hash_map;
	},
	
	htmlentities: function(string, quote_style) {
	    // http://kevin.vanzonneveld.net
	    // +   original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
	    // +    revised by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
	    // +   improved by: nobbler
	    // +    tweaked by: Jack
	    // +   bugfixed by: Onno Marsman
	    // +    revised by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
	    // +    bugfixed by: Brett Zamir (http://brett-zamir.me)
	    // +      input by: Ratheous
	    // -    depends on: get_html_translation_table
	    // *     example 1: htmlentities('Kevin & van Zonneveld');
	    // *     returns 1: 'Kevin &amp; van Zonneveld'
	    // *     example 2: htmlentities("foo'bar","ENT_QUOTES");
	    // *     returns 2: 'foo&#039;bar'
	
	    var hash_map = {}, symbol = '', tmp_str = '', entity = '';
	    tmp_str = string.toString();
	    
	    if (false === (hash_map = this.get_html_translation_table('HTML_ENTITIES', quote_style))) {
	        return false;
	    }
	    hash_map["'"] = '&#039;';
	    for (symbol in hash_map) {
	        entity = hash_map[symbol];
	        tmp_str = tmp_str.split(symbol).join(entity);
	    }
	    
	    return tmp_str;
	}
};
