appIconCandidateFlickrPhotoIds = new Array();
appIconCandidatePhotoIds = new Array();

Array.prototype.remove = function(from, to) {
	var rest = this.slice((to || from) + 1 || this.length);
	this.length = from < 0 ? this.length + from : from;
	return this.push.apply(this, rest);
};

function verifyNotEmpty(encodedDisplayName, idName) {
//alert("verifyNotEmpty called with encodedDisplayName = " + encodedDisplayName + ", idName = " + idName);
	displayName = Base64.decode(encodedDisplayName);
	if(isEmpty($("#" + idName).val())) { alert("The " + displayName + " field cannot be empty"); return false; }
	else return true;
}

String.prototype.trim = function() {
	return this.replace(/^\s+|\s+$/g,"");
}

function toggleAbstractPricesDropdown() {
var showAbstractPricesDropdown = Number($("#has_prices_select").val());
	if(showAbstractPricesDropdown) $("#has_abstract_prices_span").css("display","inline");
	else $("#has_abstract_prices_span").css("display","none");
}

function toggleSpatialGroupsDropdown() {
var showSpatialGroupsDropdown = Number($("#has_locations_select").val());
	if(showSpatialGroupsDropdown) $("#has_spatial_groups_span").css("display","inline");
	else $("#has_spatial_groups_span").css("display","none");
}

function updateCommentResponse(commentId, urlencodedAppName) {
//alert("updateCommentResponse new response = " + $("#input_new_response_for_comment_id_" + commentId).val());
	ajaxURL = "?app=" + urlencodedAppName + "&commentid=" + commentId + "&new_comment_response_ajax=" + Base64.encode($("#input_new_response_for_comment_id_" + commentId).val());
	$("#change_response_datum_" + commentId).css("display","none");
//	$("#waiting_img").css("display","inline");
	$.getJSON(ajaxURL,
        	function(data){
			succeeded = Number(data.succeeded);
			if(succeeded < 1) {
				alert ("Failed to update the comment");
				$("#change_response_datum_" + commentId).css("display","inline");
			}
			else {		
				$("#change_response_datum_" + commentId).css("display","none");
				$("#actual_response_text_" + commentId).html($("#input_new_response_for_comment_id_" + commentId).val());				
				$("#response_datum_" + commentId).css("display","inline");
			}
          	}
	);
	return false; // don't continue the form processing
}

function savePhotoOrdering(urlencodedAppName, urlencodedEntryName) {
	var originalPhotoIds = new Array();
	$(".thumblink").each(function(index) { originalPhotoIds.push($(this).attr("id")); } );

	var orderedPhotoIds = new Array();	
	$(".resorted_thumbnail").each(function() { orderedPhotoIds.push(Number($(this).attr("photo_id"))) } );

//	alert("originalPhotoIds = " + originalPhotoIds + ", orderedPhotoIds = " + orderedPhotoIds);

	var tmpOld = originalPhotoIds.join(",");
	var tmpNew = orderedPhotoIds.join(",");

//	alert('savePhotoOrdering tmpOld = ' + tmpOld + ', tmpNew = ' + tmpNew);

	if(tmpOld == tmpNew) { unshade(1); }
	else {

//		alert("savePhotoOrdering urlencodedAppName = " + urlencodedAppName + ", urlencodedEntryName = " + urlencodedEntryName + ", orderedPhotoIds = " + orderedPhotoIds.join(", "));

		ajaxURL = "?app=" + urlencodedAppName + "&entry_name=" + urlencodedEntryName + "&new_photo_ordering=" + orderedPhotoIds.join(",");



		$.getJSON(ajaxURL,
			function(data){
				succeeded = Number(data.succeeded);
				if(succeeded < 1) {
					alert ("Failed to update the photo ordering");
//					$("#change_response_datum_" + commentId).css("display","inline");
				}
				else {
					reorderThumbnails(orderedPhotoIds);
					unshade(1);
//					alert("TODO :) update the actual/visible photos...");
//					$("#change_response_datum_" + commentId).css("display","none");
//					$("#actual_response_text_" + commentId).html($("#input_new_response_for_comment_id_" + commentId).val());				
//					$("#response_datum_" + commentId).css("display","inline");
				}
          		}
		);
	}
	return false; // don't continue the form processing
}

function reorderThumbnails(newPhotoOrder) {
//alert("reorderThumbnails() called with newPhotoOrder = " + newPhotoOrder);
	for(var i = newPhotoOrder.length - 1; i >= 0; i--) {
		var photoIdToMove = Number(newPhotoOrder[i]);
		var detachedLink = $("#" + photoIdToMove).detach();
		$("#thumblist").prepend(detachedLink);
	}
}

function verifyNewUser() {
	var errorMessages = new Array();
	var username = $("#username").val();
	var password = $("#password").val();
	var password_retype = $("#password_retype").val();
	var firstname = $("#firstname").val();
	var lastname = $("#lastname").val();
	var newappname = $("#newappname").val();

	if(isEmpty(firstname)) errorMessages.push("First name is required");
	if(isEmpty(lastname)) errorMessages.push("Last name is required");
	if(isEmpty(username)) errorMessages.push("Email address is required");
	else if(!validateEmail(username.trim())) errorMessages.push("Email address is not valid");

	if(isEmpty(password)) errorMessages.push("Password is required");
	else if(password.length < 8) errorMessages.push("Password needs to be at least 8 characters");
	else if((password.length != 40) && !((password.length == password_retype.length) && (password.indexOf(password_retype) == 0))) errorMessages.push("Passwords do not match");

	if(errorMessages.length == 0) return true;
	else alert(errorMessages.join(", "));

//	alert("errorMessages = " + errorMessages + ", errorMessages.length = " + errorMessages.length);
//	alert("username = " + username + ", password = " + password + ", password_retype = " + password_retype + ", firstname = " + firstname + ", lastname = " + lastname + ", newappname = " + newappname);
	return false;
}

function buildFilterURL(appName) {
//	alert("buildFilterURL returning " +  '?app=' + appName + '&spatial_filter=' + $('#spatial_filter').val() + '&filter=' + $('#filter').val());
	return '?app=' + appName + '&spatial_filter=' + $('#spatial_filter').val() + '&filter=' + $('#filter').val();
}

function buildAppStatusUpdateURL(appNameEncoded, dropdownId, returnPage) {
	var retVal = '?app=' + appNameEncoded + '&newappstatus=' + $('#' + dropdownId).val() + '&returnpage=' + returnPage;
//	alert("buildAppStatusUpdateURL returning " + retVal);
	return retVal;
}

function buildAppRegionUpdateURL(appNameEncoded, dropdownId) {
	var retVal = '?app=' + appNameEncoded + '&newappregion=' + $('#' + dropdownId).val();
	return retVal;
}


function buildGroupingUpdateURL(appName) {
//	alert("buildFilterURL returning " +  '?app=' + appName + '&spatial_filter=' + $('#spatial_filter').val() + '&filter=' + $('#filter').val());
	return '?app=' + appName + '&action=groups&newspatialgrouping=' + $('#spatial_grouping_selector').val();
}

function showAddressLine(showElseHide) {
	$("#addressline").css("display", showElseHide ? "inline" : "none");
//        if(showElseHide) $("#yeslocation").attr("CHECKED", "");
//        else(showElseHide) $("#nolocation").attr("CHECKED", "");
}

/*
function registerEntryLinkPicker(urlencodedAppName, myEditor) {
//alert("registerEntryLinkPicker() called with urlencodedAppName = " + urlencodedAppName + ", myEditor = " + myEditor);
 	var menu = new YAHOO.widget.Overlay('inserticon', { width: '300px', height: '100px', visible: false });
	menu.setBody('<div id="entrylinkpicker" style="font-size:.6em;">Link to entry:<br><div id="entry_select_div"></div></div>');
	var imgConfig = {
		type: 'push', label: 'Link to Entry', value: 'inserticon',
		menu: function() {

	                menu.beforeShowEvent.subscribe(function() {
				ajaxURL = "?app=" + urlencodedAppName + "&action=listentriesAJAX";
				$.getJSON(ajaxURL, function(data){
					var selectOptions = '';
        	  			$.each(data.entries, function(i,entry){
						selectOptions += '<option value="' + entry.id + '">' + entry.entry_name + '</option>';
					});
					$("#entry_select_div").html('<select name="entryselect" onchange=\'alert("hi world");\'>' + selectOptions + '</select>');
				});

                		menu.cfg.setProperty('context', [myEditor.toolbar.getButtonByValue('inserticon').get('element'), 'tl', 'bl']);
                	});
	                menu.render(document.body);
			menu.element.style.visibility = 'hidden';
                	return menu;
            	}()
	};

        YAHOO.log('Create the (inserticon) Button', 'info', 'example');
        myEditor.toolbar.addButtonToGroup(imgConfig, 'insertitem');

        myEditor.toolbar.on('inserticonClick', function(ev) {
            YAHOO.log('inserticonClick Event Fired: ' + YAHOO.lang.dump(ev), 'info', 'example');
            var icon = '';
            this._focusWindow();
            if (ev.icon) {
                icon = ev.icon;
            }
            this.execCommand('inserthtml', '<img src="' + icon + '" border="0">');
            return false;
        }, myEditor, true);
}
*/

