var gNewCommentId;	// used to faciliate conversations with callback

/* Overload Functions to correct placement of the abuse box. */
function findPosX(obj) {
	var curleft = 0;
	if(obj.offsetParent)
		while(1) {
			curleft += obj.offsetLeft;
			if(!obj.offsetParent)
				break;
			obj = obj.offsetParent;
		}
	else if(obj.x)
		curleft += obj.x;
	return curleft;
}
function findPosY(obj) {
	var curtop = 0;
	if(obj.offsetParent)
		while(1) {
			curtop += obj.offsetTop;
			if(!obj.offsetParent)
				break;
			obj = obj.offsetParent;
		}
	else if(obj.y)
		curtop += obj.y;
	return curtop;
}
function mouseX(evt) {
	var curleft = 0;
	if (evt.pageX) { curleft = evt.pageX; }
	else if (evt.clientX) {
		curleft = evt.clientX + (document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft);
		curleft = curleft - (findPosX(document.getElementById("Comments_Container1"))/2);
	}
	return curleft;
}
function mouseY(evt) {
	var curtop = 0;
	if (evt.pageY) { curtop = evt.pageY; }
	else if (evt.clientY) {
		curtop = evt.clientY + (document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop);
		curtop = curtop - (findPosY(document.getElementById("Comments_Container1"))/2);
	}
	return curtop;
}
/* Overload the abuse function so we can also record it to the db */
function ReportAbuseViaDaapi() {
	/* hide the reporting form */
	HideDiv("ReportAbuse_Menu");
	/* do the report via daapi */
	var url = document.getElementById("ReportAbuse_Url").value; 
    var text = document.getElementById("ReportAbuse_CommentText").value;
    var reason = document.getElementById("ReportAbuse_Reason").value;
    
    /* get the key type and actual key from the command */
    var key = getCommandParam("ReportAbuse_Command", "plckTargetKey");
    var type = getCommandParam("ReportAbuse_Command", "plckTargetKeyType");
    if (key!="" && type!="") {
    	var ReportThisKey = false;
    	switch(type) {
    	case "Comment":
    		ReportThisKey = new CommentKey(key);
    		break;
    	}
    	if (ReportThisKey) {
		    var requestBatch = new RequestBatch();
		    requestBatch.AddToRequest(new ReportAbuseAction(ReportThisKey, reason, text));
		    requestBatch.BeginRequest(serverUrl, ReportAbuseViaDaapi_callback);
    	}
    }
}
function getCommandParam(commandId,paramName) {
    var command = document.getElementById(commandId).value;
    /* get the key type from the command */
    var arCommand = command.split("&");
    var key = "";
    var type = "";
    for (var i=0; i<arCommand.length; i++) {
    	var ar = arCommand[i].split("=");
    	if (ar[0]==paramName) return (ar[1]);
    }
    return "";
}
function ReportAbuseViaDaapi_callback(responseBatch) {
	/* invalidate the cache and reload the UI with the latest comments */
	invalidateCache();
	/* add the data to the commenting db */
	var dataIn = {};
	dataIn.ugcSiteID = publicusPath;
	dataIn.ugcType = "abuse";
	dataIn.ugcData = jQuery.trim($("#ReportAbuse_Reason").val()) + " [" + jQuery.trim($("#ReportAbuse_CommentText").val()) + "]";
	dataIn.articleKey = plckArticleKey;
	dataIn.articleUrl = plckArticleUrl;
	dataIn.articleTitle = plckArticleTitle;
	dataIn.articleDescription = getNonHtmlText(500, plckArticleDescription);
	dataIn.articleDate = plckArticleDate;
	dataIn.authorPluckUserKey = CurrentUser;
	dataIn.authorSSOKey = retrieveSSOCookieUserId();
	dataIn.authorDisplayName = RetrieveSSOCookieDisplayName();
	dataIn.authorAvatarPhotoUrl = RetrieveUserAvatarCookie();
	dataIn.itemType = getCommandParam("ReportAbuse_Command", "plckTargetKeyType").toLowerCase();
	dataIn.itemUgcKey = getCommandParam("ReportAbuse_Command", "plckTargetKey");
	dataIn = escape(JSON.stringify(dataIn));
	var url = appsPath + "/utils/utils/pluckUtils/store.php?jsoncallback=?&action=abuseReport&data=" + dataIn;
	$.getJSON(url,
			  function(data){
				// if (console) console.debug(data);
			  });
}
function reorderComments(sortOrder) {
	/* 'reorder' the comments by reloading the page
		Hey, wait?  Why not do something like e.innerHTML = gSiteLife.getComments?  Well....
		gSiteLife likes to work with document.writes.  Since the page is already rendered, it makes
		ajax-style interactivity very difficult, and I didn't want to do an iframe implementation.  So, 
		hi-ho, hi-ho, to a reload we will go... */
	// Strip out the sort field from the URL
	if (sortOrder && sortOrder != "") {
		oldurl = document.URL;
		newUrl = oldurl.replace(/&?sort=(timestampascending|timestampdescending|recommendationsdescending|recommendationsascending)/gi, "");
		newUrl += "&sort=" + sortOrder;
		window.location = newUrl;
	}
	return false;
}
gSiteLife.CommentsOutputWithURLFix = function(parentKeyType, parentKey, refreshPage, pageSize, sortOrder) {
	sortOrder = sortOrder || "TimeStampDescending";
	var parentUrl = document.URL;
	if (!parentUrl.match("plckCurrentPage"))
		parentUrl = parentUrl+"&";
	return this.CommentsInternal(parentKeyType, parentKey, pageSize, sortOrder, null, null, parentUrl, null, false, true, null, refreshPage);
}
function formSubmit(formObj) {
	// early exit on empty comment body
	if (formObj.elements.namedItem('comment.Body').value.trim() == '') {
		document.getElementById("CommentError").innerHTML = "* Please provide a comment.";
		return false;
	}
	fbConnect = document.getElementById('fbConnect');
	if (fbConnect && fbConnect.checked) {
		var previewImages = [];
		try {
			pluckArticleDescription = unescape('<pbs:macro name=ArticleDescriptionPluck>');
			slFB.submitArticleComment(PlickArticleTitle,
								 document.location.href,
								 pluckArticleDescription,
								 formObj.elements.namedItem('comment.Body').value.trim(),
								 previewImages,
								 fbCommentSubmitCallback);
			return false;	// suppress form submission.  We'll do that during the facebook callback.
		} catch(ex) {
			// if (console) console.debug(ex);
			return true;	// submit the form normally, despite the FB error
		}
	} else
		return true;		// submit the form noramally
}
function LimitLength(control, limitToLength) {
	var str = control.value;
	if(! str || str.length == 0) return false;
	if (str.length > limitToLength) {
		control.value = str.substring(0, limitToLength);
	}
	document.getElementById("CommentCharacterCount").innerHTML = str.length;
	return false;
}
function fbCommentSubmitCallback() {
	/* The comment was handled (either submitted or cancelled).  We 
	   still need to submit the form to Pluck and then reshow the form.  We 
	   do that all by a simple form submission */
	document.forms.commentSubmitForm.submit();
}
/* submitCommentViaDaapi() : called to submit a comment 
 * via Pluck DAAPI, clear the Pluck cache, and
 * add the comment to the Swift Comment db via JSON
 * assumes the following are defined elsewhere:
 * (element) commentBody
 * (element) CommentError
 * (element) commentListing
 * (element) daapiSubmit
 * (element) fbConnect
 * plckArticleKey
 * plckArticleUrl
 * plckArticleTitle
 * plckArticleDescription
 * plckArticleDate
 * 
 */
