function makeCommaSeparatedString(arr) {
	var ret = "";
	for (var i=0; arr!=null && i<arr.length; i++) {
		if (i > 0) {
			ret += ",";
		}
		ret += arr[i];
	}
	return ret;
}
function comparePerformancesByTime(performanceA, performanceB) {
	var startA = performanceA.start * 1;
	var startB = performanceB.start * 1;
	if (startA > startB) return 1;
	if (startB > startA) return -1;
	// Performances are at the same time.
	// doesn't really matter which one we return,
	// but keep it consistent
	if (performanceA.id > performanceB.id) return 1;
	return -1;
}
function makePerformanceTimeText(performance, format) {
	if (typeof(format) == "undefined") {
		format = "h:mm";
	}
	var startDate = newDate(performance.startTime);
	var endDate = startDate.clone().addMinutes(performance.durationInMinutes);
	return startDate.toString(format) + " - " + endDate.toString(format);
}
function newDate(startTime) {
	return Date.parseExact(startTime, "yyyy-MM-dd HH:mm:ss");
}
function compareEntriesByTime(entryA, entryB) {
	return comparePerformancesByTime(performanceMap[entryA.performanceId], performanceMap[entryB.performanceId]);
}
function renderPerformances(performances, container, dayTemplate, entryTemplate, attendingCallback) {
	performances.sort(comparePerformancesByTime);
	var prevDate = null;
	var entriesContainer = null;
	for (var i=0; i<performances.length; i++) {
		var performance = performances[i];
		var thisDate = newDate(performance.startTime);
		// because the start times run from 12 noon to 4 am,
		// and we want to consider those all part of the same "day",
		// the simplest thing to do is subtract 11 hours.
		thisDate.addHours(-11);
		var newDay = false;
		if (prevDate == null) {
			newDay = true;
		} else {
			newDay = prevDate.getDate() != thisDate.getDate();
		}
		prevDate = thisDate;
		if (newDay) {
			var dayContainer = dayTemplate.clone().removeAttr("id");
			$(".dayLabel", dayContainer).text(thisDate.toString("dddd MMMM dS, yyyy"));
			container.append(dayContainer);
			dayContainer.show();
			entriesContainer = $(".entriesContainer", dayContainer);
		}
		var entryDiv = entryTemplate.clone();
		entryDiv.removeAttr("id");
		var performer = performerMap[performance.performerId];
		var venue = venueMap[performance.venueId];
		$(".performerName", entryDiv).text(performer.name);
		$(".venueName", entryDiv).text(venue.name);
		$(".performanceTime", entryDiv).text(makePerformanceTimeText(performance, "h:mm tt"));
		entriesContainer.append(entryDiv);
		if (typeof(attendingCallback) != "undefined" && attendingCallback != null) {
			var attending = attendingCallback(performance.id);
			if (attending) {
				entryDiv.addClass("selected");
			} else {
				entryDiv.addClass("unselected");
			}
		}
		entryDiv.data("performance", performance);
		entryDiv.show();
	}
}

function renderSchedule(scheduleEntries, container, dayTemplate, entryTemplate, attendingCallback) {
	var performances = [];
	for (var i=0; i<scheduleEntries.length; i++) {
		var performance = performanceMap[scheduleEntries[i].performanceId];
		performances.push(performance);
	}
	renderPerformances(performances, container, dayTemplate, entryTemplate, attendingCallback);
}

function setStatusWithPrompt(status) {
	var hasPermission = FB.Facebook.apiClient.users_hasAppPermission("status_update", function(result) {
		FB.Debug.dump(result, 'Status Permission');
		if (result == null || !result) {
			FB.Connect.showPermissionDialog('status_update', function(allow) {
				onAllowStatus(allow, status);
			});
		} else {
			// we have the permission, go ahead and set.
			onAllowStatus(true, status);
		}
	});
	FB.Debug.writeLine("has status permission = " + hasPermission);
}