function setupEntryLinkDialog() {
	var url = $(".external_entry_link_input").val();
	if(!isEmpty(url)) {
		var matches = url.match(/SMEntryLink:\/\/(\d+)$/);
		if(matches) {
			$("#entry_link_select").val(matches[1]);
			$("#external_link_input").css("display", "none");
//			alert("kevin: matches[1] = " + matches[1]);
		}
		else {
			$("#entry_link_select").val(0);
			$("#external_link_input").css("display", "inline");
			$("#external_link_input").val(url);
//			$(".external_entry_link_input").val("");
		}
	}
	else {
		$("#entry_link_select").val(0);
		$("#external_link_input").val("http://");
		$("#external_link_input").css("display", "inline");
	}
}

function entryLinkChanged() {
	// TODO -> if value = 0 show url box, else hide url box
	var selectedEntryId = Number($("#entry_link_select").val());
//	alert("select entry id = " + selectedEntryId);
	if(selectedEntryId == 0) {
		$("#external_link_input").css("display", "inline");
		$("#external_link_input").val("http://");
		$(".external_entry_link_input").val("");
	}
	else {
		$("#external_link_input").css("display", "none");
		$(".external_entry_link_input").val("SMEntryLink://" + selectedEntryId);
	}
}

function addEntryLinkSelections() {
	ajaxURL = "?app=" + appNameEncoded + "&action=listentriesAJAX";
	$.getJSON(ajaxURL, function(data) {
		var selectOptions = '<option style="font-style:italic;" value="' + 0 + '">External Website</option>';
        	$.each(data.entries, function(i,entry) {
			selectOptions += '<option value="' + entry.id + '">' + entry.entry_name + '</option>';
		});
		$("#entry_link_select").append(selectOptions);
		setupEntryLinkDialog();
	});
}


function showIconPicker() {
	var thumbsHTML = "";
	$(".thumbimg").each(function() {
		var iconURL = $(this).attr('src').substring(0, $(this).attr('src').length - 6) + '-icon.jpg';
		var photoId = $(this).attr('id').substring(0, $(this).attr('id').length - 4);
		thumbsHTML += '<a style="padding:15px;" href="javascript:{}" onclick=\'selectIcon(' + photoId + ', "' + iconURL + '", true);\'><img width="45" height="45" src="' + iconURL + '"></a>';
	});

//	alert("thumbsHTML = " + thumbsHTML);
	window.scroll(0,0);
	shade(1).prepend('<div style="font-size:.75em; width: 600px; margin-left:auto; margin-right:auto; padding:40px;">' + thumbsHTML + '<p style="color:white;">Select an icon above or <input type="submit" value="cancel" onclick="unshade(1);"/></div><div style="position:absolute; left:' + (pageSize[0] - 80) + 'px; top:15px;"><a href="javascript:{}" onclick=\'unshade(1);\'><img src="graphics/close.png"></a></div>'); 
}

function showAppIconPicker() {
	var pickerDiv = '<div style="font-size:.75em; width: 740px; margin-left:20px; margin-right:auto; margin-top:20px; padding:20px; min-height:711px; background-image:url(graphics/itunes-travel-background.png); background-repeat:no-repeat;">';
	var thumbsHTML = "";
	var leftX = 256;
	var relativeY = 657;
	var relativeX = leftX;
	var xIncrement = 247;
	var yIncrement = 94;
	var photoCount = 0;
	$(".thumbimg").each(function() {
		if(++photoCount > 14) return false;
		var iconURL = $(this).attr('src').substring(0, $(this).attr('src').length - 6) + '-icon.jpg';
		var photoId = $(this).attr('id').substring(0, $(this).attr('id').length - 4);
		pickerDiv += '<div style="position:absolute; left:' + relativeX + 'px;top:' + relativeY + 'px;"><a href="javascript:{}" onclick=\'selectIcon(' + photoId + ', "' + iconURL + '", false);\'><img width="60" height="60" src="' + iconURL + '"></a></div>';
		relativeY = (relativeX == leftX) ? relativeY : relativeY - yIncrement;
		relativeX = (relativeX == leftX) ? relativeX + xIncrement : leftX; 
	});
	pickerDiv += '<p style="margin-right:20px; position:absolute; left:850px; top:100px; color:white;"><- Select (click on) an icon candidate to the left that best<br><br>#1) catches the eye<br><br>and<br><br>#2) positively reflects the content and spirit of your app<br><br>If you have trouble spotting one of your icons, your customers might have trouble too...<br><br><input type="submit" value="cancel" onclick="unshade(1);"/></p></div>';
 
//	alert("thumbsHTML = " + thumbsHTML);
	window.scroll(0,0);
	shade(1).prepend(pickerDiv + '<div style="position:absolute; left:' + (pageSize[0] - 80) + 'px; top:15px;"><a href="javascript:{}" onclick=\'unshade(1);\'><img src="graphics/close.png"></a></div>');


}


function showNoteForm(appId) {
	$("#" + appId + "_app_note_span").css("display", "none");
	$("#" + appId + "_app_note_form").css("display", "inline");
	$("#" + appId + "_app_note_cancel").css("display", "inline");
}

function hideNoteForm(appId) {
	$("#" + appId + "_app_note_span").css("display", "inline");
	$("#" + appId + "_app_note_form").css("display", "none");
	$("#" + appId + "_app_note_cancel").css("display", "none");
}


function showMap(defaultCenterLatitude, defaultCenterLongitude) {
//	alert("showMap() called");
	var arrayPageSize = getPageSize();
//	alert("arrayPageSize = [" + arrayPageSize[0] + ", " + arrayPageSize[1] + ", " + arrayPageSize[2] + ", " + arrayPageSize[3]);
	var mapWidth = arrayPageSize[2] - 15;
	var mapHeight = arrayPageSize[3];
	shade(1).append('<div id="map" style="width:' + mapWidth + 'px; height:' + mapHeight + 'px; "></div><div style="position:absolute; left:' + (pageSize[2] - 80) + 'px; top:35px;"><a href="javascript:{}" onclick=\'unshade(1);\'><img src="graphics/close.png"></a></div>');
	window.scroll(0,0);
	findLocation(Base64.encode(document.getElementById("address").value),document.getElementById("latitude").value, document.getElementById("longitude").value, true, defaultCenterLatitude, defaultCenterLongitude);

}

function selectIcon(photoId, thumbURL, updateOrdering) {
	if(photoId != null) {
		$("#icon_photo_id").val(photoId);
	//	url = thumbURL;
	}

	if(updateOrdering) {
		$("#thumblist").prepend($("#" + photoId).detach());
		var newPhotoIdOrder = new Array();

		$(".thumblink").each(function(index) {
			newPhotoIdOrder.push($(this).attr("id"));
		});	
	
		reorderThumbnails(newPhotoIdOrder);
	}

	iconImageHTML = '<img src="' + thumbURL + '" id="icon_img" width="45" height="45"/>';
//	alert("iconImageHTML = " + iconImageHTML);
	$("#icon_link").empty().append(iconImageHTML);
	unshade(1);
}

function updateThumbListAfterUpload(urlencodedAppName, urlencodedEntryName, urlencodedTimestamp, srcZLevel, uploadTarget) {
	onMarketingPage = (uploadTarget == "app_icon_candidates") ? true : false;
	ajaxURL = "?app=" + urlencodedAppName + "&entry=" + urlencodedEntryName + "&photos_added_since_ajax=" + urlencodedTimestamp + "&upload_target=" + uploadTarget;
//	alert("updateThumbListAfterUpload calling ajax URL " + ajaxURL);
	$.getJSON(ajaxURL,
        	function(data){
			tmpCounter = 0;
          		$.each(data.photos, function(i,photo){
				tmpCounter++;
//alert("adding thumb url_m = " + photo.url_m + ", url_t = " + photo.url_t + ", flickr_photo_id = " + photo.flickr_photo_id + ", photo_id = " + photo.photo_id + ", uploader_name = " + photo.uploader_name + ", photo.largest_width = " + photo.largest_width + ", photo.largest_height = " + photo.largest_height);
				addThumb(urlencodedAppName, photo.url_m, photo.url_t, photo.flickr_photo_id, photo.photo_id, photo.flags, srcZLevel, Base64.encode(photo.uploader_name), Base64.encode(photo.caption), onMarketingPage, photo.largest_width, photo.largest_height, photo.license_id);
				if(onMarketingPage) {
//alert("updateThumbListAfterUpload uploadTarget = " + uploadTarget + ", adding photo_id = " + photo.photo_id + " to appIconCandidatePhotoIds");
					appIconCandidateFlickrPhotoIds.push(Number(photo.flickr_photo_id));
					appIconCandidatePhotoIds.push(Number(photo.photo_id));
				}
          		});
//			alert("tried to add " + tmpCounter + " thumbs");
        	}
	);
}	

