function getProfileInfo(uid, callback) {
	FB.Bootstrap.ensureInit(function() {
		FB.Facebook.apiClient.users_getInfo([uid], 
				[
					'name',
					'proxied_email',
					'first_name', 
					'last_name',
					'activities',
					'birthday',
					'current_location',
					'education_history',
					'hometown_location',
					'interests',
					'movies',
					'music',
					'relationship_status',
					'sex',
					'meeting_sex',
					'tv',
					'work_history'
				],
			
			function(userInfo, ex) {
				if (userInfo != null) {
					callback(userInfo[0]);
				} else {
					onLoginMismatch();
				}
		    });	

	});

}
function onLoginMismatch() {
	clearFBConnectCookies(appKey);

	onError("Login Mismatch", "It looks like you may have been logged out.  You'll now be taken to the home page where you can log in again.");
}
function alertDialog(title, text) {
	var alertDiv = $("<div></div>");
	alertDiv.attr("title", title);
	alertDiv.append(text);
	alertDiv.dialog({resizable:false, buttons: {"Close" : function() { $(this).dialog("destroy");}}});
}
function getFlexApp(appName) 
{
    if (navigator.appName.indexOf ("Microsoft") !=-1) 
        return window[appName];
    else
        return document[appName];
}

function loadFlash(swfLoc, configLoc, id, replaceId, width, height, installerLoc) {
    var flashvars = {};
    flashvars.tour = "";

    var params = {};
    params.menu = "false";
    params.allowsscriptaccess = "always";
    params.wmode = "transparent";
    
    var attributes = {};
    attributes.id = id;

    if (configLoc != null && configLoc != '') {
    	swfLoc += "?config=" + configLoc;
    }
    swfobject.embedSWF(swfLoc, replaceId, width, height, "9.0.124", installerLoc, flashvars, params, attributes);	
}
function loadFlashButton(swfLoc, link, buttonId, containerId, width, height) {
	var flashvars = {};
	flashvars.myLink=link;
	var params = {};
	params.menu = "false";
	params.allowsscriptaccess = "always";
	params.wmode = "transparent";

	var attributes = {};
	attributes.id = buttonId;
	swfobject.embedSWF(swfLoc, containerId, width, height, "9.0.124", "<c:url value='/static/other/expressInstall.swf'/>", flashvars, params, attributes);

}

function getDatePickerDefaultOptions(buttonImageUrl) {
	var options = {minDate: 0, 
			beforeShowDay: function(date) {
				var selectable = date.getDay() != 2;
				var tip = selectable ? null : 'MoMA is closed on Tuesdays';
				return [selectable, '', tip];
	}};
	
	if (buttonImageUrl != null && typeof(buttonImageUrl) != 'undefined') {
		options.buttonImage = buttonImageUrl;
		options.buttonImageOnly = true;
		options.showOn = 'both';
	}
	return options;
}
function scaleAffinities(affinities, pctBelow) {
	var min = null;
	var max = null;
	for (var i=0; i<affinities.length; i++) {
		var affinityObj = affinities[i];
		if ((min == null || affinityObj.affinity < min) && affinityObj.affinity > 0) {
			min = affinityObj.affinity;
		}
		if (max == null || affinityObj.affinity > max) {
			max = affinityObj.affinity;
		}
	}
	var floor = 0;
	if (affinities.length > 0) {
		
		floor = min - ((max - min) * (pctBelow));
	}
	for (var i = 0; i<affinities.length; i++) {
		var affinityObj = affinities[i];
		affinityObj.originalAffinity = affinityObj.affinity;
		if (affinityObj.affinity > 0) {
			affinityObj.affinity = affinityObj.affinity - floor;
		}
	}
	return affinities;
}
function convertToCsv(arr) {
	if (arr == null || arr.length == 0) return '';
	
	var csv = '';
	for (var i=0; i<arr.length; i++) {
		if (i > 0) {
			csv += ',';
		}
		csv += arr[i];
	}
	return csv;
}
function sortRandomly(arr) {
	if (arr != null && arr.length > 1) {
		arr.sort(function(a, b) { return Math.round(Math.random())-0.5; });
	}
}

function popupInviteFriends(actionUrl, currentFriendIds) {
	var fbmlContent = "<fb:fbml><fb:request-form action=\"" + actionUrl + "\"";
	fbmlContent += " method=\"POST\" invite=\"true\" type=\"Ranger Dave's Magic Scheduler\" content=\"";
	fbmlContent += "Let Ranger Dave help you plan your Outside Lands schedule!";
	fbmlContent += "<fb:req-choice url='http://magicscheduler.sfoutsidelands.com/' label='Plan!' />\"";
	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 Ranger Dave's Magic Scheduler.\">";
	fbmlContent += "</fb:request-form></fb:fbml>";
	
	var dialog = new FB.UI.FBMLPopupDialog ('Invite Friends');
	dialog.setFBMLContent(fbmlContent);
	dialog.setContentWidth(750);
	dialog.set_placement(FB.UI.PopupPlacement.topCenter );
	dialog.show();
}