function onAllowStatus(allow, status) {
	if (allow) {
		var r = FB.Facebook.apiClient.users_setStatus(status, false, true, function(result) {
			FB.Debug.dump(result, 'Status reply');
			if (result) {
				alertDialog('Status set', 'Your status has been set');
			}
		});
		FB.Debug.dump(r, "status r");
	}
}
function popupInviteFriends(actionUrl, currentFriendIds) {
	var fbmlContent = "<fb:fbml><fb:request-form action=\"" + actionUrl + "\"";
	fbmlContent += " method=\"POST\" invite=\"true\" type=\"Bonnaroo Mind Reader\" content=\"";
	fbmlContent += "Let Zoltaroo The Bonnaroo Mind Reader help pick your Bonnaroo '09 schedule!";
	fbmlContent += "<fb:req-choice url='http://mindreader.bonnaroo.com/' label='Play!' />\"";
	fbmlContent += "<fb:multi-friend-selector condensed=\"false\" bypass=\"cancel\"";
	if (currentFriendIds != null && currentFriendIds.length > 0) {
		var excludeIds = "";
		for (var i=0; i<currentFriendIds.length; i++) {
			if (i > 0) {
				excludeIds += ",";
			}
			excludeIds += currentFriendIds[i];
		}
		fbmlContent += " exclude_ids=\"" + excludeIds + "\"";
	}
	fbmlContent += " showborder=\"false\" actiontext=\"Invite your friends to use Zoltaroo.\">";
	fbmlContent += "</fb:request-form></fb:fbml>";
	
	var dialog = new FB.UI.FBMLPopupDialog ('Invite Friends');
	dialog.setFBMLContent(fbmlContent);
	dialog.setContentWidth(700);
	dialog.set_placement(FB.UI.PopupPlacement.topCenter );
	dialog.show();
}

function onRsvpClick(postUrl, callback) {
	callback = (typeof(callback) == "undefined") ? onRsvpResult : callback;  
	// find out if the user has given us this permission yet
	var hasPermission = FB.Facebook.apiClient.users_hasAppPermission("rsvp_event", function(result) {
		FB.Debug.dump(result, 'RSVP Permission');
		if (!result) {
			FB.Connect.showPermissionDialog('rsvp_event', function(allow) {
				onRsvp(allow, postUrl, callback);
			});
		} else {
			// we have the permission, go ahead and RSVP.
			onRsvp(true, postUrl, callback);
		}
	});
	
}
function onRsvp(allowed, postUrl, callback) {
	if (allowed) {
 		$.post(postUrl, {eid: 80266911300}, callback, "json");					
	}
}
function onRsvpResult(result, status) {
	if (result.result != "OK") {
		alertDialog("RSVP Failed", "Oops, RSVP failed. Try again.");	
	} else {
		alertDialog("RSVP", "You have RSVP'd successfully.");
	}
}

function alertDialog(title, text) {
	var alertDiv = $("<div></div>");
	alertDiv.attr("title", title);
	alertDiv.append(text);
	alertDiv.dialog({resizable:false, buttons: {"Close" : function() { $(this).dialog("close"); }}});
}

function onUpdateStatus(inputId) {
	//$("#statusError").text("");
	var status = $.trim($("#" + inputId).val());
	var maxLength = 160;
	var length = status.length;
	if (length > maxLength) {
		var msg = "Status cannot exceed " + maxLength + " characters (currently " + length + ")";
		alertDialog("Status too long", msg);
		//$("#statusError").text("Status cannot exceed " + maxLength + " characters (currently " + length + ")");
	} else {
		setStatusWithPrompt(status);
		//$j(this).dialog("close");
	}
}
function shareOnFacebook(url) {
	FB.Connect.showShareDialog(href, function(result) {
		FB.FBDebug.dump(result, "share dialog result");
	});
}
function postScheduleOnFacebook(url, bundleId) {
	if (typeof(bundleId) == "undefined") {
		bundleId = 84444692180;
	}
	var templateData = {"scheduleUrl" : url};
	FB.Connect.showFeedDialog(bundleId, templateData);
}
function getPerformerImageUrl(performer) {
	var imageUrl = performer.imageUrl;
	if (imageUrl == null || imageUrl == "") {
		imageUrl = "../static/images/tarot/" + performer.internalName + ".gif";
	}
	return imageUrl;
}
function getShortName(entity) {
	if (entity.shortName != null && entity.shortName != "") {
		return entity.shortName;
	}
	return entity.name;
}
function getPerformerShortName(performer) {
	return getShortName(performer);
}
function onError(title, text) {
	var alertDiv = $("<div></div>");
	alertDiv.attr("title", title);
	alertDiv.append(text);
	alertDiv.dialog({resizable:false, buttons: {"Close" : function() { $(this).dialog("close"); onLogout();}}});
}
function checkForError(result, title, msg) {
	try {
		var status = result.result;
		if (status != "OK") {
			onError(title, msg);
		}
	} catch (err) {
		onError(title, msg);
	}
}