function updatePhotographer(urlencodedAppName, flickrPhotoId, photoId, newPhotographerName, onMarketingPage) {
//	alert("updatePhotographer called with urlencodedAppName = " + urlencodedAppName + ", photoId = " + photoId + ", newPhotographerName = " + newPhotographerName);
	encodedNewPhotographerName = isEmpty(newPhotographerName) ? "" : Base64.encode(newPhotographerName);
	ajaxURL = "?app=" + urlencodedAppName + "&photoid=" + photoId + "&newphotographername=" + encodedNewPhotographerName + "&app_icon_candidate=" + onMarketingPage;
//	alert("updateThumbListAfterUpload calling ajax URL " + ajaxURL);
	$("#mutable_photographer").css("display","none");
	$("#license_img").css("display","none");
	$("#waiting_img").css("display","inline");
	$.getJSON(ajaxURL,
        	function(data){
			encodedNewPhotographerNameFromServer = data.encoded_photographer_name;
			newPhotographerNameFromServer = Base64.decode(encodedNewPhotographerNameFromServer);
			rowCount = data.update_count;
//alert("newPhotographerNameFromServer = " + newPhotographerNameFromServer + ", rowCount = " + rowCount);
			$("#" + flickrPhotoId).attr("encoded_mutable_photographer_name", encodedNewPhotographerNameFromServer);
			$("#immutable_photographer_name").text(newPhotographerNameFromServer);
			if(isEmpty(newPhotographerNameFromServer)) $("#immutable_photographer_name").text("<no author shown>");

			$("#immutable_photographer").css("display","inline");
			$("#license_img").css("display","inline");
			$("#waiting_img").css("display","none");
          	}
	);
	return false; // don't continue the form processing
}	

function updateCaption(urlencodedAppName, photoId, newCaptionText) {
//alert("updateCaption(\"" + urlencodedAppName + "\", " + photoId + ", \"" + newCaptionText + "\") called");
	encodedNewCaptionText = isEmpty(newCaptionText) ? "" : Base64.encode(newCaptionText);
//alert("updateCaption() encodedNewCaptionText = " + encodedNewCaptionText);
	ajaxURL = "?app=" + urlencodedAppName + "&photoid=" + photoId + "&newcaptiontext=" + encodedNewCaptionText;

	$("#mutable_caption").css("display","none");
	$("#caption_img").css("display","none");
	$("#waiting_for_caption_update_img").css("display","inline");
	$.getJSON(ajaxURL,
        	function(data){
			encodedCaptionFromServer = data.encoded_caption;

			newCaptionFromServer = Base64.decode(encodedCaptionFromServer);
//alert("updateCaption() encodedCaptionFromServer = " + encodedCaptionFromServer + ", newCaptionFromServer = " + newCaptionFromServer);

			$("#" + photoId).attr("encoded_caption", encodedCaptionFromServer);
			$("#immutable_caption_text").text(newCaptionFromServer);
			if(isEmpty(newCaptionFromServer)) $("#immutable_caption_text").text("<no caption shown>");

			$("#immutable_caption").css("display","inline");
			$("#caption_img").css("display","inline");
			$("#waiting_for_caption_update_img").css("display","none");
          	}
	);
	return false; // don't continue the form processing
}	

function addAppIconCandidate(urlencodedAppName, flickrPhotoId, photoId, onMarketingPage, zLevel) {
	ajaxURL = '?app=' + urlencodedAppName + ((photoId == null) ? '&new_app_icon_candidate_flickr_photo_id=' + flickrPhotoId : '&new_app_icon_candidate_photo_id=' + photoId);
	$("#app_icon_candidate_plus_img").css("display","none");
	$("#app_icon_waiting_img").css("display","inline");
	$.getJSON(ajaxURL,
        	function(photo){
//alert("before adding... appIconCandidatePhotoIds = " + appIconCandidatePhotoIds + ", appIconCandidateFlickrPhotoIds = " + appIconCandidateFlickrPhotoIds);
			$("#app_icon_row").remove();
			flickrPhotoId = Number(photo.flickr_photo_id);
			photoId = Number(photo.photo_id);
			appIconCandidateFlickrPhotoIds.push(flickrPhotoId);
			appIconCandidatePhotoIds.push(photoId);
//alert("after adding... appIconCandidatePhotoIds = " + appIconCandidatePhotoIds + ", appIconCandidateFlickrPhotoIds = " + appIconCandidateFlickrPhotoIds);

			if(onMarketingPage) {
				addThumb(urlencodedAppName, photo.url_m, photo.url_t, flickrPhotoId, photoId, photo.flags, 1, null, true, photo.large_width, photo.large_height, photo.license_id);
				unshade(zLevel);				
			}
          	}
	);
	return false; // don't continue the form processing
}	

function removeAppIconCandidate(urlencodedAppName, photoId, flickrPhotoId, zLevel) {
	ajaxURL = '?app=' + urlencodedAppName + '&remove_app_icon_candidate_photo_id=' + photoId;
	$("#app_icon_candidate_minus_img").css("display","none");
	$("#app_icon_waiting_img").css("display","inline");
	$.getJSON(ajaxURL,
        	function(photo){
//alert("before removing... appIconCandidatePhotoIds = " + appIconCandidatePhotoIds + ", appIconCandidateFlickrPhotoIds = " + appIconCandidateFlickrPhotoIds);

			$("#remove_app_icon_row").remove();
			$("#" + photoId).remove();
			var photoIndex = appIconCandidatePhotoIds.indexOf(photoId);
			appIconCandidatePhotoIds.remove(photoIndex);
			var flickrPhotoIndex = appIconCandidateFlickrPhotoIds.indexOf(flickrPhotoId);
			appIconCandidateFlickrPhotoIds.remove(flickrPhotoIndex);
//alert("after removing... appIconCandidatePhotoIds = " + appIconCandidatePhotoIds + ", appIconCandidateFlickrPhotoIds = " + appIconCandidateFlickrPhotoIds);
			unshade(zLevel);
          	}
	);
	return false; // don't continue the form processing
}	

function updatePhotoList() {
	var photoList = "";
	var counter = 0;
	$(".thumblink").each(function() {
                if(counter++ > 0) photoList += ",";
		photoList += $(this).attr('id');
	});
/*
	photoList += "-";

        counter = 0;
	$(".thumblink").each(function() {
                if(counter++ > 0) photoList += ",";
		photoList += $(this).hasClass('awesome') ? "1" : "0";
	});

//	alert("photoList = " + photoList);

*/
	$("#photolist").val(photoList);

	return true;
}

function arrayToString(arrayToStringify) {
	return "[" + arrayToStringify.join(", ") + "]";
}

function showSimpleImage(photoUrl, clientXOnScreen, clientYOnScreen, zLevel) { //, encodedMutablePhotographer) {
	clientScrollTop = f_scrollTop();
	clientX = clientXOnScreen;
	clientY = clientYOnScreen  + clientScrollTop;

	toShow = new Image();
	toShow.src = photoUrl;

	toShow.onload = function () {
		imageWidth = toShow.width;
		imageHeight = toShow.height;

		var arrayPageSize = getPageSize();
		var arrayPageScroll = getPageScroll();

		var lightboxLeft = clientX - imageWidth/2.;
		var scrollbarWidth = 15;
		if(lightboxLeft < 0) lightboxLeft = 0;
		else if((lightboxLeft + imageWidth + scrollbarWidth) > arrayPageSize[0]) lightboxLeft = arrayPageSize[0] - imageWidth - scrollbarWidth;

		var lightboxTop = clientY - imageHeight/2.;
		if(lightboxTop < clientScrollTop) lightboxTop = clientScrollTop;

		lightboxTop += "px";
		lightboxLeft += "px";

		shade(zLevel).append('<div style="position:absolute; left:' + lightboxLeft + ';top:' + lightboxTop + ';"><a href="javascript:{}" onclick="unshade(' + zLevel + ');"><img src="' + photoUrl + '"></a></div>');
	};
}