function submitCommentViaDaapi() {
	/* fix up the text to strip out abusable tags */
	// var allowedTags = "<a><b><blockquote><br><cite><del><em><i><ins><li><ol><p><q><s><strike><strong><sub><sup><u><ul>";
	var allowedTags = "a,b,blockquote,br,cite,del,em,i,ins,li,ol,p,q,s,strike,strong,sub,sup,u,ul";
	var text = jQuery.trim($("#commentBody").val());
	text = text.replace(/\n/gi, "<br/>");
	text = stripTags(text, allowedTags);
	text = stripCommentSGML(text);
	text = text.substr(0, 950);			// limit to 950, in case the browser doesn't catch it
	$("#commentBody").val(text);		// reset the form comment in case other routines use it directly
	// early exit on empty comment body
	if (text == '') {
		$("#CommentError").html("* Please provide a comment.");
		return false;
	}
	// Fix up the interface to indicate something is happening
	$("#commentListing").html("<img src='/Global/images/wheelOfJoy.gif' alt='downloading content'>" + $("#commentListing").html());
	// Block multi-requests
	if ($("#daapiSubmit").length > 0) $("#daapiSubmit")[0].disabled = true;
	// Batch it up and call pluck to do the add
	var requestBatch = new RequestBatch();
	var key = new ArticleKey(plckArticleKey);
	var action = new CommentAction(key, plckArticleUrl, plckArticleTitle, text);
	requestBatch.AddToRequest(action); 
	// initiate the request.  The response will be passed to the renderUserAvatar() method.  
	requestBatch.BeginRequest(serverUrl, afterDaapiCommentSubmission);
}
function afterDaapiCommentSubmission(responseBatch) {
	/* invalidate the cache and reload the UI with the latest comments */
	invalidateCache();
	if (responseBatch.Messages.length > 0 && responseBatch.Messages[0].Message=="ok") {
		/* add the data to the commenting db */
		var dataIn = {};
		dataIn.ugcSiteID = publicusPath;
		dataIn.ugcType = "comment";
		dataIn.ugcData = escape(jQuery.trim($("#commentBody").val()));
		dataIn.articleKey = plckArticleKey;
		dataIn.articleUrl = plckArticleUrl;
		dataIn.articleTitle = plckArticleTitle;
		dataIn.articleDescription = getNonHtmlText(500, plckArticleDescription);
		dataIn.articleDate = plckArticleDate;
		dataIn.authorPluckUserKey = CurrentUser;
		dataIn.authorSSOKey = retrieveSSOCookieUserId();
		dataIn.authorDisplayName = RetrieveSSOCookieDisplayName();
		dataIn.authorAvatarPhotoUrl = RetrieveUserAvatarCookie();
		dataIn.itemType = "story";		// Is this always true?
		dataIn.itemVendorID = plckArticleKey;
		dataIn = encodeURIComponent(JSON.stringify(dataIn));
		var url = appsPath + "/utils/utils/pluckUtils/store.php?jsoncallback=?&action=commentAction&data=" + dataIn;
		$.getJSON(url,
			   function(data){
					fixupCommentDbKey(data.newId);
				  });
		/* if we are performing fbConnect, do that now */
		fbConnect = document.getElementById('fbConnect');
		if (fbConnect && fbConnect.checked) {
			var previewImages = [];
			try {
				slFB.submitArticleComment(plckArticleTitle,
									 document.location.href,
									 plckArticleDescription,
									 jQuery.trim($("#commentBody").val()),
									 previewImages,
									 fbDaapiCommentSubmitCallback);
			} catch(ex) {
				// if (console) console.debug(ex);
			}
		}
	} else if (responseBatch.Messages.length > 0) {
		var html = "<div class='error'>Comment submission failed:  " + responseBatch.Messages[0].Message + "</div>";
		$("#CommentError").html(html);
	}
	if ($("#daapiSubmit").length > 0) $("#daapiSubmit")[0].disabled = false;
	$("#commentBody").val("");
	$("#CommentCharacterCount").html("<strong>0</strong>");
}
function fbDaapiCommentSubmitCallback() {
	// don't need to do anything at this point
}
/* return a max of size length of str, stripping html codes first */
function getNonHtmlText(size, str) {
	// First, replace any <br> or <br/> with \n
	str.replace(/(<br ?\/?>)/ig,"\n");
	// Now, replace the rest of the html
	str.replace(/(<([^>]+)>)/ig,"");		// thanks to http://zamov.online.fr/EXHTML/DHTML/DHTML_983246.html
	// return a max of size
	if (size>0) str = str.substr(0,size);
	return str;
}
/* addRecommendToDb() : called to 
 * add the recommend to the Swift Comment db via JSON
 * assumes the following are defined elsewhere:
 * (element) commentBody
 * (element) CommentError
 * (element) commentListing
 * (element) daapiSubmit
 * (element) fbConnect
 * plckArticleKey
 * plckArticleUrl
 * plckArticleTitle
 * plckArticleDescription
 * plckArticleDate
 * 
 * keyType = 'ExternalResource' for an article
 * 			 'Comment' for a comment
 */