function clearFBConnectCookies(appKey) {
	var loginCookies = [appKey, appKey + "_user", appKey + "_session_key", appKey + "_ss", appKey + "_expires"];
	for (var i=0; i<loginCookies.length; i++) {
		$.cookie(loginCookies[i], null, {domain:'sfoutsidelands.com', path:'/'});
	}
}

function getResponseChoices() {
	return [
	        {text:"Black Eyed Peas", responseId:1},
	        {text:"Q-tip", responseId:2},
	        {text:"Dave Matthews Band", responseId:3},
	        {text:"Modest Mouse", responseId:4},
	        {text:"Mars Volta", responseId:5}
	        ];
}
function addResponseChoicesToDropDown(dropdown, responseChoices) {
	for (var i=0; i<responseChoices.length; i++) {
		dropdown.append("<option value='" + responseChoices[i].responseId + "'>" + responseChoices[i].text + "</option>");
	}
}
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"); doLogout();}}});
}
function checkForError(result, title, msg) {
	try {
		var status = result.result;
		if (status != "OK") {
			onError(title, msg);
		}
	} catch (err) {
		onError(title, msg);
	}
}

function postToFacebook(url, bundleId) {
	if (typeof(bundleId) == "undefined") {
		bundleId = 134259763091;
	}
	// add some tracking to the URL
	if (url.indexOf("?") >= 0) {
		url += "&";
	} else {
		url += "?";
	}
	url += "utm_source=titlelink&utm_medium=facebook&utm_campaign=guptamedia";
	
	var templateData = createTemplateData(url);
	FB.Connect.showFeedDialog(bundleId, templateData, null, null, null, FB.RequireConnect.require, null, "Add a comment", {value: ""});
}

function createTemplateData(url) {
	var templateData = {"scheduleUrl": url, "actionLink": url, 
			"images" : [{"src":"http://magicscheduler.sfoutsidelands.com/static/images/FB-App-Post.gif", "href":url}]
	};
	return templateData;
}

function trackAnalyticsAction(domElement) {
	try {
		var elem = $(domElement);
	    var path = elem.attr("gaId");
	    if (path == null || path == "") {
	        path = elem.attr("id");
	    }
	    if (path == null || path == "") {
	        path = elem.attr("href");
	    }
	    pageTracker._trackPageview(path);
	} catch (err) {}
}

function trackAnalyticsEvent(domElement) {
	try {
		var elem = $(domElement);
	    var category = elem.attr("gac");
	    var event = elem.attr("gae");
	    
	    pageTracker._trackEvent(category, event);
	} catch (err) {}
}

function newDate(startTime) {
	return Date.parseExact(startTime, "yyyy-MM-dd HH:mm:ss");
}
function makePerformanceTimeText(performance, format) {
	if (typeof(format) == "undefined") {
		format = "h:mm";
	}
	var startDate = newDate(performance.start);
	var endDate = startDate.clone().addMinutes(performance.duration);
	return startDate.toString(format) + " - " + endDate.toString(format);
}
function getStartDateObj(performance) {
	var startObj = performance.startObj;
	if (startObj == null) {
		startObj = newDate(performance.start);
		performance.startObj = startObj;
	}
	return startObj;
}
function comparePerformancesByTime(performanceA, performanceB) {
	var startAObj = getStartDateObj(performanceA);
	var startBObj = getStartDateObj(performanceB);
	var compare = Date.compare(startAObj, startBObj);
	if (compare != 0) {
		return compare;
	}
	// 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 getNameOrLongName(venue) {
	var name = venue.line3;
	if (name == null || name == '') {
		name = venue.line1;
	}
	return name;
}
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.start);
		// because the start times can run into the next day,
		// and we want to consider those all part of the same "day",
		// the simplest thing to do is subtract 6 hours.
		thisDate.addHours(-6);
		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("ddd MMM dS"));
			container.append(dayContainer);
			dayContainer.show();
			entriesContainer = $(".entriesContainer", dayContainer);
		}
		var entryDiv = entryTemplate.clone();
		entryDiv.removeAttr("id");
		var venue = venueMap[performance.venueId];
		$(".performerName", entryDiv).text(performance.line1);
		var name = getNameOrLongName(venue);
		$(".venueName", entryDiv).text(name);
		$(".venueSubtitle", entryDiv).text(venue.line2);
		$(".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("in");
			} else {
				entryDiv.addClass("out");
			}
		}
		entryDiv.data("performance", performance);
		entryDiv.show();
	}
}
function showContestDetails() {
	$("#contestDetails").dialog({modal: true, buttons:{"Close" : function() { $(this).dialog("destroy"); }}, autoOpen: true, width: 500, height: 380, resizable:false, position:['center', 100] })
}