function showImage(urlencodedAppName, photoUrl, thumbUrl, photoId, flickrPhotoId, clientXOnScreen, clientYOnScreen, zLevel, onMarketingPage, isCCSearch, largestWidth, largestHeight, licenseId) { //, encodedMutablePhotographer) {
//alert("showImage() called");

	if((photoId === null) && (flickrPhotoId !== null) && $(".thumblink").hasClass("flickr_photo_id_" + flickrPhotoId)) photoId = Number($(".flickr_photo_id_" + flickrPhotoId).attr("id"));

//	mutablePhotographer = (encodedMutablePhotographer == "null") ? "null" : Base64.decode(encodedMutablePhotographer);
	var encodedMutablePhotographer = ($("#" + photoId).length > 0) ? $("#" + photoId).attr("encoded_mutable_photographer_name") : "null";
	var mutablePhotographer = (encodedMutablePhotographer === "null") ? null : Base64.decode(encodedMutablePhotographer);
//alert("encodedMutablePhotographer = " + encodedMutablePhotographer + ", mutablePhotographer = " + mutablePhotographer);
	if(mutablePhotographer === "") mutablePhotographer = "&lt;no author shown&gt;";

//alert("showImage encodedMutablePhotographer = " + encodedMutablePhotographer + ", mutablePhotographer = " + mutablePhotographer + ", (encodedMutablePhotographer == \"null\") = " + (encodedMutablePhotographer == "null") + ", (encodedMutablePhotographer === \"null\") = " + (encodedMutablePhotographer === "null"));

	var encodedCaption = ($("#" + photoId).length > 0) ? $("#" + photoId).attr("encoded_caption") : "null";
//alert("showImage() encodedCaption = " + encodedCaption);
	var caption = (encodedCaption === "null") ? null : Base64.decode(encodedCaption);
	if(caption === "") caption = "&lt;no caption&gt;";

	clientScrollTop = f_scrollTop();
	clientX = clientXOnScreen;
	clientY = clientYOnScreen  + clientScrollTop;

	if(!onMarketingPage) {
//		alert("appIconCandidates = " + appIconCandidates);
//		alert("inArray(" + photoId + " , appIconCandidates) = " + $.inArray(photoId, appIconCandidates));
	}

	toShow = new Image();
//alert("showImage() setting toShow.src = " + photoUrl);
	toShow.src = photoUrl;
//alert("showImage() setting toShow.onload()");

	toShow.onload = function () {
//		alert("toShow onload called.. clientX = " + clientX + ", clientY = " + clientY + ", scroll y pos = " + f_scrollTop());
		imageWidth = toShow.width;
		imageHeight = toShow.height;

		var arrayPageSize = getPageSize();
		var arrayPageScroll = getPageScroll();

		var lightboxLeft = clientX - imageWidth/2.;
		var scrollbarWidth = 15;
		if(lightboxLeft < 0) lightboxLeft = 0;
		else if((lightboxLeft + imageWidth + scrollbarWidth) > arrayPageSize[0]) lightboxLeft = arrayPageSize[0] - imageWidth - scrollbarWidth;

		var lightboxTop = clientY - imageHeight/2.;
		if(lightboxTop < clientScrollTop) lightboxTop = clientScrollTop;

//		alert("clientX = " + clientX + ", clientY = " + clientY + ", imageWidth = " + imageWidth + ", imageHeight = " + imageHeight + ", lightboxLeft = " + lightboxLeft + ", lightboxTop = " + lightboxTop + ", imageWidth = " + imageWidth);

		var imageCurrentlyAdded = $("#" + photoId).length > 0 || (flickrPhotoId !== "null" && $(".thumblink").hasClass("flickr_photo_id_" + flickrPhotoId));
//		alert("showImage() flickrPhotoId = " + flickrPhotoId);

		var turnOffLink = '<a href="javascript:{}" onclick=\'untagImage("' + urlencodedAppName + '", ' + photoId + ', ' + zLevel + ',"' + entryNameEncoded + '");\'>';

		var turnOffRow = '<tr id="untag_image_row" style="' + (imageCurrentlyAdded ? "display:table-row;" : "display:none;") +'"><td style="vertical-align:middle;">' + turnOffLink + '<img id="add_image_icon" src="graphics/remove.png" style="padding:5px;display:block;"/></a></td><td style="vertical-align:middle;">' + turnOffLink + ' Remove From "' + Base64.decode(entryNameEncoded) + '"</a></td></tr>';

		var turnOnLink = '<a href="javascript:{}" onclick=\'tagImage("' + urlencodedAppName + '", "' + photoUrl + '", "' + thumbUrl + '", ' + flickrPhotoId + ', ' + zLevel + ', ' + largestWidth + ', ' + largestHeight + ', ' + licenseId + ', "' + entryNameEncoded + '");\'>';

		var turnOnRow = '<tr id="tag_image_row" style="' + (imageCurrentlyAdded ? "display:none;" : "display:table-row;") +'"><td style="vertical-align:middle;">' + turnOnLink + '<img src="graphics/add.png" style="padding:5px;"/></a></td><td style="vertical-align:middle;">' + turnOnLink + ' Add for "' + Base64.decode(entryNameEncoded) + '"</a></td></tr>';

		var tagRow = onMarketingPage ? "" : turnOffRow + turnOnRow + '<tr id="waiting_for_image_update_row" style="display:none;"><td style="vertical-align:middle;">' + turnOnLink + '<img src="graphics/ajaxload-small.gif" style="padding:5px;"/></a></td><td style="vertical-align:middle;">Updating...</td></tr>';

//alert("tagRow = " + tagRow);

		var removeAwesomeLink = '<a href="javascript:{}" onclick=\'toggleAwesomeFlag("' + urlencodedAppName + '", ' + photoId + ', ' + zLevel + ', "' + entryNameEncoded + '");\'>';

		var removeAwesomeRow = '<tr class="photo_awesomeness_row" id="remove_photo_awesomeness_row" style="display:' + (($("#" + photoId).length > 0) && ($("#" + photoId).hasClass("awesome")) ? "table-row" : "none") + ';"><td style="vertical-align:middle;">' + removeAwesomeLink + '<img src="graphics/remove.png" style="padding:5px;"/>' + removeAwesomeLink + '</td><td style="vertical-align:middle;">' + removeAwesomeLink + ' Remove from top-level slideshow</a></td></tr>';

		var addAwesomeLink = '<a href="javascript:{}" onclick=\'toggleAwesomeFlag("' + urlencodedAppName + '", ' + photoId + ', ' + zLevel + ', "' + entryNameEncoded + '");\'>';
		var addAwesomeRow = '<tr class="photo_awesomeness_row" id="add_photo_awesomeness_row" style="display:' + (($("#" + photoId).length > 0) && !($("#" + photoId).hasClass("awesome")) ? "table-row" : "none") + ';"><td style="vertical-align:middle; "><img src="graphics/add.png" style="padding:5px;"/></td><td style="vertical-align:middle;">' + addAwesomeLink + ' Add to top-level slideshow</a></td></tr>';

		var awesomeRow = onMarketingPage ? "" : removeAwesomeRow + addAwesomeRow + '<tr class="photo_awesomeness_row" id="waiting_for_photo_awesomeness_update_row" style="display:none;"><td style="vertical-align:middle;">' + turnOnLink + '<img src="graphics/ajaxload-small.gif" style="padding:5px;"/></a></td><td style="vertical-align:middle;">Updating...</td></tr>';

//alert("awesomeRow = " + awesomeRow);
//alert("about to generate appIconCandidateRow.. photoId = " + photoId + ", appIconCandidates = " + appIconCandidates + ", isCCSearch = " + isCCSearch + ", onMarketingPage = " + onMarketingPage + ", inArray(photoId,appIconCandidates) returns " + $.inArray(photoId,appIconCandidates));

		var addAppIconCandidateLink = '<a href="javascript:{}" onclick=\'addAppIconCandidate("' + urlencodedAppName + '", ' + flickrPhotoId + ', ' + photoId + ', ' + onMarketingPage + ', ' + zLevel + ');\'>';

//alert('largestWidth = ' + largestWidth + ', largestHeight = ' + largestHeight + ', (($.inArray(photoId, appIconCandidatePhotoIds) < 0) && ($.inArray(flickrPhotoId, appIconCandidateFlickrPhotoIds) < 0) && (licenseId != 6) && (Number(largestWidth) >= 512) && (Number(largestHeight) >= 512)) = ' + ($.inArray(photoId, appIconCandidatePhotoIds) < 0) + ', ' +  ($.inArray(flickrPhotoId, appIconCandidateFlickrPhotoIds) < 0) + ', ' + (licenseId != 6) + ', ' + (Number(largestWidth) >= 512) + ', ' + (Number(largestHeight) >= 512));

		var appIconCandidateRow = (($.inArray(photoId, appIconCandidatePhotoIds) < 0) && ($.inArray(flickrPhotoId, appIconCandidateFlickrPhotoIds) < 0) && (licenseId != 6) && (Number(largestWidth) >= 512) && (Number(largestHeight) >= 512)) ? '<tr id="app_icon_row"><td style="vertical-align:middle; ">' + addAppIconCandidateLink + '<img id="app_icon_candidate_plus_img" src="graphics/add.png" style="padding:5px;"/><img id="app_icon_waiting_img" src="graphics/ajaxload-small.gif" style="padding:5px;display:none;"</a></td><td style="vertical-align:middle;">' + addAppIconCandidateLink + ' Add to app-icon candidates</a></td></tr>' : '';

//		alert("photoId = " + photoId + ", flickrPhotoId = " + flickrPhotoId + ", appIconCandidatePhotoIds = " + appIconCandidatePhotoIds + ", appIconCandidateFlickrPhotoIds = " + appIconCandidateFlickrPhotoIds + ", inArray(photoId, appIconCandidatePhotoIds) = " + $.inArray(photoId, appIconCandidatePhotoIds) + ", inArray(flickrPhotoId, appIconCandidateFlickrPhotoIds) = " + $.inArray(flickrPhotoId, appIconCandidateFlickrPhotoIds));

		var removeAppIconCandidateLink = '<a href="javascript:{}" onclick=\'removeAppIconCandidate("' + urlencodedAppName + '", ' + photoId + ', ' + flickrPhotoId + ', ' + zLevel + ');\'>';

		var removeAppIconCandidateRow = (onMarketingPage && !isCCSearch && (($.inArray(photoId, appIconCandidatePhotoIds) >= 0) || ($.inArray(flickrPhotoId, appIconCandidateFlickrPhotoIds) >= 0))) ? '<tr id="remove_app_icon_row"><td style="vertical-align:middle; ">' + removeAppIconCandidateLink + '<img id="app_icon_candidate_minus_img" src="graphics/remove.png" style="padding:5px;"/><img id="app_icon_waiting_img" src="graphics/ajaxload-small.gif" style="padding:5px;display:none;"></a></td><td style="vertical-align:middle;">' + removeAppIconCandidateLink + ' Remove from app-icon candidates</a></td></tr>' : '';

//alert("appIconCandidatePhotoIds = " + appIconCandidatePhotoIds + ", appIconCandidateFlickrPhotoIds = " + appIconCandidateFlickrPhotoIds);

//		alert("$(#photoId).length  = " + $("#" + photoId).length + ", encodedMutablePhotographer = " + encodedMutablePhotographer + ", mutablePhotographer = " + mutablePhotographer + " isEmpty(mutablePhotographer) = " + isEmpty(mutablePhotographer) + ", licenseId = " + licenseId + ", largestWidth = " + largestWidth + ", largestHeight = " + largestHeight);

		var flickrLinkRow = (mutablePhotographer === null) ? '<tr><td style="vertical-align:middle; text-align:right;"><img src="graphics/flickr.png" style="padding:5px;"></td><td style="vertical-align:middle; text-align:left;"><a target="_blank" href="?gotoflickrpage=' + flickrPhotoId +'">Open flickr page</a></td></tr>' : '<tr><td style="vertical-align:middle text-align:right;"><img id="license_img" src="graphics/symbol4_gray_30x27.png" style="padding:5px;"><img id="waiting_img" src="graphics/ajaxload-small.gif" style="padding:5px;display:none;"></td><td style="vertical-align:middle; text-align:left;"> <span id="immutable_photographer"><span id="immutable_photographer_name">' + mutablePhotographer + '</span> (<a href="javascript:{}" onclick=\'$("#immutable_photographer").css("display", "none"); $("#mutable_photographer").css("display","inline");\'>change</a>)</span><span id="mutable_photographer" style="display:none;"><form style="display:inline;" onsubmit=\'return updatePhotographer("' + urlencodedAppName + '", ' + photoId + ', ' + photoId + ', $("#newphotographername").val(), ' + onMarketingPage + ');\' action=""><input type="text" id="newphotographername" name="newphotographername" size="18" maxlength="128"> (<a href="javascript:{}" onclick=\'$("#immutable_photographer").css("display","inline"); $("#mutable_photographer").css("display","none");\'>cancel</a>) <input type="submit" value="Save"></form></span></td></tr>';

		var captionRow = (($("#" + photoId).length > 0 && !onMarketingPage) ? '<tr><td style="vertical-align:middle text-align:middle;"><img id="caption_img" src="graphics/info.png" style="padding:5px;"/><img id="waiting_for_caption_update_img" src="graphics/ajaxload-small.gif" style="padding:5px;display:none;"></td><td style="vertical-align:middle; text-align:left;"><span id="immutable_caption"> &ldquo;<span id="immutable_caption_text">' + caption + '</span>&rdquo; (<a href="javascript:{}" onclick=\'$("#immutable_caption").css("display", "none"); $("#newcaptiontext").val(Base64.decode($("#' + photoId + '").attr("encoded_caption"))); $("#mutable_caption").css("display","inline");\'>change</a>)</span><span id="mutable_caption" style="display:none;"><form style="display:inline;" onsubmit=\'updateCaption("' + urlencodedAppName + '", ' + photoId + ', $("#newcaptiontext").val()); return false;\' action="">&ldquo;<input type="text" id="newcaptiontext" name="newcaptiontext" size="18" maxlength="80">&rdquo; (<a href="javascript:{}" onclick=\'$("#immutable_caption").css("display","inline"); $("#mutable_caption").css("display","none");\'>cancel</a>) <input type="submit" value="Save"></form></span></td></tr>' : '');

//alert("caption = " + caption + "captionRow = " + captionRow);
//alert("flickrLinkRow = " + flickrLinkRow);
		controlDivWidth = 350;
		controlDivLeft = (Number(lightboxLeft) + Number(imageWidth) + controlDivWidth) < arrayPageSize[0] ? (Number(lightboxLeft) + Number(imageWidth)) : (Number(lightboxLeft) - controlDivWidth);
		controlDivLocation = ' left:' + controlDivLeft + 'px;top:' + lightboxTop + 'px; width:' + controlDivWidth + 'px;';

		var cancelRow = '<tr><td colspan="2" style="vertical-align:middle;"' + (Number(controlDivLeft) > Number(lightboxLeft) ? ' align="left"><img src="graphics/fingergun_left_28x28.png" style="vertical-align:bottom;">&nbsp;click photo when finished&nbsp;' : ' align="right">&nbsp;click photo when finished&nbsp;<img style="vertical-align:bottom;" src="graphics/fingergun_right_28x28.png">') + '</td></tr>';

		controlDiv = '<div id="onControlDiv" style="background-color: #dde; position:absolute; text-align:left; font-size: .75em;' + controlDivLocation + '"><table style="padding:.3em;">' + captionRow + flickrLinkRow + tagRow + awesomeRow + appIconCandidateRow + removeAppIconCandidateRow + cancelRow + '</table></div>';

//alert("controlDiv = " + controlDiv); 
		lightboxTop += "px";
		lightboxLeft += "px";
//alert("calling shade..");
		shade(zLevel).append('<div style="position:absolute; left:' + lightboxLeft + ';top:' + lightboxTop + ';"><a href="javascript:{}" onclick="unshade(' + zLevel + ');"><img src="' + photoUrl + '"></a></div>').append(controlDiv);

//alert("showImage() onload completing...")
	};
}