function addRecommendToDb(keyType, targetKey) {
	//gSiteLife.PostRecommendation('Post','Blog:9057ff0d-6042-40ed-8488-3706d851aeabPost:ca2308fe-61cf-48cf-8404-7e6cc98018d5','rec_Blog:9057ff0d-6042-40ed-8488-3706d851aeabPost:ca2308fe-61cf-48cf-8404-7e6cc98018d5', document.title);
	var dataIn = {};
	dataIn.ugcSiteID = publicusPath;
	dataIn.ugcType = "recommend";
	dataIn.ugcData = "";		// no data for a recommend!
	dataIn.authorPluckUserKey = CurrentUser;
	dataIn.authorSSOKey = retrieveSSOCookieUserId();
	dataIn.authorDisplayName = RetrieveSSOCookieDisplayName();
	dataIn.authorAvatarPhotoUrl = RetrieveUserAvatarCookie();

	switch (keyType) {
	case "ExternalResource":		// story recommendation
		dataIn.articleKey = plckArticleKey;
		dataIn.articleUrl = plckArticleUrl;
		dataIn.articleTitle = plckArticleTitle;
		dataIn.articleDescription = getNonHtmlText(500, plckArticleDescription.replace(/'/g, "&#39;"));
		dataIn.articleDate = plckArticleDate;
		dataIn.itemType = "story";
		dataIn.itemVendorID = targetKey;	// this will be the article id for a story
		dataIn = escape(JSON.stringify(dataIn));
		addToDb_Go("recommendAction", dataIn);
		break;
	case "Comment":				// comment recommendation
		dataIn.articleKey = plckArticleKey;
		dataIn.articleUrl = plckArticleUrl;
		dataIn.articleTitle = plckArticleTitle;
		dataIn.articleDescription = getNonHtmlText(500, plckArticleDescription.replace(/'/g, "&#39;"));
		dataIn.articleDate = plckArticleDate;
		dataIn.itemType = "comment";
		dataIn.itemUgcKey = targetKey;
		dataIn = escape(JSON.stringify(dataIn));
		addToDb_Go("recommendAction", dataIn);
		break;
	case "Post":
		/* With a post, we use widgets so we don't have the nice JS variables to give us info.
		   Thus, we need to grab the post info from Pluck */
		var requestBatch = new RequestBatch();
		requestBatch.AddToRequest(new BlogPostKey(targetKey));
		requestBatch.BeginRequest(serverUrl, function(responseBatch) {
			if (responseBatch.Responses.length>0) {
				var response = responseBatch.Responses[0];
				if (response.BlogPost!=null) {
					var post = response.BlogPost;

					// First, add the post itself if it isn't already in there (again, since we don't use daapi, we aren't hooking the post creation code)
					dataQuery = {};
					dataQuery.type = "post";
					dataQuery.itemUgcKey = post.BlogKey;
					dataQuery = escape(JSON.stringify(dataQuery));
					var url = appsPath + "/utils/utils/pluckUtils/store.php?jsoncallback=?&action=query&data=" + dataQuery;
					$.getJSON(url,
							  function(responseOut){
									var dataOut = responseOut.dataOut;
									if (dataOut.error == "" && dataOut.queryResults.length==0) {
										// Post is missing, so add it
										var site = post.SiteOfOrigin.toLowerCase();		// will be sitelife<stage?>.<domain>.com.  Remove sitelife
										site = site.replace(/sitelife/g, "");
										if (site[0]==".") site = "www" + site;
										site = "http://" + site;
										
										dataPost = {};
										dataPost.ugcSiteID = site;
										dataPost.ugcType = "post";
										dataPost.ugcData = post.PostBody.replace(/'/g, "&#39;");
										dataPost.ugcDate = post.PostDate;
										dataPost.authorPluckUserKey = post.PostAuthor.UserKey.Key;
										dataPost.authorSSOKey = post.PostAuthor.Email;
										dataPost.authorDisplayName = post.PostAuthor.DisplayName;
										dataPost.authorAvatarPhotoUrl = post.PostAuthor.AvatarPhotoUrl;
										dataPost.articleKey = post.BlogPostKey.Key;
										dataPost.articleUrl = post.Url;
										dataPost.articleTitle = post.PostTitle;
										dataPost.articleDescription = getNonHtmlText(500, post.PostBody.replace(/'/g, "&#39;"));
										dataPost.articleDate = post.PostDate;
										dataPost.itemType = "post";
										dataPost.itemUgcKey = post.BlogPostKey.Key;
										dataPost = escape(JSON.stringify(dataPost));
										addToDb_Go("postAction", dataPost);
									}
							  });
					
					// Add the recommend itself
					dataIn.articleKey = post.BlogPostKey;
					dataIn.articleUrl = post.Url;
					dataIn.articleTitle = post.PostTitle;
					dataIn.articleDescription = getNonHtmlText(500, post.PostBody.replace(/'/g, "&#39;"));
					dataIn.articleDate = post.PostDate;
					dataIn.itemType = "post";
					dataIn.itemUgcKey = post.BlogPostKey.Key;
					dataIn = escape(JSON.stringify(dataIn));
					addToDb_Go("recommendAction", dataIn);
				}
			}
		});
		break;
	case "Photo":
		/* With a photo, we use widgets so we don't have the nice JS variables to give us info.
		   Thus, we need to grab the info from Pluck */
		var requestBatch = new RequestBatch();
		requestBatch.AddToRequest(new PhotoKey(targetKey));
		requestBatch.BeginRequest(serverUrl, function(responseBatch) {
			if (responseBatch.Responses.length>0) {
				var response = responseBatch.Responses[0];
				if (response.Photo!=null) {
					var photo = response.Photo;

					// First, add the post itself if it isn't already in there (again, since we don't use daapi, we aren't hooking the post creation code)
					dataQuery = {};
					dataQuery.type = "photo";
					dataQuery.itemUgcKey = photo.PhotoKey.Key;
					dataQuery = escape(JSON.stringify(dataQuery));
					var url = appsPath + "/utils/utils/pluckUtils/store.php?jsoncallback=?&action=query&data=" + dataQuery;
					$.getJSON(url,
							  function(responseOut){
									var dataOut = responseOut.dataOut;
									if (dataOut.error == "" && dataOut.queryResults.length==0) {
										// Post is missing, so add it
										var site = photo.SiteOfOrigin.toLowerCase();		// will be sitelife<stage?>.<domain>.com.  Remove sitelife
										site = site.replace(/sitelife/g, "");
										if (site[0]==".") site = "www" + site;
										site = "http://" + site;
										
										dataPost = {};
										dataPost.ugcSiteID = site;
										dataPost.ugcType = "photo";
										ugcData = {};
										ugcData.PhotoKey = photo.PhotoKey;
										ugcData.GalleryKey = photo.GalleryKey;
										ugcData.Image = photo.Image;
										ugcData.Title = photo.Title;
										ugcData.Description = photo.Description;
										// dataPost.ugcData = photo.Image;			// this is actually an array of images for the various sizes
										dataPost.ugcData = ugcData;
										dataPost.ugcDate = photo.CreatedOn;
										dataPost.authorPluckUserKey = photo.Author.UserKey.Key;
										dataPost.authorSSOKey = photo.Author.Email;
										dataPost.authorDisplayName = photo.Author.DisplayName;
										dataPost.authorAvatarPhotoUrl = photo.Author.AvatarPhotoUrl;
										dataPost.articleKey = photo.PhotoKey.Key;
										dataPost.articleUrl = appsPath + "/utils/photogalleries/ui/publicgallery.php?plckPhotoID=" + photo.PhotoKey.Key + "&plckGalleryID=" + photo.GalleryKey.Key;
										dataPost.articleTitle = photo.Title;
										dataPost.articleDescription = getNonHtmlText(500, photo.Description.replace(/'/g, "&#39;"));
										dataPost.articleDate = photo.CreatedOn;
										dataPost.itemType = "photo";
										dataPost.itemUgcKey = photo.PhotoKey.Key;
										dataPost = escape(JSON.stringify(dataPost));
										addToDb_Go("photoAction", dataPost);
									}
							  });
					
					// Add the recommend itself
					dataIn.articleKey = photo.PhotoKey.Key;
					dataIn.articleUrl = appsPath + "/utils/photogalleries/ui/publicgallery.php?plckPhotoID=" + photo.PhotoKey.Key + "&plckGalleryID=" + photo.GalleryKey.Key;
					dataIn.articleTitle = photo.Title;
					dataIn.articleDescription = getNonHtmlText(500, photo.Description.replace(/'/g, "&#39;"));
					dataIn.articleDate = photo.CreatedOn;
					dataIn.itemType = "photo";
					dataIn.itemUgcKey = photo.PhotoKey.Key
					dataIn = escape(JSON.stringify(dataIn));
					addToDb_Go("recommendAction", dataIn);
				}
			}
		});
		break;
	case "Video":
		/* With a video, we use widgets so we don't have the nice JS variables to give us info.
		   Thus, we need to grab the info from Pluck */
		var requestBatch = new RequestBatch();
		requestBatch.AddToRequest(new VideoKey(targetKey));
		requestBatch.BeginRequest(serverUrl, function(responseBatch) {
			if (responseBatch.Responses.length>0) {
				var response = responseBatch.Responses[0];
				if (response.Video!=null) {
					var video = response.Video;

					// First, add the post itself if it isn't already in there (again, since we don't use daapi, we aren't hooking the post creation code)
					dataQuery = {};
					dataQuery.type = "video";
					dataQuery.itemUgcKey = video.VideoKey.Key;
					dataQuery = escape(JSON.stringify(dataQuery));
					var url = appsPath + "/utils/utils/pluckUtils/store.php?jsoncallback=?&action=query&data=" + dataQuery;
					$.getJSON(url,
							  function(responseOut){
									var dataOut = responseOut.dataOut;
									if (dataOut.error == "" && dataOut.queryResults.length==0) {
										// Video is missing, so add it
										var site = video.SiteOfOrigin.toLowerCase();		// will be sitelife<stage?>.<domain>.com.  Remove sitelife
										site = site.replace(/sitelife/g, "");
										if (site[0]==".") site = "www" + site;
										site = "http://" + site;
										
										dataPost = {};
										dataPost.ugcSiteID = site;
										dataPost.ugcType = "video";
										ugcData = {};
										ugcData.VideoKey = video.VideoKey;
										ugcData.GalleryKey = video.GalleryKey;
										ugcData.VideoUrl = video.VideoUrl;
										ugcData.VideoThumbnail = video.VideoThumbnail;
										ugcData.Title = video.Title;
										ugcData.Description = video.Description;
										dataPost.ugcData = ugcData;
										// dataPost.ugcData = video.VideoUrl;
										dataPost.ugcDate = video.CreatedOn;
										dataPost.authorPluckUserKey = video.Author.UserKey.Key;
										dataPost.authorSSOKey = video.Author.Email;
										dataPost.authorDisplayName = video.Author.DisplayName;
										dataPost.authorAvatarVideoUrl = video.Author.AvatarVideoUrl;
										dataPost.articleKey = video.VideoKey.Key;
										dataPost.articleUrl = appsPath + "/utils/uservideo/PlayMovie.php?PluckGalleryId=" + video.GalleryKey.Key + "&PluckVideoId=" + video.VideoKey.Key + "&PluckGalleryDesc=video gallery&PlcukGalleryTitle=video gallery";
										dataPost.articleTitle = video.Title;
										dataPost.articleDescription = getNonHtmlText(500, video.Description.replace(/'/g, "&#39;"));
										dataPost.articleDate = video.CreatedOn;
										dataPost.itemType = "video";
										dataPost.itemUgcKey = video.VideoKey.Key;
										dataPost = escape(JSON.stringify(dataPost));
										addToDb_Go("videoAction", dataPost);
									}
							  });
					
					// Add the recommend itself
					dataIn.articleKey = video.VideoKey.Key;
					dataIn.articleUrl = appsPath + "/utils/uservideo/PlayMovie.php?PluckGalleryId=" + video.GalleryKey.Key + "&PluckVideoId=" + video.VideoKey.Key + "&PluckGalleryDesc=video gallery&PlcukGalleryTitle=video gallery";
					dataIn.articleTitle = video.Title;
					dataIn.articleDescription = getNonHtmlText(500, video.Description.replace(/'/g, "&#39;"));
					dataIn.articleDate = video.CreatedOn;
					dataIn.itemType = "video";
					dataIn.itemUgcKey = video.VideoKey.Key
					dataIn = escape(JSON.stringify(dataIn));
					addToDb_Go("recommendAction", dataIn);
				}
			}
		});
		break;
	case "UserProfileKey":
		/* With a user profile, we use widgets so we don't have the nice JS variables to give us info.
		   Thus, we need to grab the info from Pluck */
		var requestBatch = new RequestBatch();
		requestBatch.AddToRequest(new UserKey(targetKey));
		requestBatch.BeginRequest(serverUrl, function(responseBatch) {
			if (responseBatch.Responses.length>0) {
				var response = responseBatch.Responses[0];
				if (response.User!=null) {
					var user = response.User;

					// First, add the post itself if it isn't already in there (again, since we don't use daapi, we aren't hooking the post creation code)
					dataQuery = {};
					dataQuery.type = "user";
					dataQuery.itemUgcKey = user.UserKey.Key;
					dataQuery = escape(JSON.stringify(dataQuery));
					var url = appsPath + "/utils/utils/pluckUtils/store.php?jsoncallback=?&action=query&data=" + dataQuery;
					$.getJSON(url,
							  function(responseOut){
									var dataOut = responseOut.dataOut;
									if (dataOut.error == "" && dataOut.queryResults.length==0) {
										// Post is missing, so add it
										dataPost = {};
										dataPost.ugcSiteID = ""; 				// users are not tied to a specific site in Pluck
										dataPost.ugcType = "user";
										dataPost.ugcData = user.DisplayName;
										dataPost.ugcDate = user.CreatedOn;
										dataPost.authorPluckUserKey = user.UserKey.Key;
										dataPost.authorSSOKey = user.Email;
										dataPost.authorDisplayName = user.DisplayName;
										dataPost.authorAvatarPhotoUrl = user.AvatarPhotoUrl;
										dataPost.articleKey = user.UserKey.Key;
										dataPost.articleUrl = appsPath + "/utils/usergalleries/ui/publicgallery.php?plckuserID=" + user.UserKey.Key + "&plckGalleryID=" + user.UserKey.Key;
										dataPost.articleTitle = user.Title;
										dataPost.articleDescription = getNonHtmlText(500, user.AboutMe.replace(/'/g, "&#39;"));
										dataPost.articleDate = user.CreatedOn;
										dataPost.itemType = "user";
										dataPost.itemUgcKey = user.UserKey.Key;
										dataPost = escape(JSON.stringify(dataPost));
										addToDb_Go("userAction", dataPost);
									}
							  });
					
					// Add the recommend itself
					dataIn.articleKey = user.UserKey.Key;
					dataIn.articleUrl = appsPath + "/utils/usergalleries/ui/publicgallery.php?plckuserID=" + user.UserKey.Key + "&plckGalleryID=" + user.UserKey.Key;
					dataIn.articleTitle = user.DisplayName;
					dataIn.articleDescription = getNonHtmlText(500, user.AboutMe.replace(/'/g, "&#39;"));
					dataIn.articleDate = user.CreatedOn;
					dataIn.itemType = "user";
					dataIn.itemUgcKey = user.UserKey.Key
					dataIn = escape(JSON.stringify(dataIn));
					addToDb_Go("recommendAction", dataIn);
				}
			}
		});
		break;
	default:
		// if (console) console.debug("recommendation for key type " + keyType + " not available for adding to the meta db");
		break;
	}
}

function addToDb_Go(action, dataIn) {
	/* add the data to the commenting db */
	var url = appsPath + "/utils/utils/pluckUtils/store.php?jsoncallback=?&action=" + action + "&data=" + dataIn;
	$.getJSON(url,
			  function(data){
					//if (console) console.debug(data);
			  });
}
/* get the latest comment id and fix up the new comment record in the swift db */
function fixupCommentDbKey(newId) {
	/* Because responseBatch doesn't have the comment's id, we need to go get it.
	 * We'll do this by issuing a batch for the latest comment that meets certain criteria
	 * that will give us a 99.99% chance this is the correct comment.  HOWEVER, it
	 * is possible that we may get the wrong id back, thus linking the Swift db to
	 * the wrong comment.  So then we'll roll through the requests and find the first
	 * that matches the current author
	 */
	gNewCommentId = newId;		// set the global id for conversation with the callback
	var requestBatch = new RequestBatch();
	requestBatch.AddToRequest(getCommentPageRequest(plckArticleKey, 10, 1, "TimeStampDescending")); 
	requestBatch.BeginRequest(serverUrl, fixupCommentDbKey_callback);
}
function fixupCommentDbKey_callback(responseBatch) {
	for (var i=0;i<responseBatch.Responses.length;i++) {
		var response = responseBatch.Responses[i];
		if (response.CommentPage && response.CommentPage.Comments.length > 0) {
			for (var c=0;c<response.CommentPage.Comments.length;c++) {
				// Ensure the comment we are looking at is the last comment made by THIS user on this article
				var sn = RetrieveSSOCookieDisplayName();
				var comment = response.CommentPage.Comments[c];
				if (comment.Author.DisplayName == sn) {
					var dataIn = {};
					dataIn.commentKey = comment.CommentKey.Key;
					dataIn.commentId = gNewCommentId;
					dataIn = escape(JSON.stringify(dataIn));
					var url = appsPath + "/utils/utils/pluckUtils/store.php?jsoncallback=?&action=fixupCommentKey&data=" + dataIn;
					$.getJSON(url,
							  function(data){
								//if (console) console.debug(data);
							  });
					break;	// end the for loop
				}
			}
		}
	}
}

gSiteLife.PostRecommendation = function(keyType, targetKey, recommendDiv, parentTitle, parentUrl) {
	parentUrl = parentUrl || window.location.href;
	var url = this.__baseUrl +
		'/Recommend/PostRecommendation?plckElementId=' + recommendDiv +
		'&plckTargetKey=' + gSiteLife.EscapeValue(targetKey) +
		'&plckTargetKeyType=' + keyType +
		'&plckTargetUrl=' + gSiteLife.EscapeValue(parentUrl);
	if (parentTitle) {
		try {
			// plckArticleTitle only exists if this is an article; if it is missing, use parentTitle
			url += '&plckParentTitle=' + plckArticleTitle;
		} catch(x) {
			url += '&plckParentTitle=' + gSiteLife.EscapeValue(parentTitle);
		}
	}
	this.__Send(url);
	// Invalidate cache
	if (DappiPath != "") {
		var sCacheInvalidateUrl = DappiPath + "/utils/utils/pluckUtils/cachingProxy/pluck.service.php?action=invalidatecache&uid="+uniqueCacheGroupKey;
	} else {
		var sCacheInvalidateUrl = appsPath + "/utils/utils/pluckUtils/cachingProxy/pluck.service.php?action=invalidatecache&uid="+uniqueCacheGroupKey;
	}
	this.__Send(sCacheInvalidateUrl);
	// Write record to the db
	addRecommendToDb(keyType, targetKey);
	return false;
}
gSiteLife.ArticleRecommend = function(keyType, targetKey, parentUrl) {
	keyType = keyType || "ExternalResource";
	targetKey = targetKey || gSiteLife.__StripAnchorFromUrl(window.location.href);
	parentUrl = parentUrl || window.location.href;
	targetKey = targetKey;
	var url = this.__baseUrl + 
		'/Recommend/Recommend?plckElementId=articleRecommend' + 
		'&plckTargetKey=' + gSiteLife.EscapeValue(targetKey) + 
		'&plckTargetKeyType=' + keyType +
		'&plckTargetUrl=' + gSiteLife.EscapeValue(parentUrl);
	this.__Send(url);
	return false;
}
gSiteLife.CommentsInputWithTitle = function(parentKey, title, redirectToUrl) {
	return this.CommentsInternal("ExternalResource", parentKey, null, null, null, null, null, title, true, false, redirectToUrl, false);
}
SiteLifeProxy.prototype.Blog = function(BlogId,DestID) {
	if (!DestID) {
		DestID = "blogDest";
		this.WriteDiv("blogDest", "Persona_Main");
	}
	var action = this.GetParameter("plckBlogPage");
	if(!BlogId){
		BlogId = this.GetParameter('plckBlogId');
	}
	if(action && action != "Blog" && (typeof this[action] == 'function')){
		return this[action](BlogId);
	}else{
		var AdParams = this.GetParameter('plckCurrentPage') ? 'plckCurrentPage=' + this.GetParameter('plckCurrentPage') : "";
		return this.BlogSend('Blog', 'Blog', DestID, 'blogScript', BlogId, AdParams);
	}
}
SiteLifeProxy.prototype.PersonaHeader = function(UserId,DestID) {
	if (!DestID) {
		DestID = "personaHDest";
		this.WriteDiv("personaHDest", "Persona_Main");
	}
	this.AddEventHandler('persona:header', function() { gSiteLife.PersonaHeaderInbox();  });
	this.PersonaHeaderRequest(UserId); 
}
SiteLifeProxy.prototype.Persona = function(UserId,DestID) {
	if (!DestID) {
		DestID = "personaDest";
		this.WriteDiv("personaDest", "Persona_Main");
	}
	var action = this.GetParameter("plckPersonaPage");
	if(action && (typeof this[action] == 'function')) this[action](UserId);
	else this.PersonaHome(UserId);
}
SiteLifeProxy.prototype.PhotoUpload = function(DestID) {
	if (!DestID) {
		DestID = 'plcksubmit';
		this.WriteDiv(DestID);
	}
	var galleryID = gSiteLife.GetParameter('plckGalleryID');
	var url = this.__baseUrl + '/Photo/PhotoUpload?plckElementId=' + DestID + '&plckGalleryID=' +galleryID;
	this.__Send(url);
	return false;
}

SiteLifeProxy.prototype.PublicGallery = function(DestID) {
	if (!DestID) {
		DestID = 'plckgallery';
		this.WriteDiv(DestID);
	}
	var galleryID = gSiteLife.GetParameter('plckGalleryID');
	var pageNum = gSiteLife.GetParameter('plckPageNum');
	var url = this.__baseUrl + '/Photo/PublicGallery?plckElementId=' + DestID + '&plckGalleryID=' +galleryID + '&plckPageNum=' +pageNum;
	this.__Send(url);
	return false;
}
SiteLifeProxy.prototype.GalleryPhoto = function(DestID) {
	if (!DestID) {
		elementId = 'plckphoto';
		this.WriteDiv(DestID);
	}
	var photoid = gSiteLife.GetParameter('plckPhotoID');
	var findCommentKey = gSiteLife.ReadFindCommentKey(null, "widget:galleryPhoto");
	var url = this.__baseUrl + '/Photo/GalleryPhoto?plckElementId=' + DestID + '&plckPhotoID=' +photoid + '&plckFindCommentKey=' + findCommentKey;
	this.__Send(url, null, "widget:galleryPhoto");
	return false;
}
SiteLifeProxy.prototype.PublicGalleries = function(DestID) {
	if (!DestID) {
		DestID = 'plckgalleries';
		this.WriteDiv(DestID);
	}
	var pageNum = gSiteLife.GetParameter('plckPageNum') ?  gSiteLife.GetParameter('plckPageNum') : "0";
	var url = this.__baseUrl + '/Photo/PublicGalleries?plckElementId=' + DestID + '&plckPageNum=' + pageNum;
	this.__Send(url);
	return false;
}