function showHelp(photoUrl, xOffset, yOffset, clientXOnScreen, clientYOnScreen, zLevel) {
	clientScrollTop = f_scrollTop();
	clientX = clientXOnScreen;
	clientY = clientYOnScreen  + clientScrollTop;

	toShow = new Image();
	toShow.src = photoUrl;

	toShow.onload = function () {
//		alert("toShow onload called.. clientX = " + clientX + ", clientY = " + clientY + ", scroll y pos = " + f_scrollTop());
		imageWidth = toShow.width;
		imageHeight = toShow.height;

		var arrayPageSize = getPageSize();
		var arrayPageScroll = getPageScroll();

		var lightboxLeft = clientX + xOffset;
		var scrollbarWidth = 15;
//		if(lightboxLeft < 0) lightboxLeft = 0;
//		else if((lightboxLeft + imageWidth + scrollbarWidth) > arrayPageSize[0]) lightboxLeft = arrayPageSize[0] - imageWidth - scrollbarWidth;

		var lightboxTop = clientY + yOffset;
//		if(lightboxTop < clientScrollTop) lightboxTop = clientScrollTop;

//	alert("clientX = " + clientX + ", clientY = " + clientY + ", imageWidth = " + imageWidth + ", imageHeight = " + imageHeight + ", lightboxLeft = " + lightboxLeft + ", lightboxTop = " + lightboxTop + ", imageWidth = " + imageWidth);

		lightboxTop += "px";
		lightboxLeft += "px";
		popup(zLevel).append('<div style="position:absolute; left:' + lightboxLeft + ';top:' + lightboxTop + ';"><a href="javascript:{}" onclick="unshade(' + zLevel + ');"><img src="' + photoUrl + '"></a></div>');
	};
}

function var_dump(obj) {
   if(typeof obj == "object") {
      return "Type: "+typeof(obj)+((obj.constructor) ? "\nConstructor: "+obj.constructor : "")+"\nValue: " + obj;
   } else {
      return "Type: "+typeof(obj)+"\nValue: "+obj;
   }
}//end function var_dump

function addThumb(urlencodedAppName, photoUrl, thumbUrl, flickrPhotoId, photoId, flags, srcZLevel, encodedMutablePhotographer, encodedCaption, onMarketingPage, largestWidth, largestHeight, licenseId) {
	var awesomeClass = (parseInt(flags) % 2 == 1) ? " awesome" : "";
	var newThumbLink = '<a class="entry thumblink' + awesomeClass + ((flickrPhotoId === null) ? '' : ' flickr_photo_id_' + flickrPhotoId) + '" encoded_mutable_photographer_name="' + encodedMutablePhotographer + '" encoded_caption="' + encodedCaption + '" id="' + photoId + '" href="javascript:{}" onclick=\'showImage("' + urlencodedAppName + '", "' + photoUrl + '", "' + thumbUrl + '", ' + photoId + ', ' + flickrPhotoId + ', event.clientX, event.clientY, ' + srcZLevel + ', ' + onMarketingPage + ', false, ' + largestWidth + ', ' + largestHeight + ', ' + licenseId + ');\'><img id="' + photoId + '_img" class="thumbimg" src="' + thumbUrl + '"></a>';

//alert("addThumb() newThumbLink = " + newThumbLink);

//	alert("#" + photoId + ".length = " + $("#" + photoId).length);

	if(onMarketingPage) {
		if($('#' + photoId).length == 0) $("#thumblist").append(newThumbLink);
	}

	else {
		if($('#' + photoId).length == 0) $("#photo_reordering_link").before(newThumbLink);
		if($('.thumblink').size() > 1) $("#photo_reordering_link").css("display","block");
	}
}

function tagImage(urlencodedAppName, photoUrl, thumbUrl, flickrPhotoId, srcZLevel, largestWidth, largestHeight, licenseId, entryNameEncoded) {
	ajaxURL = "?ajax=true&app=" + urlencodedAppName + "&flickrphotoid=" + flickrPhotoId + "&addphotoforentry=" + encodeURIComponent(entryNameEncoded);
	$("#tag_image_row").css("display","none");
	$("#waiting_for_image_update_row").css("display","table-row");

	$.getJSON(ajaxURL,
        	function(data){
			sutroPhotoId = data.sutro_photo_id;
			if(sutroPhotoId < 0) {
				alert ("Failed to save the selected photo");
				$("#waiting_for_image_update_row").css("display","none");
				$("#tag_image_row").css("display","table-row");
			}
			else {
				$("#waiting_for_image_update_row").css("display","none");
				$("#untag_image_row").css("display","table-row");
		
//alert("addThumb() called wtih flickrPhotoId = " + flickrPhotoId + ", photoId = " + sutroPhotoId);
				addThumb(urlencodedAppName, data.sutro_photo_url, data.sutro_thumb_url, flickrPhotoId, sutroPhotoId, 1, srcZLevel, null, "", false, largestWidth, largestHeight, licenseId);
				unshade(srcZLevel);
			}
          	}
	);
	return false; // don't continue the form processing
}

function untagImage(urlencodedAppName, photoId, srcZLevel, entryNameEncoded) {
	ajaxURL = "?ajax=true&app=" + urlencodedAppName + "&photoid=" + photoId + "&removephotofromentry=" + encodeURIComponent(entryNameEncoded);
	$("#untag_image_row").css("display","none");
	$("#waiting_for_image_update_row").css("display","table-row");

	$.getJSON(ajaxURL,
        	function(data){
			succeeded = data.succeeded;
//alert("untagImage.. succeeded = " + succeeded);
			if(succeeded < 0) {
				alert ("Failed to remove the selected photo");
				$("#waiting_for_image_update_row").css("display","none");
				$("#untag_image_row").css("display","table-row");
			}
			else {
				$("#waiting_for_image_update_row").css("display","none");
				$("#tag_image_row").css("display","table-row");
				$("#" + photoId).remove();
				if($('.thumblink').size() < 2) $("#photo_reordering_link").css("display","none");
				unshade(srcZLevel);
			}
          	}
	);
	return false; // don't continue the form processing
}

function toggleAwesomeFlag(urlencodedAppName, photoId, srcZLevel, entryNameEncoded) {
	newFlagValue = Number($("#" + photoId).hasClass("awesome") ? 0 : 1);
//alert("toggling photo flag to " + newFlagValue);
	ajaxURL = "?ajax=true&app=" + urlencodedAppName + "&photoid=" + photoId + "&updatephotoflagsforentry=" + encodeURIComponent(entryNameEncoded) + "&new_flag_value=" + newFlagValue;

	$(".photo_awesomeness_row").css("display","none");
	$("#waiting_for_photo_awesomeness_update_row").css("display","table-row");

	$.getJSON(ajaxURL,
        	function(data){
			actualFlagValue = Number(data.new_flag_value);
//alert("untagImage.. succeeded = " + succeeded);
			if(actualFlagValue < 0) {
				alert ("Failed to update the top-level slideshow");
				$("#waiting_for_flags_update_row").css("display","none");
				$("#untag_image_row").css("display","table-row");
			}
			else {
				$("#waiting_for_photo_awesomeness_update_row").css("display","none");
				if(actualFlagValue) $("#remove_photo_awesomeness_row").css("display","table-row");
				else $("#add_photo_awesomeness_row").css("display","table-row");
				$("#" + photoId).toggleClass("awesome");
//				unshade(srcZLevel);
			}
          	}
	);
	return false; // don't continue the form processing
}

function spacesToCommas(src) {
	return src.replace(/ /g, ',').replace(/,+/g, ',');
}

function showItunesText(srcZLevel) {
	window.scroll(0,0);
	var tagLineText = $("#app_tagline").val();
	var tagLine = isEmpty(tagLineText) ? "" : "★ " + tagLineText + " ★\n\n";

	var aboutTheAuthorHeader = $("#author_name").text().search(/ and /) == -1 ? "★ About the Author ★" : "★ About the Authors ★";

	shade(srcZLevel).append('<div style="position:absolute; left:' + (pageSize[0] - 80) + 'px; top:15px;"><a href="javascript:{}" onclick=\'unshade(1);\'><img src="graphics/close.png"></a></div><div style="width: 900px; margin-left:auto; margin-right:auto; margin-top:50px; color:white; font-size:.5em;"><p>' + $("#name").val() + '</p><hr><p><textarea rows=40 cols=100 readonly>\n\n' + tagLine + $("#store_text").val().replace(/\n+$/, '') + '\n\n\n' + aboutTheAuthorHeader + '\n\n' + $("#about_author").val().replace(/\n+$/, '') + '\n\n\n★ About Sutro Media ★\n\nThis guide is published in partnership with Sutro Media. By enabling local writers to share their expertise on mobile phones, Sutro Media is making it easier and more fun to explore the world!\n\nIf you have any problems, comments, or suggestions for improvement, we\'d love to hear from you - letusknow@sutromedia.com\n\n</textarea></p><hr><p>' + spacesToCommas($("#keywords").val()) + '</p></div>');
}

function showPhotoReorderingPage(urlencodedAppName, urlencodedEntryName) {

	var pageSize = getPageSize();

	shade(1).append('<div style="position:absolute; left:' + (pageSize[0] - 80) + 'px; top:15px;"><a href="javascript:{}" onclick=\'unshade(1);\'><img src="graphics/close.png"></a></div>');

	var rowSize = 120;
	var outsidePadding = 50;

	var columnsPerRow = Math.floor((pageSize[0] - (2 * outsidePadding)) / rowSize);
	var rows = Math.floor((pageSize[3] - (2 * outsidePadding))/rowSize) - 1;

	var htmlToAdd = '';
	var photoCount = 0;
	$(".thumblink").each(function(index) {
		photoCount++;
		var photoId = $(this).attr("id");
		var thumbSrc = $("#" + photoId + "_img").attr("src");
		htmlToAdd += '<li><img class="resorted_thumbnail" photo_id="' + photoId + '" src="' + thumbSrc + '"></li>';
	});	

//	alert("showPhotoReorderingPage() htmlToAdd = " + htmlToAdd);
	htmlToAdd = '<div style="font-size:.75em; color:#888; width: ' + (columnsPerRow * 120) + 'px; margin-left:auto; margin-right:auto; padding:40px;"><table><tr><td><ul id="sortable">' + htmlToAdd + '</ul></td></tr><tr><td>&nbsp;</td></tr><tr><td align="center"><form onsubmit="return false;" name="revise_search" action="donotexecute" style="display:inline;"><input type="submit" value="Save" onclick=\'savePhotoOrdering("' + urlencodedAppName + '", "' + urlencodedEntryName + '"); return false;\'></form>&nbsp;&nbsp;(<a href="javascript:{}" onclick="unshade(1);">cancel</a>)</td></tr></table></div>';

// <td>' + leftArrow + '</td><td colspan="' + (columnsPerRow - 2) + '" style="color:#888;vertical-align:top; text-align:center;"><p style="padding:10px; line-height:1px;">' + resultsString + '</p><p><form onsubmit="return false;" name="revise_search" action="donotexecute" style="display:inline;">Revise Search: <input type="text" id="new_search_string" value="' + entryName + '"> <input type="submit" value="go" onclick=\'showCCSearchPage("' + urlencodedAppName + '", Base64.encode($("#new_search_string").attr("value")), 1, event, ' + onMarketingPage + '); return false;\'>';


	shade(1).prepend(htmlToAdd + '<div style="position:absolute; left:' + (pageSize[0] - 80) + 'px; top:15px;"><a href="javascript:{}" onclick=\'unshade(1);\'><img src="graphics/close.png"></a></div>');

        $("#sortable").sortable();
        $("#sortable").disableSelection();

//        var reorderingHTML = '<div style="position:absolute; left:' + (pageSize[0] - 80) + 'px; top:15px;"><a href="javascript:{}" onclick=\'unshade(1);\'><img src="graphics/close.png"></a></div>';
	var reorderingHTML = '';
	$(".thumblink").each(function(index) {
        	if(index > 0) reorderingHTML += ", ";
		reorderingHTML += index + " : " + $(this).attr("id");
	});

//	shade(1).append(reorderingHTML);
//	alert("showPhotoReorderingPage() called reorderingHTML = " + reorderingHTML);
}

function showUploadPage(urlencodedAppName, urlencodedEntryName, urlencodedTimestamp, uploadTarget) {
//	alert("showUploadPage called() with uploadTarget = " + uploadTarget);
	window.scroll(0,0);
	var minDimension = ((uploadTarget == "app_icon_candidates") || (uploadTarget == "actual_app_icon")) ? '<param name="uc_minimumImageDimension" value="512x512"/>' : (uploadTarget == "splash_screen") ? '<param name="uc_minimumImageDimension" value="960x1440"/>' : '<param name="uc_minimumImageDimension" value="151x100"/>';

	var maxDimension = (uploadTarget == "actual_app_icon") ? '<param name="uc_maximumImageDimension" value="512x512"/>' : (uploadTarget == "splash_screen") ? '<param name="uc_maximumImageDimension" value="960x1440"/>' : '';

	var mimeType = ((uploadTarget == "actual_app_icon") || (uploadTarget == "splash_screen")) ? "image/png" : "(image/png|image/jpeg)";

	var mimeTypeClause = '<param name="uc_mimeTypePattern" value="' + mimeType + '"/>';


	var PageSize = getPageSize();
	shade(3).append('<div style="width: 715px; margin-left:auto; margin-right:auto; margin-top:50px;"><applet id="jumpLoaderApplet" name="jumpLoaderApplet" code="jmaster.jumploader.app.JumpLoaderApplet.class" archive="jumploader_z.jar" width="715" height="500" mayscript>' +
    			'<param name="uc_imageEditorEnabled" value="true"/>' + 
			'<param name="uc_uploadUrl" value="?app=' + urlencodedAppName + '&uploadforentry=' + urlencodedEntryName + '&upload_target=' + uploadTarget + '"/>' + 
			minDimension +
			maxDimension +
			mimeTypeClause +
			'<param name="uc_maxFileLength" value="5000000"/>' + 
			'<param name="ic_respectExifOrientation" value="true"/>' + 
			'</applet></div><div style="position:absolute; left:' + (pageSize[0] - 80) + 'px; top:15px;"><a href="javascript:{}" onclick=\'updateThumbListAfterUpload("' + urlencodedAppName + '", "' + urlencodedEntryName + '", "' + urlencodedTimestamp + '", 1, "' + uploadTarget + '");unshade(3);\'><img src="graphics/close.png"></a></div>');
}

function showCCSearchPage(urlencodedAppName, encodedEntryName, pageNumber, event, onMarketingPage) {
	var entryName = Base64.decode(encodedEntryName);
//alert("entryName = " + entryName + ", encodedEntryName = " + encodedEntryName + ', pageNumber = ' + pageNumber);

	var pageSize = getPageSize();

	shade(1).append('<div style="position:absolute; left:' + (pageSize[0] - 80) + 'px; top:15px;"><a href="javascript:{}" onclick=\'unshade(1);\'><img src="graphics/close.png"></a></div>');


//	alert("pageSize = " + pageSize[0] + ", " + pageSize[1] + ", " + pageSize[2] + ", " + pageSize[3]);
	var rowSize = 120;
	var outsidePadding = 50;

	var columnsPerRow = Math.floor((pageSize[0] - (2 * outsidePadding)) / rowSize);
	var rows = Math.floor((pageSize[3] - (2 * outsidePadding))/rowSize) - 1;

	ajaxURL = "?photo_search_term_ajax=" + encodedEntryName + "&photos_per_page=" + (columnsPerRow * rows) + "&page_number=" + pageNumber + "&only_app_icon_candidates=" + onMarketingPage;
//	alert("showCCSearchPage calling ajax url = " + ajaxURL);
	$.getJSON(ajaxURL, 
        	function(data){
			var htmlToAdd = "";
			var photoCount = 0;
          		$.each(data.photos, function(i,photo){
				photoCount++;
				if(i % columnsPerRow == 0) htmlToAdd += "<tr>";

				htmlToAdd += "<td id=\"" + photo.id + "_td" + "\" style=\"min-width:" + rowSize + "px;\"><a href=\"javascript:{}\" onclick='showImage(\"" + urlencodedAppName + "\", \"" + photo.url_m + "\", \"" + photo.url_t + "\", null, " + photo.id + ", event.clientX, event.clientY, 2, " + onMarketingPage + ", true, " + photo.o_width + ", " + photo.o_height + ", " + photo.license_id + ");'><img src=\"" + photo.url_t + "\"/></a></td>";
				if(i % columnsPerRow == (columnsPerRow - 1)) htmlToAdd += "</tr>";
          		});

//			alert("data.total = " + data.total + ", photoCount = " + photoCount + ", encodedEntryName = " + encodedEntryName);
			leftArrow = ((data.total == 0) || (pageNumber == 1)) ? "&nbsp;" : '<a href="javascript:{}" onclick=\'showCCSearchPage("' + urlencodedAppName + '", "' + encodedEntryName + '", ' + (Number(pageNumber) - 1) + ', event, ' + onMarketingPage + ');\'><img src="graphics/arrow-left.png"></a>';
			rightArrow = ((pageNumber * (columnsPerRow * rows)) >= data.total) ? "&nbsp;" : '<a href="javascript:{}" onclick=\'showCCSearchPage("' + urlencodedAppName + '", "' + encodedEntryName + '", ' + (Number(pageNumber) + 1) + ', event, ' + onMarketingPage + ');\'><img src="graphics/arrow.png"></a>';
			totalPages = Math.ceil(parseFloat(data.total) / (columnsPerRow * rows));

			resultsString = (data.total == 0) ? 'No Creative Commons photos found for "' + entryName + '"' : 'Creative Commons photos found for "' + entryName + '" (page ' + pageNumber + ' of ' + totalPages + ')';

			htmlToAdd = '<div style="font-size:.75em; width: ' + (columnsPerRow * 120) + 'px; margin-left:auto; margin-right:auto; padding:40px;"><table class="thumb_table">' + htmlToAdd + '<tr><td>' + leftArrow + '</td><td colspan="' + (columnsPerRow - 2) + '" style="color:#888;vertical-align:top; text-align:center;"><p style="padding:10px; line-height:1px;">' + resultsString + '</p><p><form onsubmit="return false;" name="revise_search" action="donotexecute" style="display:inline;">Revise Search: <input type="text" id="new_search_string" value="' + entryName + '"> <input type="submit" value="go" onclick=\'showCCSearchPage("' + urlencodedAppName + '", Base64.encode($("#new_search_string").attr("value")), 1, event, ' + onMarketingPage + '); return false;\'>';

			if(totalPages > 1) {
				htmlToAdd += '&nbsp;&nbsp;&nbsp;Jump to Page:<select id="page_jumper" name="page_jumper" onchange=\'showCCSearchPage("' + urlencodedAppName + '", "' + encodedEntryName + '", $("#page_jumper option:selected").val(), event, ' + onMarketingPage + '); return false;\'>';

				for(i = 1; i <= totalPages; i++) htmlToAdd += '<option ' + (pageNumber == i ? 'SELECTED ' : '') + 'value="' + i + '">' + i + '</option>';
				htmlToAdd += '</select>';
			}
			htmlToAdd += '</form></p></td><td>' + rightArrow + '</td></tr></table></div>';

//			alert("htmlToAdd = " + htmlToAdd);
			shade(1).prepend(htmlToAdd + '<div style="position:absolute; left:' + (pageSize[0] - 80) + 'px; top:15px;"><a href="javascript:{}" onclick=\'unshade(1);\'><img src="graphics/close.png"></a></div>');
        	}
	);

}	

//
// getPageSize()
// Returns array with page width, height and window width, height
// Core code from - quirksmode.org
// Edit for Firefox by pHaez
//
function getPageSize(){
	
	var xScroll, yScroll;
	
	if (window.innerHeight && window.scrollMaxY) {	
		xScroll = document.body.scrollWidth;
		yScroll = window.innerHeight + window.scrollMaxY;
	} else if (document.body.scrollHeight > document.body.offsetHeight){ // all but Explorer Mac
		xScroll = document.body.scrollWidth;
		yScroll = document.body.scrollHeight;
	} else { // Explorer Mac...would also work in Explorer 6 Strict, Mozilla and Safari
		xScroll = document.body.offsetWidth;
		yScroll = document.body.offsetHeight;
	}
	
	var windowWidth, windowHeight;
	if (self.innerHeight) {	// all except Explorer
		windowWidth = self.innerWidth;
		windowHeight = self.innerHeight;
	} else if (document.documentElement && document.documentElement.clientHeight) { // Explorer 6 Strict Mode
		windowWidth = document.documentElement.clientWidth;
		windowHeight = document.documentElement.clientHeight;
	} else if (document.body) { // other Explorers
		windowWidth = document.body.clientWidth;
		windowHeight = document.body.clientHeight;
	}	
	
	// for small pages with total height less then height of the viewport
	if(yScroll < windowHeight){
		pageHeight = windowHeight;
	} else { 
		pageHeight = yScroll;
	}

	// for small pages with total width less then width of the viewport
	if(xScroll < windowWidth){	
		pageWidth = windowWidth;
	} else {
		pageWidth = xScroll;
	}


	arrayPageSize = new Array(pageWidth,pageHeight,windowWidth,windowHeight) 
	return arrayPageSize;
}


function unshade(zLevel) {
//	alert("unshade called for zLevel = " + zLevel);
	return parseInt(zLevel) == 3 ? 
		$("#shade_" + zLevel).css("display","none") :
		$("#shade_" + zLevel).css("display","none").empty();
}

function shade(zLevel) { 
	return popup(zLevel, true); 
}

function popup(zLevel, shadeOn) {
//	alert("shaded called for zLevel = " + zLevel);
	pageSize = getPageSize();
	$("#shade_" + zLevel).empty();
	backgroundImageValue = shadeOn ? "url(graphics/95black.png)" : "none";
	return $("#shade_" + zLevel).css("top","0px").css("left","0px").css("width","100%").css("height", pageSize[1] + "px").css("display", "block").css("background-image", backgroundImageValue);
}


function removeFilter(filterName) {
//	alert("removeFilter called with " + filterName);
	var list = $("#currentfilterlist");
	var list = document.getElementById("currentfilterlist");
	$("currentfilterlist").innerHTML = $("currentfilterlist").innerHTML.substring(0,4);
}

function addFilter(filterName) {
}

function getClientHeight(element) {
  return(element.clientHeight == undefined) ? element.documentElement.clientHeight : element.clientHeight;
}

/**
*
*  Base64 encode / decode
*  http://www.webtoolkit.info/
*
**/
 
var Base64 = {
 
	// private property
	_keyStr : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
 
	// public method for encoding
	encode : function (input) {
		var output = "";
		var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
		var i = 0;
 
		input = Base64._utf8_encode(input);
 
		while (i < input.length) {
 
			chr1 = input.charCodeAt(i++);
			chr2 = input.charCodeAt(i++);
			chr3 = input.charCodeAt(i++);
 
			enc1 = chr1 >> 2;
			enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
			enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
			enc4 = chr3 & 63;
 
			if (isNaN(chr2)) {
				enc3 = enc4 = 64;
			} else if (isNaN(chr3)) {
				enc4 = 64;
			}
 
			output = output +
			this._keyStr.charAt(enc1) + this._keyStr.charAt(enc2) +
			this._keyStr.charAt(enc3) + this._keyStr.charAt(enc4);
 
		}
 
		return output;
	},
 
	// public method for decoding
	decode : function (input) {
		var output = "";
		var chr1, chr2, chr3;
		var enc1, enc2, enc3, enc4;
		var i = 0;
 
		input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
 
		while (i < input.length) {
 
			enc1 = this._keyStr.indexOf(input.charAt(i++));
			enc2 = this._keyStr.indexOf(input.charAt(i++));
			enc3 = this._keyStr.indexOf(input.charAt(i++));
			enc4 = this._keyStr.indexOf(input.charAt(i++));
 
			chr1 = (enc1 << 2) | (enc2 >> 4);
			chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
			chr3 = ((enc3 & 3) << 6) | enc4;
 
			output = output + String.fromCharCode(chr1);
 
			if (enc3 != 64) {
				output = output + String.fromCharCode(chr2);
			}
			if (enc4 != 64) {
				output = output + String.fromCharCode(chr3);
			}
 
		}
 
		output = Base64._utf8_decode(output);
 
		return output;
 
	},
 
	// private method for UTF-8 encoding
	_utf8_encode : function (string) {
		string = string.replace(/\r\n/g,"\n");
		var utftext = "";
 
		for (var n = 0; n < string.length; n++) {
 
			var c = string.charCodeAt(n);
 
			if (c < 128) {
				utftext += String.fromCharCode(c);
			}
			else if((c > 127) && (c < 2048)) {
				utftext += String.fromCharCode((c >> 6) | 192);
				utftext += String.fromCharCode((c & 63) | 128);
			}
			else {
				utftext += String.fromCharCode((c >> 12) | 224);
				utftext += String.fromCharCode(((c >> 6) & 63) | 128);
				utftext += String.fromCharCode((c & 63) | 128);
			}
 
		}
 
		return utftext;
	},
 
	// private method for UTF-8 decoding
	_utf8_decode : function (utftext) {
		var string = "";
		var i = 0;
		var c = c1 = c2 = 0;
 
		while ( i < utftext.length ) {
 
			c = utftext.charCodeAt(i);
 
			if (c < 128) {
				string += String.fromCharCode(c);
				i++;
			}
			else if((c > 191) && (c < 224)) {
				c2 = utftext.charCodeAt(i+1);
				string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
				i += 2;
			}
			else {
				c2 = utftext.charCodeAt(i+1);
				c3 = utftext.charCodeAt(i+2);
				string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
				i += 3;
			}
 
		}
 
		return string;
	}
 
}

function f_clientWidth() {
	return f_filterResults (
		window.innerWidth ? window.innerWidth : 0,
		document.documentElement ? document.documentElement.clientWidth : 0,
		document.body ? document.body.clientWidth : 0
	);
}
function f_clientHeight() {
	return f_filterResults (
		window.innerHeight ? window.innerHeight : 0,
		document.documentElement ? document.documentElement.clientHeight : 0,
		document.body ? document.body.clientHeight : 0
	);
}
function f_scrollLeft() {
	return f_filterResults (
		window.pageXOffset ? window.pageXOffset : 0,
		document.documentElement ? document.documentElement.scrollLeft : 0,
		document.body ? document.body.scrollLeft : 0
	);
}
function f_scrollTop() {
	return f_filterResults (
		window.pageYOffset ? window.pageYOffset : 0,
		document.documentElement ? document.documentElement.scrollTop : 0,
		document.body ? document.body.scrollTop : 0
	);
}
function f_filterResults(n_win, n_docel, n_body) {
	var n_result = n_win ? n_win : 0;
	if (n_docel && (!n_result || (n_result > n_docel)))
		n_result = n_docel;
	return n_body && (!n_result || (n_result > n_body)) ? n_body : n_result;
}

function isEmpty (mixed_var) {
    
    var key;
    
    if (mixed_var === "" ||
        mixed_var === 0 ||
        mixed_var === "0" ||
        mixed_var === null ||
        mixed_var === false ||
        mixed_var === undefined
    ){
        return true;
    }
 
    if (typeof mixed_var == 'object') {
        for (key in mixed_var) {
            return false;
        }
        return true;
    }
 
    return false;
}

function validateEmail(elementValue){      
	var emailPattern = /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/;
	return emailPattern.test(elementValue); 
}

//
// getPageScroll()
// Returns array with x,y page scroll values.
// Core code from - quirksmode.org
//
function getPageScroll(){

	var yScroll;

	if (self.pageYOffset) {
		yScroll = self.pageYOffset;
	} else if (document.documentElement && document.documentElement.scrollTop){	 // Explorer 6 Strict
		yScroll = document.documentElement.scrollTop;
	} else if (document.body) {// all other Explorers
		yScroll = document.body.scrollTop;
	}

	arrayPageScroll = new Array('',yScroll) 
	return arrayPageScroll;
}



//
// getPageSize()
// Returns array with page width, height and window width, height
// Core code from - quirksmode.org
// Edit for Firefox by pHaez
//
function getPageSize(){
	
	var xScroll, yScroll;
	
	if (window.innerHeight && window.scrollMaxY) {	
		xScroll = document.body.scrollWidth;
		yScroll = window.innerHeight + window.scrollMaxY;
	} else if (document.body.scrollHeight > document.body.offsetHeight){ // all but Explorer Mac
		xScroll = document.body.scrollWidth;
		yScroll = document.body.scrollHeight;
	} else { // Explorer Mac...would also work in Explorer 6 Strict, Mozilla and Safari
		xScroll = document.body.offsetWidth;
		yScroll = document.body.offsetHeight;
	}
	
	var windowWidth, windowHeight;
	if (self.innerHeight) {	// all except Explorer
		windowWidth = self.innerWidth;
		windowHeight = self.innerHeight;
	} else if (document.documentElement && document.documentElement.clientHeight) { // Explorer 6 Strict Mode
		windowWidth = document.documentElement.clientWidth;
		windowHeight = document.documentElement.clientHeight;
	} else if (document.body) { // other Explorers
		windowWidth = document.body.clientWidth;
		windowHeight = document.body.clientHeight;
	}	
	
	// for small pages with total height less then height of the viewport
	if(yScroll < windowHeight){
		pageHeight = windowHeight;
	} else { 
		pageHeight = yScroll;
	}

	// for small pages with total width less then width of the viewport
	if(xScroll < windowWidth){	
		pageWidth = windowWidth;
	} else {
		pageWidth = xScroll;
	}


	arrayPageSize = new Array(pageWidth,pageHeight,windowWidth,windowHeight) 
	return arrayPageSize;
}