var months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
var full_months = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
var days_of_week = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
var timezone_values = [-12, -11, -10, -9, -8, -7, -6, -5, -4, -3.5, -3, -2, -1, 0, 1, 2, 3, 3.5, 4, 4.5, 5, 5.5, 5.75, 6, 7, 8, 9, 9.5, 10, 11, 12, 13, 14];

if (!Array.prototype.indexOf) {
	Array.prototype.indexOf = function (searchElement /*, fromIndex */ ) {
		"use strict";
		if (this === void 0 || this === null) {
			throw new TypeError();
		}
		var t = Object(this);
		var len = t.length >>> 0;
		if (len === 0) {
			return -1;
		}
		var n = 0;
		if (arguments.length > 0) {
			n = Number(arguments[1]);
			if (n !== n) { // shortcut for verifying if it's NaN
				n = 0;
			} else if (n !== 0 && n !== Infinity && n !== -Infinity) {
				n = (n > 0 || -1) * Math.floor(Math.abs(n));
			}
		}
		if (n >= len) {
			return -1;
		}
		var k = n >= 0 ? n : Math.max(len - Math.abs(n), 0);
		for (; k < len; k++) {
			if (k in t && t[k] === searchElement) {
				return k;
			}
		}
		return -1;
	}
}

function concatStrings() {
	return Array.prototype.slice.call(arguments).join('');
}

function isArray(a) {
	return a instanceof Array;
}

function count (a) {
	var c = 0,
		i;
		
	if (!a) {
		return 0;
	} else if (a.length != null) {
		return a.length;
	} else {
		for (i in a) {
			if (a.hasOwnProperty(i)) {
				c++;
			}
		}
		
		return c;
	}
}

var Timer = {
	t : {},
	start : function (id) {
		Timer.t[id] = (new Date()).getTime();
	},
	
	end : function (id) {
		var t;
		if (id) {
			t = (new Date()).getTime() - Timer.t[id];
			try {
				console.log('Timer (' + id + '): ' + t);
			} catch (err) {
				//swallow the error
			}
		}
	}
}

/**
 * returns the length of an array or 0 if the argument is not an array
 */
function arrayLength(arr) {
	return (arr && arr.length) || 0;
}

function forEach(o, fn) {
	var length = o.length,
		i;
	
	if ((typeof fn) !== 'function') {
		return;
	}
	
	if (length) {
		for(i = 0; i < length; i++) {
			fn(i, o[i]);
		}
	} else {
		for (i in o) {
			if (o.hasOwnProperty(i)) {
				fn(i, o[i]);
			}
		}
	}
}

function objectToArray(o) {
	var arr = [],
		i;
	
	if (i in o) {
		if (o.hasOwnProperty(i)) {
			arr.push(o[i]);
		}
	}
	
	return arr;
}

function randomInt(min, max) {
	return Math.floor(Math.random() * (max - min + 1) + min);
}

function inArray(value, arr) {
	var length = arr.length,
		i;
	for (i=0;i<length;i++) {
		if (arr[i] == value) {
			return true;
		}
	}
	
	return false;
}

function sortByField(array, field) {
	"use strict";
	var comparitor = function (a, b) {
		var a_field = a[field],
			b_field = b[field];
		
		if (a_field === b_field) {
			return 0;
		} else if (a_field < b_field) {
			return -1;
		} else {
			return 1;
		}
	};
	
	array.sort(comparitor);
}

function groupArray(array, field, modify_item) {
	var groups = {},
		array_length = arrayLength(array),
		i, item, group, group_key;
	
	for (i = 0; i < array_length; i++) {
		item = array[i];
		safeCall(modify_item, [i, item]);
		group_key = item[field];
		group = groups[group_key];
		if (group) {
			group.push(item);
		} else if (group_key) {
			groups[group_key] = [item];
		}
	}
	
	return groups;
}

function extractValuesByField (array, field) {
	var values = [];
	
	forEach(array, function (key, value) {
		values.push(value[field]);
	});
	
	return values;
}

function extractUniqueValuesByField (array, field) {
	var values = [],
		unique_values = {},
		new_value;
	
	forEach(array, function (key, value) {
		new_value = value[field];
		if (!unique_values[new_value]) {
			unique_values[new_value] =	1;
			values.push(value[field]);
		}
	});
	
	return values;
}

function extractKeys (array) {
	var keys = [];
	
	forEach(array, function (key, value) {
		keys.push(key);
	});
	
	return keys;
}

/**
 * returns an array of items with unique values based on the value of a key field.
 */
function getUniqueObjectArray(arr, field) {
	var item_ids = {},
		array_length = arrayLength(arr),
		unique_array = [],
		i, item, key;
	
	if (!arr) {
		return null;
	}
	
	for (i = 0; i < array_length; i++) {
		if (arr[i] && arr[i][field] && !item_ids[arr[i][field]]) {
			item_ids[arr[i][field]] = true;
			unique_array.push(arr[i]);
		}
	}
	
	return unique_array;
}

/**
 * ensure a function is a function before calling it with the specified parameters
 */
function safeCall(fn, args, that) {
	if ((typeof fn) == 'function') {
			fn.apply(that || null, args || []);
	}
}

function supportsCanvas () {
	return !!document.createElement('canvas').getContext;
}

function isIpad() {
	return navigator.userAgent.match(/iPad/i) != null
}

function isChrome() {
	return navigator.userAgent.match(/chrome/i) != null
}

function hasMembers(obj) {
	for (i in obj) {
		return true;
	}

	return false;
}

/**
 * gets the event based on a passed in event.  This function is neccessary for
 * IE compatability.
 */
function getEvent(event) {
	return event || window.event;
}

//prevents an event from bubbling up the dom
function preventBubbling(event) {
	event = getEvent(event); //for ie compatability

	if (event) {
		event.cancelBubble = true;
		if (event.stopPropagation) {
			event.stopPropagation();
		}
	}
}

function getEventTarget(event) {
	event = getEvent(event);
	if (event) {
		return event.target || event.srcElement;
	} else {
		return event;
	}
}

function getParentElement(node) {
	if (node) {
		return node.parentNode || node.parentElement;
	} else {
		return node;
	}
}

function getAncestorByTagName(node, tagName) {
	tagName = tagName.toLowerCase();
	while ((node != null) && (node.nodeName.toLowerCase() != tagName)) {
		node = getParentElement(node);
	}

	return node;
}

function getAncestorByClassName(node, className) {
	while ((node != null) && (node.nodeName.toLowerCase() != className)) {
		node = getParentElement(node);
	}

	return node;
}

/*
 *	A jquery version of getAncestorByClassName
 */
function getAncestorWithClass(node, class_name) {
	while (node.length && !node.hasClass(class_name)) {
		node = node.parent();
	}
	
	if (!node.length) {
		node = null;
	}
	
	return node;
}

function removeNode(node) {
	if (node) {
		var parentNode = node.parentNode || node.parentElement;
		if (parentNode) {
			return parentNode.removeChild(node);
		}
	}
	return node;
}

/**
 * swaps to nodes in the dom.  It is assumed neither is an ancestor of the other
 */
function swapNodes(node1, node2) {
	var parent1 = node1.parentNode || node1.parentElement;
	var parent2 = node2.parentNode || node2.parentElement;
	if (parent1 && parent2) {
		var next1 = node1.nextElementSibling || node1.nextSibling;
		var next2 = node2.nextElementSibling || node2.nextSibling;

		//there are several different cases to handle specially
		if (node2 == next1) { //node2 immediately follows node1
			node2 = parent1.removeChild(node2);
			node2 = parent1.insertBefore(node2, node1);
		} else if (node1 == next2) { //node1 immediate follows node2
			node1 = parent1.removeChild(node1);
			node1 = parent1.insertBefore(node1, node2);
		} else { //nodes are not adjacent
			node1 = parent1.removeChild(node1);
			node2 = parent2.removeChild(node2);
			if (next1 && next2) { //neither is the last element
				node2 = parent1.insertBefore(node2, next1);
				node1 = parent2.insertBefore(node1, next2);
			} else if (next1) { //only node2 is the last element
				node2 = parent1.insertBefore(node2, next1);
				node1 = parent2.appendChild(node1);
			} else if (next2) { //only node1 is the last element
				node2 = parent1.appendChild(node2);
				node1 = parent2.insertBefore(node1, next2);
			}
		}
	}
}

function removeObjectFromArray(array, value, field) {
	var array_length = arrayLength(array),
		i;
	
	for (i = 0; i < array_length; i++) {
		if (array[i][field] == value) {
			removeIndexFromArray(array, i);
			break;
		}
	}
}

function removeItemFromArray(array, item) {
	var item_index = array.indexOf(item);
	
	if (item_index != -1) {
		removeIndexFromArray(array, item_index);
	}
}

function removeItemsFromArray(array, items) {
	var num_items = arrayLength(items),
		i, item_index;
}

function removeIndexFromArray(array, index) {
	array.splice(index, 1);
	return array;
}

function addItemToArray(array, item, index) {
	return array.splice(index, 0, item);
}

function addItemsToArray(array, items, index) {
	return array.splice.apply(array, [index, 0].concat(items));
}

function isLastChild(node) {
	return (node == node.parentNode.lastChild);
}

function isFirstChild(node) {
	return (node == node.parentNode.firstChild);
}

function shuffle(o) {
	for(var j, x, i = o.length; i; j = parseInt(Math.random() * i), x = o[--i], o[i] = o[j], o[j] = x);
	return o;
}

function show_props(obj, obj_name) {
   var result = "";
   for (var i in obj)
      result += obj_name + "." + i + " = " + obj[i] + "<br>\n";
   return result;
}

function elem_count(obj) {
	var count = 0;
	if (obj) {for (var i in obj) count++;}
	return count;
}

function print_r(theObj){
	if (theObj.constructor == Array || theObj.constructor == Object || typeof(theObj) == 'object') {
		document.write("<ul>")
		for (var p in theObj) {
			if (theObj[p]) {
				if (theObj[p].constructor == Array || theObj[p].constructor == Object || typeof(theObj[p]) == Object) {
					document.write("<li>["+p+"] => "+typeof(theObj)+"</li>");
					document.write("<ul>")
					print_r(theObj[p]);
					document.write("</ul>")
				} else document.write("<li>["+p+"] => "+theObj[p]+"</li>");
			}
		}document.write("</ul>");
	}
}

function in_array(needle, haystack) {
	if (haystack && haystack.indexOf) {
		return (haystack.indexOf(needle) != -1);
	}
	for (var i in haystack) {
		if (haystack[i] == needle) return true;
	}
	return false;
}

function escapeQuotes(src) {
	// unescape single and double quotes from src and return
	if (typeof(src) == "string") {
		src = src.replace(/&#39;/g, "&rsquo;");
		src = src.replace(/'/g, "&rsquo;");
		src = src.replace(/"/g, "&quot;");
		return src;
	}return '';
}

function unescapeQuotes(src) {
	// unescape single and double quotes from src and return
	src = src.replace(/&#39;/g, "'");
	src = src.replace(/&rsquo;/g, "'");
	src = src.replace(/&quot;/g, '"');
	return src;
}

function formatTagStr(tag_str) {
	return tag_str.replace(/['"]/g,'').replace(/[^\w,]/g,' ').replace(/\s{2,}/g,' ').replace(/\s?,\s?/g, ',').replace(/(^\s?)|(\s?$)/g,'').replace(/,{2,}/g,',').replace(/(^,?)|(,?$)/g,'').replace(/,/g, ', ').toLowerCase();
}

function d_escape(content) {
	if (!content) return '';
	return encodeURIComponent(encodeURIComponent(content)).replace(/'/g, '%2527');
}

function urldecode(content) {
	if (content != null) {
		try {
			content = decodeURIComponent(content);
		} catch (err) {
			try {
				content = decodeURIComponent(unescape(content));
			} catch (err) {
				content = unescape(content);
			}
		}
	}
	return content;
}

function removeFromArray(elem, array) {
	var length = array.length;
	for (var i=0; i<length; i++) {
		var elemInArr = array[i];
		if (elemInArr == elem) {
			array.splice(i, 1);
			break;
		}
	}
}

function getNewPageUrl(page) {
	var url = location.href;
	var page_param = 'p='+page;
	if (url.indexOf('?') != -1) {
		var page_regex = /([^\w])(p=[^&]+)/;
		if (url.match(page_regex)) url = url.replace(page_regex, RegExp.$1+page_param);
		else {
			if (!url.match(/\?$/)) url += '&';
			url += page_param;
		}
	} else url += '?'+ page_param;
	return url;
}

function recreateOwnNight() {
	if (!loggedInUser) loginToFacebook(redirectToRecreate);
	else redirectToRecreate();
}

function redirectToRecreate() {
	var new_url = replaceUrlParam('sts', segmentData.start, removeUrlParam('sid', removeUrlParam('fid', getNewPageUrl('create'))));
	location.href = new_url+(new_url.indexOf('newcreator')==-1?'&newcreator=1':'');
}

function redirectToEditMode(skip_prompt, photobook) {
	var current_url = location.href,
		segmentFlags = window.segmentFlags,
		href = current_url;
	
	if (skip_prompt) {
		//prompt only occurs when there are pending ajax calls so we prentend they
		// do not exist
		segmentFlags.ajaxCalls = 0;
	}
	
	//search first to prevent this from being added multiple times
	if (href.indexOf('&edit_mode=1') == -1) {
		href = href.replace('p=nw', 'p=nw&edit_mode=1');
	} if (photobook && href.indexOf('&photobook=1') == -1) {
		href = href.replace('edit_mode=1', 'edit_mode=1&photobook=1');
	}
	
	location.href = href;
}

function propagateContributeAction(action) {
	$.cookies.set("postAuthAction", action);
	var trackLoggedIn = '&loggedIn=1';
	if (window.editNight) trackLoggedIn = '&contributeClicked=1';
	location.href = location.href+trackLoggedIn;
}

function gaIframe(type, args) {
	var app_id;
	if (args) app_id = args['app_id'];
	if (!window.dataFlags) window.dataFlags = {};
	if (!dataFlags[type+'Tracked']) {
		var uid_param = '';
		uid_param = (window.userProfileObj && userProfileObj.id?userProfileObj.id:
		  (window.kaptur_quickstart && kaptur_quickstart.user_kaptur_id? kaptur_quickstart.user_kaptur_id : 
			(window.KML && KML.user_info && KML.user_info.kaptur_id? KML.user_info.kaptur_id : '')
		  )); uid_param = uid_param?'&uid='+uid_param:'';
		var ga_url = '?p=ga'
			+(window.memoryCreationWizard && memoryCreationWizard.sid?'&sid='+memoryCreationWizard.sid:'')
			//+(window.loggedInUser?'&fid='+loggedInUser:'')
			+uid_param+(app_id?'&app_id='+app_id:'')
			+(window.order_data && order_data.id?'&oid='+order_data.id:'')
			+'&btn='+type;
		
		var ref_regex = new RegExp('&(aff|ref)=([^&]*)');
		if (location.href.match(ref_regex)) ga_url += '&'+RegExp.$1+'='+RegExp.$2;
		
		document.getElementById('gaIframeTracker').src = ga_url;
		dataFlags[type+'Tracked'] = 1;
	}
}

function formatTimeStr(utc_time, format) {
	var date_format = 'dotted';var time_format = 'short';var date_time_str = '';var separator = ' ';
	if (in_array(format, ['timeline', 'timeline_indicator'])) {
		date_format = 'slashed';time_format = '';separator = format != 'timeline_indicator'? '<br>' : ' - ';
	}var date_str = formatDateStr(new Date(utc_time*1000), date_format);
	if (format == 'timeline') date_str = '<b>'+date_str+'</b>';
	var time_str = getFormattedTime(utc_time*1000, time_format);
	var date_time_str = date_str+separator+time_str;
	return date_time_str;
}

function formatDateStr(calendar_date, type) {
	var calendar_str = '';
	var date_val = calendar_date.getUTCDate().toString();
	var date_day = calendar_date.getUTCDay();
	var date_month = calendar_date.getUTCMonth();
	var date_month = calendar_date.getUTCMonth();
	var date_full_month = full_months[date_month];
	var date_month_real = date_month + 1;
	var date_year = calendar_date.getUTCFullYear();
	var date_year_short = date_year.toString().substr(2);
	if (!type || type == 'day') {
		var ordinal = date_val.charAt(date_val.length-1);
		if (ordinal == 1 && date_val != 11) ordinal = 'st';else if (ordinal == 2 && date_val != 12) ordinal = 'nd';
		else if (ordinal == 3 && date_val != 13) ordinal = 'rd'; else ordinal = 'th';
		if (!type) calendar_str = date_full_month+' '+date_val+ordinal+', '+date_year;
		else calendar_str = days_of_week[date_day]+', '+date_full_month+' '+date_val+ordinal;
	} else if (type == 'short') calendar_str = months[date_month]+' '+date_val+', '+date_year;
	else if (type == 'slashed') calendar_str = date_month_real+'/'+date_val+'/'+date_year_short;
	else if (type == 'slashed_full') calendar_str = date_month_real+'/'+date_val+'/'+date_year;
	else if (type == 'dotted') calendar_str = date_month_real+'.'+date_val+'.'+date_year_short;
	return calendar_str;
}

function getFormattedTime(millitime, format) {
	var showZeros, condense = format=='short';
	if (format && !condense) showZeros = 1;	
	var time;var date = new Date(millitime);
	var hours = date.getHours();
	var minutes = date.getMinutes();
	if (minutes === 0) {
		minutes = '';
		if (showZeros) minutes = '0';
	}if (minutes) {
		if (minutes < 10) minutes = "0"+minutes;
		minutes = ":"+minutes;
	}if (!hours) time = "12"+minutes+' '+(condense?'a':"AM");
	else if (hours > 11) {
		hours -= 12;
		if (!hours) hours = 12;
		time = hours+minutes+(condense?'p':' PM');
	} else time = hours+minutes+(condense?'a':' AM');
	return time;
}

function validateDate(div_id) {
	// select specified fields set
	var month_field = document.getElementById(div_id+'Month');
	var day_field = document.getElementById(div_id+'Day');
	var year_field = document.getElementById(div_id+'Year');
	var hours_field = document.getElementById(div_id+'Hours');
	var minutes_field = document.getElementById(div_id+'Minutes');
	var am_pm_field = document.getElementById(div_id+'AMPM');
	var tz_field = document.getElementById(div_id+'TZ');
	if (div_id.indexOf('summary') == 0) tz_field = document.getElementById('nightSummaryTZ');
	var error_msg = '';
	
	// construct date
	var tzoffset = div_id.indexOf('newNightCreate') == 0? segmentData.tzoffset:tz_field.value; //segmentData.id? segmentData.tzoffset : -new Date(segmentData.start*1000).getTimezoneOffset()/60;
	var time_sec = parseInt(Date.parse(month_field.value+'/'+day_field.value+'/'+year_field.value+" "+hours_field.value+":"+minutes_field.value+" "+am_pm_field.value+offsetToGMTStr(tzoffset))/1000, 10);
	if (!(month_field.value*1) || month_field.value < 1 || month_field.value > 12) {
		error_msg = 'Please enter a number between 1 and 12 for month!';
		month_field.select();
	} else if (!(day_field.value*1) || day_field.value < 1 || day_field.value > 31) {
		error_msg = 'Please enter a number between 1 and 31 for day!';
		day_field.select();
	} else if (!(year_field.value*1)) {
		error_msg = 'Please enter a valid year!';
		year_field.select();
	} else if (!(hours_field.value*1) || hours_field.value < 1 || hours_field.value > 12) {
		error_msg = 'Please enter a number between 1 and 12 for hours!';
		hours_field.select();
	} else if ((!(minutes_field.value*1) && minutes_field.value != '00' && minutes_field.value != '0') || minutes_field.value < 0 || minutes_field.value > 60) {
		error_msg = 'Please enter a number from 0 and 60 for minutes!';
		minutes_field.select();
	} else if (!has_segment_point_table && (div_id.indexOf('summary') == -1 && div_id.indexOf('newNightCreate') == -1) && (time_sec < segmentData.start || time_sec > segmentData.end)) {
		error_msg = 'The time you entered is out of this memory\'s range!';
	}
	else if (!time_sec) error_msg = 'Please enter a valid date!';
	return {'time':time_sec, 'tzoffset':tzoffset, 'error':error_msg};
}

function extractJSONid(data) {
	data = JSON.parse(data);
	data = JSON.parse(data['result']);
	return data['id'];
}

function updateDateDisplays() {
	try {
		document.getElementById("summaryLoading").style.display = "none";
		// calculate and display start date
		var night_start_date = new Date(getAdjustedTime(segmentData.start)*1000);
		var night_start_day = night_start_date.getDate();
		var night_start_month = night_start_date.getMonth();
		var night_start_year = night_start_date.getFullYear();
		document.getElementById('nightCalendarMonth').innerHTML = full_months[night_start_month]+" "+night_start_year;
		document.getElementById('nightCalendarDay').innerHTML = night_start_day;
		document.getElementById('nightCalendarStartMonth').innerHTML = full_months[night_start_month]+" "+night_start_year;
		document.getElementById('nightCalendarStartDay').innerHTML = night_start_day;
		
		// build and display end date
		var night_end_date = new Date(getAdjustedTime(segmentData.end)*1000);
		var night_end_day = night_end_date.getDate();
		var night_end_month = night_end_date.getMonth();
		var night_end_year = night_end_date.getFullYear();
		document.getElementById('nightCalendarEndMonth').innerHTML = full_months[night_end_month]+" "+night_end_year;
		document.getElementById('nightCalendarEndDay').innerHTML = night_end_day;
		
		// check if start date is the same as the end date to determine whether to display one or two calendar images
		var nightCalendar = document.getElementById('nightCalendarWrapper');
		var nightDuoCalendar = document.getElementById('nightDuoCalendarWrapper');
		if (night_start_day == night_end_day && night_start_month == night_end_month && night_start_year == night_end_year) {
			nightCalendar.style.display = 'block';
			nightDuoCalendar.style.display = '';
		} else {
			nightDuoCalendar.style.display = 'block';
			nightCalendar.style.display = '';
		}
		
		// store date data in memory
		segmentData.startDay = night_start_day;
		segmentData.startMonth = night_start_month+1;
		segmentData.startYear = night_start_year;
		segmentData.endDay = night_end_day;
		segmentData.endMonth = night_end_month+1;
		segmentData.endYear = night_end_year;
		segmentData.tzindex = getTzIndex();
		
		// update tenses
		if (!segmentData.tense) setSegmentTense();
		var tense_str = 'Is';var tense = segmentData.tense;
		if (tense == 'past') tense_str = "Was";
		else if (tense == 'future') tense_str = "Will Be";
		var who_was_there_str = 'Who '+tense_str+' There';
		document.getElementById('nightFriendsLabel').innerHTML = who_was_there_str;
		document.getElementById('nightFriendsAddLabel').innerHTML = who_was_there_str;
		document.getElementById('optInText').innerHTML = 'I '+(tense=='present'?'am here':tense_str.toLowerCase()+' there')+'!';
		
		// format and display segment start and end times // getAdjustedTime
		if (dataFlags.timelineView) { // location.href.indexOf('timeline') != -1 || 
			var timelineNavLeft = document.getElementById('timelineNavLeft');
			var timelineNavRight = document.getElementById('timelineNavRight');
			if (timelineNavLeft) {
				timelineNavLeft.innerHTML = formatTimeStr(getAdjustedTime(segmentData.start));
				timelineNavLeft.style.display = 'block';
			}if (timelineNavRight) {
				timelineNavRight.innerHTML = formatTimeStr(getAdjustedTime(segmentData.end));
				timelineNavRight.style.display = 'block';
			}
		}
		
		// normalize date and calculate next and previous dates
		/*var day_in_ms = 24*60*60*1000;
		var normalized_date = Date.parse((night_start_month+1)+'/'+night_start_day+'/'+night_start_year);
		var prev_date = new Date(normalized_date-day_in_ms);
		var next_date = new Date(normalized_date+day_in_ms);
		
		// format and display dates
		var date_format = 'short';
		//document.getElementById('nightTitleDate').innerHTML = formatDateStr(night_start_date, date_format);
		document.getElementById('prevNightDate').innerHTML = formatDateStr(prev_date, date_format);
		document.getElementById('nextNightDate').innerHTML = formatDateStr(next_date, date_format);*/
		
		// show updated like button
		updateLikeBtn();
	} catch(err) {}
}

function getTzIndex(tzoffset) {
	if (!tzoffset) tzoffset = segmentData.tzoffset;
	return timezone_values.indexOf(parseFloat(tzoffset, 10));
}

function getAdjustedTimeWrap(date_item) {
	var utc_time = parseInt(date_item.getTime()/1000, 10);
	var tzoffset = memoryCreationWizard.timezone_offset;
	return new Date(getAdjustedTime(utc_time, tzoffset)*1000);
}

function getAdjustedTime(utc_time, tzoffset) {
	if (!tzoffset) tzoffset = segmentData.tzoffset;
	utc_time = parseInt(utc_time, 10);tzoffset = parseFloat(tzoffset, 10);
	return utc_time + (tzoffset*60 + new Date((utc_time+tzoffset*60*60)*1000).getTimezoneOffset())*60;
}

/**
 * takes either a date object or a timestamp in milliseconds and returns a the
 * timezone offset in hours.
 */
function getDateTimezone(date) {
	if ((typeof date) == 'number') {
		date = new Date(date);
	}
	
	return date.getTimezoneOffset() / -60;
}

function getUniqueTime(point_time) {
	if (rmnPointTimes[point_time]) { // ensure no two points have the same time
		while (rmnPointTimes[point_time]) point_time++;
	}rmnPointTimes[point_time] = 1;
	return point_time;
}

function roundOffSec(utcSec) {
	return Math.round(utcSec/100)*100;
}

// enable indexOf function for IE
if (!Array.prototype.indexOf) {
	Array.prototype.indexOf = function(elt, from) {
		var len = this.length;
		var from = Number(arguments[1]) || 0;
		from = (from < 0) ? Math.ceil(from) : Math.floor(from);
		if (from < 0) from += len;
		for (; from < len; from++) {if (from in this && this[from] === elt) return from;}
		return -1;
	}
}

function getFullName(first_name, last_name) {
	var full_name;if (first_name || last_name) full_name = (first_name?first_name+(last_name?' ':''):'')+last_name;
	if (full_name && full_name != 'undefined') full_name = urldecode(full_name);
	else full_name = '';
	return full_name;
}

function getLinkedProfilePic(fbid, first_name, last_name) {
	if (fbid) {
		var full_name = getFullName(first_name, last_name);
		var full_name_alt = full_name?' title="'+full_name+'"':'';
		var link_url = location.href.split('?')[0].replace('theconstellations.','')+'?p=f&fid='+fbid;
		var ie_click_hanlder = '';
		if (navigator.userAgent.indexOf("MSIE") != -1) ie_click_hanlder = ' onclick="location.href=\''+link_url+'\'" style="cursor:hand"';
		//return '<a href="'+link_url+'"><fb:profile-pic uid="'+fbid+'" size="square" linked="false" class="profile_pic"'+ie_click_hanlder+' /></a>';
		return '<a href="'+link_url+'"><img src="'+getPartnerLink(fbid, 'profile_pic')+'"'+full_name_alt+' class="profile_pic"'+ie_click_hanlder+' /></a>';
	}return '<img src="'+TEMPLATE_VIEW_PATH+'images/placeholders/fb_thumb.png"'+full_name_alt+' class="profile_pic" style="cursor:default" />';
}

function loadFBML(div) {
	if (div && div.id) setTimeout('FB.XFBML.parse(document.getElementById("'+div.id+'"))', 100);
	else FB.XFBML.parse(div);
}

function getPartnerLink(media_id, type) {
	var url = '';
	if (type == 'yt') url = 'http://www.youtube.com/v/'+media_id+yt_params;
	else if (type == 'yt_thumb') url = 'http://i.ytimg.com/vi/'+media_id+'/1.jpg';
	else if (type == 'vim') url = 'http://vimeo.com/moogaloop.swf?clip_id='+media_id+'&autoplay=1';
	else if (type == 'embed') url = 'http://www.facebook.com/v/'+media_id;
	else if (type == 'profile_pic') url = 'http://graph.facebook.com/'+media_id+'/picture';
	else url = 'http://www.facebook.com/video/video.php?v='+media_id;
	return url;
}

function getYouTubeHashFromUrl(yt_link) {
	var yt_hash_regex, yt_hash;
	if (yt_link.indexOf('youtube.com/') != -1) {
		if ((yt_link.indexOf('/watch?v=') != -1) || (yt_link.indexOf('&v=') != -1)) yt_hash_regex = /[?&]v=([^&?]+)/;
		else if (yt_link.indexOf('youtube.com/v/') != -1) yt_hash_regex = /youtube.com\/v\/([^&?]+)/;
	}

	if (yt_link.match(yt_hash_regex)) yt_hash = RegExp.$1;
	
	return yt_hash;
}

function isFbVideo(video_url) {//.net
	return (video_url.indexOf('fbcdn') != -1 || video_url.indexOf('facebook.com') != -1); // video.ak.fbcdn.net
}

function previewVideo(video_src, video_id, thumbnail_only) {
	if (video_id) {
		if (isFbVideo(video_src)) {
			var fbVideo = fbVideos[video_id];
			if (fbVideo) {
				var show_desc = 1;
				var video_title = fbVideo['title'];
				var video_desc = fbVideo['description'];
				var video_thumb = fbVideo['thumbnail_link']
				var video_date = formatDateStr(new Date(fbVideo['created_time']*1000), 'slashed');
				if (thumbnail_only) {
					var fbVideoPreview = document.getElementById('fbVideoPreview');
					var fbVideoPreviewContent = fbVideoPreview.firstChild;
					if (!fbVideoPreviewContent || fbVideoPreviewContent.nodeName.toLowerCase() != 'embed')
						fbVideoPreview.innerHTML = '<img src="'+video_thumb+'" class="fb_preview_thumb" alt="'+video_title+'" title="'+video_title+'">';
					else show_desc = 0;
				} else embedVideo(video_src, {'vid':video_id, 'preview':1});
				
				if (show_desc) document.getElementById('fbVideoPreviewDesc').innerHTML = '<div class="video_desc_title">'+video_title+'</div><div>Uploaded: '+video_date+'</div><div class="video_desc">'+video_desc+'</div>';
			}
		}
	}
}

function embedVideo(video_url, opts) {
	if (video_url) {
		var fb_vid = opts['vid'];
		var preview = opts['preview'];
		var edit_video = opts['edit'];
		var edit_music = opts['music'];
		var no_autoplay = opts['no_autoplay'];
		var return_html = opts['return_html'];
		var flashvars = '';
		// special handling for fb videos
		if (isFbVideo(video_url) && (video_url.indexOf('.mp4') != -1 || video_url.indexOf('.flv') != -1)) {
			var fbVideo = fbVideos[fb_vid];
			var video_id = '1';
			var video_thumb = '', video_width = '', video_height = '';
			if (fbVideo) {
				if (fb_vid) video_id = fb_vid;
				if (fbVideo['src']) video_url = fbVideo['src'].split('?')[0];
				
				// temp fb video hack
				if (video_url.indexOf('fbcdn.net') != -1) video_url = video_url.replace('fbcdn.net', 'facebook.com');
				
				if (fbVideo['thumbnail_link']) {
					if (fbVideo['thumbnail_link'].indexOf('fbcdn.net') != -1) fbVideo['thumbnail_link'] = fbVideo['thumbnail_link'].replace('fbcdn.net', 'facebook.com'); // temp fb video hack
					video_thumb = '&thumb_url='+fbVideo['thumbnail_link'];
				}
				
				if (fbVideo['width']) video_width = '&video_width='+fbVideo['width'];
				if (fbVideo['height']) video_height = '&video_height='+fbVideo['height'];
			}//flashvars = ' flashvars="video_src='+video_url+video_thumb+video_width+video_height+(no_autoplay?'':'&video_autoplay=1')+'"';
			video_url = getPartnerLink(video_id, 'embed');
		}

		//special handling for yt videos
		/*if (isYouTubeVideo(video_url)) {
			var player_api_id = "ytplayer" + fb_vid;
			video_url = addUrlParams(video_url, "enablejsapi=1&playerapiid=" + player_api_id);
			flashvars = ' id="'+player_api_id+'"';
		}*/
		
		var player_div = 'videoPlayerWrapper';
		var player_width = '423';var player_height = '257';
		if (preview) {
			player_div = 'fbVideoPreview';
			player_width = '380';player_height = '231';
		}if (edit_video) {
			player_div = 'editLightboxVideoWrapper';
			player_width = '567';player_height = '343';
		} else if (edit_music) {
			player_div = 'editVideosPlayerWrapper';
			player_width = '485';player_height = '293';
		}if (isFbVideo(video_url)) player_width = '100%';
		if (return_html) {player_width = '600';player_height = '450';}
		var embed_html = '<embed src="'+video_url+'" type="application/x-shockwave-flash" wmode="transparent"'+(navigator.userAgent.indexOf("MSIE") == -1? ' allowscriptaccess="always"' : '')+' allowfullscreen="true" width="'+player_width+'" height="'+player_height+'"'+flashvars+'></embed>'; // allowscriptaccess="always" breaks youtube videos on ie
		if (return_html) return '<div id="fbVideoStd">'+embed_html+'</div>';
		player_div = document.getElementById(player_div);
		if (player_div) player_div.innerHTML = embed_html;
	}
}

function isYouTubeVideo(url) {
	return (url.indexOf("youtube.com") != -1);
}

//params should be a string of params separated by &
function addUrlParams(url, params){
	if (url.indexOf("?") != -1 || url.indexOf("&") != -1) {
		return url + "&" + params;
	} else {
		return url + "?" + params;
	}
}

/**
 * gets all the params in the url.  does not count params occurring after the hash.
 *
 * @param url - the url to parse.  defaults to the url of the current page
 */
function getUrlParams(url) {
	var arr = (url || location.href).split('?')[1],
		params = {},
		i, param;

	if (arr) {
		arr = arr.split('#')[0].split('&');
		for (i = 0; i < arr.length; i++) {
			param = arr[i].split('=');
			params[param[0]] = param[1] || '';
		}
	}

	params.toString = function () {
		var i,r='';
		for (i in this) {
			if ((typeof this[i]) == 'string') {
				r+= '&' + i + '=' + this[i];
			}
		}

		return r;
	}

	return params;
}

function clearDeletedVideo(video_id, video_type, video_src) {
	try {
		// check whether the deleted video is the same as the current video, if so, remove it from the player canvas
		var video_url = '', video_url_alt = getPartnerLink(video_id, 'embed');
		var fbMedia = fbVideos;
		if (video_type == 'yt') fbMedia = fbVideos.yt;
		else if (video_type == 'vim') fbMedia = fbVideos.vim;
		var fbVideo = fbMedia[video_id];
		if (fbVideo) video_url = removeAutoplay(fbVideo['src']);
		var videoPlayerWrapper = document.getElementById('videoPlayerWrapper');
		var videoPlayer = videoPlayerWrapper.firstChild;
		if (videoPlayer) {
			var current_player_url = removeAutoplay(videoPlayer.src);
			if (video_src) video_url = removeAutoplay(video_src);
			if (video_url == current_player_url || video_url_alt == current_player_url)
				videoPlayerWrapper.innerHTML = '';
		}
	} catch(err) {}
}

function clearExtVideoValues(video_text) {
	document.getElementById('ext'+video_text+'Link').value = '';
	document.getElementById('ext'+video_text+'LinkError').value = '';
}

function removeAutoplay(url) {
	if (url) return url.replace('&autoplay=1','');
	else return '';
}

function removeYtAutoplay() {
	var video_canvas = document.getElementById('videoPlayerWrapper');
	if (video_canvas) {
		var embed_obj = video_canvas.firstChild;
		if (embed_obj) {
			embed_obj.src = removeAutoplay(embed_obj.src);
			var obj_flashvars = embed_obj.getAttribute('flashvars');
			if (obj_flashvars) {
				embed_obj.flashvars = obj_flashvars.replace('&video_autoplay=1', ''); // for IE
				embed_obj.setAttribute('flashvars', obj_flashvars.replace('&video_autoplay=1', ''));
			}
		}video_canvas.innerHTML = video_canvas.innerHTML; // used to reload the video player in IE
	}
}

function clearPreviewCanvas() {
	var fbVideoPreview = document.getElementById('fbVideoPreview');
	var fbVideoPreviewDesc = document.getElementById('fbVideoPreviewDesc');
	if (fbVideoPreview) {
		fbVideoPreview.innerHTML = '';
		fbVideoPreviewDesc.innerHTML = '<center>Mouseover a video to preview</center>';
	}
}

function extractFbVideoSize(embed_html) {
	var re = new RegExp('<[^>]+width="?([^"]+)"?\\s+height="?([^"]+)"?[^>]*>', 'g');
	var video_size = re.exec(embed_html); // extract video dimensions
	if (video_size) {
		var embed_width = video_size[1];
		var embed_height = video_size[2];
		return [embed_width, embed_height];
	}re.lastIndex = 0; // reset lastIndex for next iteration
	return null;
}

function buildEditTimeHTML(div_id, dark) {
	var onchange_handler = div_id.indexOf('newNightCreate')==0? ' onchange="validateNewNightCreateEdit()"':'';
	var dark_class = dark? '_dark':'';
	return '<div class="edit_time_wrapper"><input id="'+div_id+'Month" maxlength="2" class="date_input_part'+dark_class+'"'+onchange_handler+' /> / <input id="'+div_id+'Day" maxlength="2" class="date_input_part'+dark_class+'"'+onchange_handler+' /> / <input id="'+div_id+'Year" maxlength="4" class="date_input_year'+dark_class+'"'+onchange_handler+' /><input id="'+div_id+'Hours" maxlength="2" class="date_input_part'+dark_class+'"'+onchange_handler+' /> : <input id="'+div_id+'Minutes" maxlength="2" class="date_input_part'+dark_class+'"'+onchange_handler+' /><select id="'+div_id+'AMPM" class="input_field_select'+dark_class+'"><option value="AM">AM</option><option value="PM" selected>PM</option></select>'+(div_id.indexOf('summary')!=0&&div_id.indexOf('newNightCreate')!=0?buildTimezoneDropdown(div_id, dark):'')+'</div>';
}

function buildTimezoneDropdown(div_id, dark, field_class) {
	var idAttr = "";
	if (div_id) {
		idAttr = ' id="'+div_id+'TZ"';
	}var dark_class = dark? '_dark':'';
	//return '<select'+idAttr+(typeof field_class!='undefined'?(field_class?' class="'+field_class+'"':''):' class="input_field_select'+dark_class)+'"><option value="-12">(GMT -12:00) Eniwetok, Kwajalein</option><option value="-11">(GMT -11:00) Midway Island, Samoa</option><option value="-10">(GMT -10:00) Hawaii</option><option value="-9">(GMT -9:00) Alaska</option><option value="-8">(GMT -8:00) PST, Alaska DT</option><option value="-7">(GMT -7:00) MST, PDT</option><option value="-6">(GMT -6:00) CST, MDT, Mexico City</option><option value="-5">(GMT -5:00) EST, CDT, Bogota</option><option value="-4">(GMT -4:00) EDT, Atlantic, Caracas</option><option value="-3.5">(GMT -3:30) Newfoundland, Atlantic DT</option><option value="-3">(GMT -3:00) Brazil, Buenos Aires</option><option value="-2">(GMT -2:00) Mid-Atlantic</option><option value="-1">(GMT -1:00) Azores, Cape Verde Islands</option><option value="0">(GMT) Western Europe, London</option><option value="1">(GMT +1:00) CET, Rome, Paris</option><option value="2">(GMT +2:00) CEST, Israel, South Africa</option><option value="3">(GMT +3:00) Baghdad, Moscow</option><option value="3.5">(GMT +3:30) Tehran</option><option value="4">(GMT +4:00) Abu Dhabi, Tbilisi</option><option value="4.5">(GMT +4:30) Kabul</option><option value="5">(GMT +5:00) Islamabad, Karachi</option><option value="5.5">(GMT +5:30) Bombay, New Delhi</option><option value="5.75">(GMT +5:45) Kathmandu</option><option value="6">(GMT +6:00) Dhaka, Colombo</option><option value="7">(GMT +7:00) Bangkok, Jakarta</option><option value="8">(GMT +8:00) Beijing, Hong Kong</option><option value="9">(GMT +9:00) Tokyo, Seoul</option><option value="9.5">(GMT +9:30) Adelaide, Darwin</option><option value="10">(GMT +10:00) Eastern Australia, Guam</option><option value="11">(GMT +11:00) Magadan, New Caledonia</option><option value="12">(GMT +12:00) Auckland</option><option value="13">(GMT +13:00) Phoenix Island</option><option value="14">(GMT +14:00) Line Islands</option></select>';
	return '<select'+idAttr+(typeof field_class!='undefined'?(field_class?' class="'+field_class+'"':''):' class="input_field_select'+dark_class)+'"><option value="-12">(GMT -12) Eniwetok, Kwajalein</option><option value="-11">(GMT -11) Midway Island, Samoa</option><option value="-10">(GMT -10) Hawaii</option><option value="-9">(GMT -9) Alaska Standard Time</option><option value="-8">(GMT -8) Pacific ST, Alaska Daylight Savings Time</option><option value="-7">(GMT -7) Mountain ST, Pacific DT</option><option value="-6">(GMT -6) Central ST, Mountain DT</option><option value="-5">(GMT -5) Eastern ST, Central DT</option><option value="-4">(GMT -4) Eastern DT, Atlantic</option><option value="-3.5">(GMT -3:30) Newfoundland, Atlantic DT</option><option value="-3">(GMT -3) Brazil, Buenos Aires</option><option value="-2">(GMT -2) Mid-Atlantic</option><option value="-1">(GMT -1) Azores, Cape Verde Islands</option><option value="0">(GMT) Western Europe, London</option><option value="1">(GMT +1) CET, Rome, Paris</option><option value="2">(GMT +2) CEST, Israel, South Africa</option><option value="3">(GMT +3) Baghdad, Moscow</option><option value="3.5">(GMT +3:30) Tehran</option><option value="4">(GMT +4) Abu Dhabi, Tbilisi</option><option value="4.5">(GMT +4:30) Kabul</option><option value="5">(GMT +5) Islamabad, Karachi</option><option value="5.5">(GMT +5:30) Bombay, New Delhi</option><option value="5.75">(GMT +5:45) Kathmandu</option><option value="6">(GMT +6) Dhaka, Colombo</option><option value="7">(GMT +7) Bangkok, Jakarta</option><option value="8">(GMT +8) Beijing, Hong Kong</option><option value="9">(GMT +9) Tokyo, Seoul</option><option value="9.5">(GMT +9:30) Adelaide, Darwin</option><option value="10">(GMT +10) Eastern Australia, Guam</option><option value="11">(GMT +11) Magadan, New Caledonia</option><option value="12">(GMT +12) Auckland</option><option value="13">(GMT +13) Phoenix Island</option><option value="14">(GMT +14) Line Islands</option></select>';
}

function removeHtmlTags(contents) {
	if (contents) {
		var processor_div = document.createElement('div');
		processor_div.innerHTML = contents;
		contents = processor_div.textContent;
		if (!contents) contents = processor_div.innerText; // for IE
		//if (contents) contents = contents.replace(new RegExp('</?(?:script|embed|object|frameset|frame|iframe|meta|link|style)(.|\\n)*?>', 'gi'), '');
		return contents?contents:'';
	}return '';
}

function ucfirst(str) {
	return str.charAt(0).toUpperCase() + str.slice(1);
}

function randomTime() {
	// return a random number between segment start and end
	var start_time = segmentData.start;
	var end_time = segmentData.end;
	try {
		start_time = parseInt(memoryCreationWizard.start_time.getTime()/1000, 10);
		end_time = parseInt(memoryCreationWizard.end_time.getTime()/1000, 10);
	} catch(err) {}
	return Math.round(Math.random()*(end_time-start_time))+parseInt(start_time, 10);
}

/**
 * Adjusts the time to ensure it falls within the segment.
 */
function adjustPointTime(utc_time) {
	var segmentData = window.segmentData,
		memoryCreationWizard = window.memoryCreationWizard;
	var start_time = segmentData.start;
	var end_time = segmentData.end;
	var start_month = segmentData.startMonth;
	var start_day = segmentData.startDay;
	var start_year = segmentData.startYear;
	var tzoffset = segmentData.tzoffset;
	try {
		start_time = parseInt(memoryCreationWizard.start_time.getTime()/1000, 10);
		end_time = parseInt(memoryCreationWizard.end_time.getTime()/1000, 10);
		start_month = memoryCreationWizard.start_month;
		start_day = memoryCreationWizard.start_day;
		start_year = memoryCreationWizard.start_year;
		tzoffset = memoryCreationWizard.timezone_offset;
	} catch(err) {}
	if ((utc_time < start_time) || (utc_time > end_time)) {
		// adjust time to original time but on current segment date
		var utc_normal = parseInt(new Date(start_month+'/'+start_day+'/'+start_year+' '+getFormattedTime(getAdjustedTime(utc_time*1000), 1)+offsetToGMTStr(tzoffset)).getTime()/1000, 10);

		// wrap excess time till it fits into segment range
		var segment_length = end_time - start_time;
		if (utc_normal > end_time) {
			var excess_time = utc_normal - end_time;
			var time_overlap = excess_time % segment_length;
			utc_normal = parseInt(start_time, 10) + time_overlap;
		} else if (utc_normal < start_time) {
			var excess_time = start_time - utc_normal;
			var time_overlap = excess_time % segment_length;
			utc_normal = parseInt(end_time) - time_overlap;
		}
		return utc_normal;
	} else {
		return utc_time;
	}
}

function setSegmentTense() {
	var segmentData = window.segmentData;
	segmentData.tense = 'present';
	var curr_time = parseInt(new Date().getTime()/1000, 10);
	if (curr_time > segmentData.end) segmentData.tense = 'past';
	else if (curr_time < segmentData.start) segmentData.tense = 'future';
}

function updateFriendCount() {
	var document = window.document;
	/*var memoryNumFriends = document.getElementById('memoryNumFriends');
	if (memoryNumFriends) {
		var num_friends = Math.max(0, $('#friendsTab>a').length - 1);
		memoryNumFriends.innerHTML = num_friends + ' friend' + (num_friends!=1?'s':'');
		//if (num_friends) document.getElementById('memoryFooterCallout').style.visibility = 'visible';
		var memoryNumFriendsWrapper = document.getElementById('memoryNumFriendsWrapper');
		var memoryNumPoints = document.getElementById('memoryNumPoints');
		var memoryNumPointsFew = document.getElementById('memoryNumPointsFew');
		var memoryNumPointsMany = document.getElementById('memoryNumPointsMany');
		if (num_friends < 5) {
			if (!memoryNumPoints) {
				memoryNumPointsMany.style.display = 'none';
				memoryNumPointsFew.style.display = 'block';
			} memoryNumFriendsWrapper.style.display = 'none';
		} else {
			memoryNumFriendsWrapper.style.display = 'inline';
			memoryNumPointsMany.style.display = '';
			memoryNumPointsFew.style.display = '';
		}
	}*/
	
	var nightFriendPicsWrapper = document.getElementById('nightFriendPicsWrapper');
	var nightFriendExpand = document.getElementById('nightFriendPicsExpand');
	if (nightFriendPicsWrapper) {
		var num_friends = nightFriendPicsWrapper.childNodes.length;
		if (num_friends > 7) nightFriendExpand.style.display = 'block';
		else nightFriendExpand.style.display = '';
		if (num_friends) document.getElementById("nightFriendsEmpty").style.display = 'none';
		document.getElementById('nightFriendCount').innerHTML = num_friends + ' ' + (num_friends==1?'person':'people');
		document.getElementById("nightFriendsLoading").style.display = "none";
	}
}

function offsetToGMTStr(tzoffset, lazy) {
	if (!lazy || lazy && tzoffset*-60 != new Date().getTimezoneOffset()) {
		var gmtStr = " GMT";
		var tzoffsetInt = parseInt(tzoffset, 10);
		var gmtOffset = tzoffsetInt*100 + (tzoffset-tzoffsetInt)*60;
		if (!lazy || lazy && gmtOffset) {
			if (gmtOffset >= 0) gmtStr += '+';
			gmtStr += gmtOffset;
		}if (lazy) gmtStr = gmtStr.replace(/(\d{2})$/, ':$1');
		return gmtStr;
	}return '';
}

function diaryIsCollapsed() {
	try {
		var retroDiaryEntriesExpand = document.getElementById('retroDiaryEntriesExpand');
		if (retroDiaryEntriesExpand.className == 'expand_btn') return 1;
	} catch(err) {}
	return 0;
}

function hideEmbed(revert) {
	if (navigator.userAgent.indexOf('Safari') != -1 && navigator.userAgent.indexOf('Chrome') == -1) {
		var videoPlayerWrapper = document.getElementById('videoPlayerWrapper');
		if (videoPlayerWrapper) {
			if (revert) videoPlayerWrapper.style.visibility = '';
			else videoPlayerWrapper.style.visibility = 'hidden';
		}
	}
}

function initColorbox(id, target, callback, oncomplete) {//maxWidth:'90%', maxHeight:'95%', 
	var args = {opacity:.75, inline:true, title:'&nbsp;', href:"#"+target, onComplete:function() {if (typeof oncomplete == 'function') oncomplete();hideEmbed();if (typeof updateColorboxScrollbars == 'function')updateColorboxScrollbars(target);}, onClosed:function() {if (typeof callback == 'function') callback();hideEmbed(1);}};
	if (!in_array(target, ['retroDiaryEdit', 'confirmPostToFacebook', 'memoryCreateComplete'])) args['width'] = '845px';
	if (target == 'filterMediaWrapper') args['width'] = '290px';
	else if (target == 'addMediaTagsWrapper') args['width'] = '975px';
	else if (target == 'addMediaTagsWrapperSmall') {args['href'] = '#addMediaTagsWrapper';args['width'] = '275px';}
	else if (target == 'contactSheetWrapper') args['width'] = '1090px';
	else if (target == 'newNightCreateWrapper') args['width'] = '745px';
	else if (target == 'aboutKapturWrapper') args['width'] = '872px';
	else if (target == 'privacyWrapper') args['width'] = '681px';
	else if (target == 'confirmPostToFacebook') {args['scrolling'] = false; /* args['maxWidth'] = '95%', args['maxHeight'] = '95%'; */}
	else if (target == 'memoryLinkWrapper') {args['width'] = '340px'}
	else if (target == 'memoryEmbedWrapper') {args['width'] = '450px'}
	else if (target == 'iPhotoWrapper') {args['width'] = '600px'}
	else if (target == 'notifyFriendsSelector') {args['width'] = '890px'}
	if (id) $("#"+id).colorbox(args);
	else $.colorbox(args);
}

function removeUrlParam(param, url) {
	return replaceUrlParam(param, '', url);
}

function replaceUrlParam(param, value, url) {
	if (!url) url = location.href;
	var param_str = param+'='+value;
	if (url.indexOf('?') != -1) {
		var page_regex = new RegExp('(\\?|&)('+param+'=[^&]*)');
		if (url.match(page_regex)) {
			if (value) url = url.replace(RegExp.$2, param_str);
			else {
				url = url.replace(RegExp.$1+RegExp.$2, '');
				if (url.indexOf('?') == -1) url = url.replace('&', '?');
			}
		} else if (value) {
			if (!url.match(/\?$/)) url += '&';
			url += param_str;
		}
	} else if (value) url += '?'+param_str;
	return url;
}

function updateSegmentUrl() {
	var url = location.href;
	if (!url.match(/\bsid=\w{64}\b/)) {
		url = replaceUrlParam('sts', '', url);
		url = replaceUrlParam('ets', '', url);
		url = replaceUrlParam('fid', '', url);
		url = replaceUrlParam('sid', segmentData.id, url);
		// var url = replaceUrlParam('sts', segmentData.start);
		// url = replaceUrlParam('ets', segmentData.end, url);
		setTimeout("location.href = '"+url+"'", 1500);
	}
}

function limitLen(str, maxLen) {
	if (str.length > maxLen) str = str.substr(0, maxLen).replace(/(^\s+)|(\s+$)/, "")+"..";
	return str;
}

function parsePrivacyIds(privacy_ids) {
	var privacy_keys = new Object();
	privacy_keys['autoimport'] = true;
	var keys = privacy_ids.split(',');
	for (var i in keys) {
		var privacy_key = keys[i].toString();
		if (privacy_key.indexOf('v') === 0) privacy_keys['view'] = privacy_key;
		else if (privacy_key.indexOf('c') === 0) privacy_keys['contribute'] = privacy_key;
		else if (privacy_key.indexOf('nai') === 0) privacy_keys['autoimport'] = false;
	}return privacy_keys;
}

function setIndexByValue(select_field, value) {
	for (var i=0; i<select_field.options.length; i++) {
		if (select_field.options[i].value == value)
			select_field.selectedIndex = i;
	}
}

function buildIsFriendFQL(owner_fbid) {
	return {
		fql: 'SELECT uid2 FROM friend WHERE uid1 = {0} AND uid2 = {1}',
		args: [loggedInUser, owner_fbid]
	};
}

function updateAttendBtnText(normal) {
	var optInText = document.getElementById('optInText');
	if (optInText) {
		if (!normal) {
			optInText.innerHTML = optInText.innerHTML.replace('was there', 'was not there').replace('will be', 'will not be').replace('am here', 'am not here'); // or insert 'not' as the third word
		} else optInText.innerHTML = optInText.innerHTML.replace(' not', '');
	}
}

function showAttendBtn(normal) {
	updateAttendBtnText(normal);
	var attendBtn = document.getElementById('attendBtn');
	if (attendBtn) {
		attendBtn.style.display = 'block';
		if ($.cookies.get("postAuthAction") == 'attend') { // auto confirm
			confirmAttend();$.cookies.set("postAuthAction", null);
		}
	}
}

function showLogoutBtn(hide) {
	var headerBarRightOnError = document.getElementById('headerBarRightOnError');
	if (headerBarRightOnError) headerBarRightOnError.style.display = hide?'':'block';
}

function chainCallFacebookQueries(queries, index, num_queries, callback_each, callback_all, total_response) {
	(function (queries, index, num_queries, callback_each, callback_all, total_response) {
		var FB = window.FB;
		if (!total_response) {
			total_response = [];
		}
		if (queries[index]) {
			if (true || FB.Data.queue.length) {
				/*setTimeout(function () {
					chainCallFacebookQueries(queries, index, num_queries, callback_each, callback_all, total_response);
				}, 10);
			} else {*/
				FB.api({method:'fql.query',query:queries[index]},function (fb_response) {
					total_response = total_response.concat(fb_response);
					safeCall(callback_each, [fb_response]);
					setTimeout(function () {
						chainCallFacebookQueries(queries, index+1, num_queries, callback_each, callback_all, total_response);
					}, 0);
				});
				/*queries[index].wait(function (fb_response) {
					total_response = total_response.concat(fb_response);
					setTimeout(function () {
						chainCallFacebookQueries(queries, index+1, num_queries, callback_each, callback_all, total_response);
					}, 100);
				});*/
			}
		} else {
			safeCall(callback_all, [total_response]);
		}
	})(queries, index, num_queries, callback_each, callback_all, total_response);
}

/**
 * processes multiple queries simultaneously.  If any query references others the
 * other one must occur previously to it
 */
function multiqueryFacebookFromApi (queries, callback) {
	"use strict";
	
	if (!FB.getAuthResponse()) {
		safeCall(callback, [[]]);
	}
	
	(function (queries, callback) {
		var num_queries = arrayLength(queries),
			processed_queries = {},
			query_fql = {},
			i, j, arg, num_args, args, fql, query, query_name, api_args, timeout,
			timed_out;

		//process queries for the api call
		for (i = 0; i < num_queries; i++) {
			query = queries[i];
			fql = query['fql'];
			args = query['args'];
			num_args = arrayLength(args);

			//handle references to other queries
			for (j = 0; j < num_args; j++) {
				arg = args[j];
				query_name = arg && arg['name'];
				if ((typeof arg) == 'object') {
					if (query_name && (arg == processed_queries[query_name])) {
						//for other queries that will have their values returned
						args[j] = '#' + query_name;
					}
				}
			}

			query_name = 'q' + i;
			query['name'] = query_name;
			processed_queries[query_name] = query;
			query_fql[query_name] = formatString(fql, args);

		}

		api_args = {
			method : 'fql.multiquery',
			queries : query_fql
		};

		FB.api(api_args, function (fb_response) {
			var processed_response = [],
				response_length = arrayLength(fb_response),
				query_response, result, query_name, query_result, error_msg,
				error_code, query_number;

			if (timed_out) {
				return;
			}
			
			clearTimeout(timeout);
			
			error_code = fb_response['error_code'];
			
			//if the session was expired try to log in then try again
			if (error_code == 102) {
				FB.getLoginStatus(function () {
					var session = getFacebookSession();
					if (session) {
						setTimeout(function () {
							multiqueryFacebookFromApi(queries, callback);
						},100);
					} else {
						safeCall(callback, [[]]);
					}
				});
				return;
			}
			
			if (fb_response['error_code']) {
				error_msg = error_code + ': ' + fb_response['error_msg'];
				fb_response = null;
				processed_response = null;
			}

			for (i = 0; i < response_length; i++) {
				query_response = fb_response[i];
				query_name = query_response['name'];
				query_number = parseInt(query_name.split('q')[1], 10);
				query_result = query_response['fql_result_set'];
				processed_queries[query_name]['value'] = query_result;
				processed_response[query_number] = query_result;
			}

			safeCall(callback, [processed_response]);

			if (error_msg && window.console) {
				safeCall(console.error, [error_msg], console);
			}
		});
		
		timeout = setTimeout(function () {
			timed_out = true;
			safeCall(callback, [[]]);
		}, 15000);
	})(queries, callback);
}

function queryFacebookFromApi (fql, args, callback) {
	"use strict";
	
	if (!FB.getAuthResponse()) {
		safeCall(callback, [[]]);
	}
	
	(function (fql, args, callback) {
		var api_args, query, error_code, error_msg, timeout, timed_out;
		query = formatString(fql, args);
	
		api_args = {
			method : 'fql.query',
			query : query
		}
		FB.api(api_args, function (fb_response) {
			var error_msg = null;
			
			if (timed_out) {
				return;
			}
			
			clearTimeout(timeout);
			
			//on an error return null
			error_code = fb_response['error_code'];
			if (error_code) {
				error_msg = fb_response['error_msg'];
				error_msg = error_code + ': ' + error_msg;
				fb_response = null;

				//if the session was expired try to log in then try again
				if (error_code == 102) {
					FB.getLoginStatus(function () {
						var session = getFacebookSession();
						if (session) {
							setTimeout(function () {
								queryFacebookFromApi(fql, args, callback);
							},100);
						} else {
							safeCall(callback, [[]]);
						}
					});
					return;
				}
			}

			safeCall(callback, [fb_response]);

			if (error_msg && window.console && ((typeof window.console.error) == 'function')) {
				console.error(error_msg);
			}
		});
		
		timeout = setTimeout(function () {
			timed_out = true;
			safeCall(callback, [[]]);
		}, 15000);
	})(fql, args, callback);
}

/**
 * submits a facebook query and allows handling of the response in an asynchronus
 * manner.
 *
 */
function queryFacebook(fql, args, callback) {
	queryFacebookFromApi (fql, args, callback);
	return;
	if (window.FacebookProxy) {
		//will fail if we are not using the proxy because FacebookProxy is not defined
		FacebookProxy.Data.query(fql, args, callback);
	} else {
		var query = FB.Data.query.apply(null, [fql].concat(args));
		query.wait(function (data) {
			safeCall(callback, [data]);
		});
	}
}

function formatString(s, args) {
	var args_length = arrayLength(args),
		r = s,
		i, arg, rex;

	for (i = 0; i < args_length; i++) {
		arg = args[i]
		
		r = r.replace(new RegExp('\\{' + i + '\\}', 'g'), arg);
	}
	
	return r;
}

function facebookGraphCall(args) {
	var path = '/' + args['node'],
		method = 'get',
		params = {},
		callback = args['callback'];
	
	if (args['connection']) {
		path += '/' + args['connection'];
	}
	
	if (args['fields']) {
		params['fields'] = args['fields'];
	}
	
	if (args['limit']) {
		params['limit'] = args['limit'];
	}
	
	//setting the callback to null and use of timeout_cleared try to prevent the
	//callback in the FB.api function from executing multiple times.  tiemout_cleared
	//also tries to prevent FB.api from executing again if it just called its callback (which
	// could happen if the interval callback was on the stack closer to the top and at the same
	// time as the FB.api callback function).
	(function (path, method, params, callback, max_tries, timeout) {
		var tries = 1,
			timeout_cleared = false,
			api_call = function () {
				if (!timeout_cleared) {
					if (tries < max_tries) {
						tries++;
						FB.api(path, method, params, function (facebook_response) {
							clearInterval(api_interval);
							if (!timeout_cleared) {
								if (facebook_response && facebook_response['error']) {
									//failed calls will be turned into null
									facebook_response = null;
								}
								timeout_cleared = true;
								safeCall(callback, [facebook_response]);
								callback = null;  //clear the callback so it cannot be called again
							}
						});
					} else {
						safeCall(callback, [null]);
					}
				}
			},
			api_interval = setInterval(api_call, timeout);
		
		api_call();
	})(path, method, params, callback, 3, 5000);
}

function multipleQueryFacebook(queries, callback, low_priority) {
	multiqueryFacebookFromApi(queries, callback, low_priority);
	return;
	var FB = window.FB;
	if (!FB.multipleQueryRunning) {
		FB.multipleQueryRunning = 1;
		var i = 0, key = null, query = [];
		if (window.FacebookProxy) {
			FacebookProxy.Data.multipleQuery(queries, callback)
		} else {
			for (i = 0; i < queries.length; i++) {
				query[i] = FB.Data.query.apply(null, [queries[i].fql].concat(queries[i].args));
				queries[i].query = query[i];
				queries[i].toString = function () {
					return this.query.toString();
				}
			}
			
			FB.Data.waitOn(query, function (queries, callback) {
				return function (fb_response) {
					var i = 0;delete FB.multipleQueryRunning;
					for (i = 0; i < queries.length; i++) {
						queries[i].value = queries[i].query.value;
					}
					callback(fb_response);
					if (FB.multipleQueryQueue && FB.multipleQueryQueue.length) {
						var query_next = FB.multipleQueryQueue.pop();
						multipleQueryFacebook(query_next[0], query_next[1], low_priority);
					}
				}
			}(queries, callback));
		}
	} else {
		if (!FB.multipleQueryQueue) FB.multipleQueryQueue = [];
		if (!low_priority) FB.multipleQueryQueue.push([queries, callback]);
		else FB.multipleQueryQueue.unshift([queries, callback]);
	}
}

/**
 * get the current facebook session if one is available
 */
function getFacebookSession(response) {
	//if a response is passed try to get the session from that
	if (response) {
		if (response.authResponse) {
			return response.authResponse;
		} else if (response.session) {
			return response.sesssion();
		}
	}
	
	//if facebook is defined then get the session there
	if (window.FB) {
		try {
			return FB.getAuthResponse();
		} catch (err) {
			return FB.getSession();
		}
	}
	
	//if no response and no FB then there is no session
	return null;
}

function getFacebookUserId(session) {
	if (!session) {
		session = getFacebookSession();
	}
	
	if (session) {
		return (session.userID || session.uid || null);
	} else {
		return null;
	}
}

function getFacebookPermissions(callback) {
	if (!window.FB) {
		safeCall(callback, [{}]);
		return;
	}
	
	(function (callback) {
		FB.api('/me/permissions', function (response) {
			if (response && response['data'] && response['data'][0]) {
				response = response['data'][0];
			} else {
				response = {};
			}

			safeCall(callback, [response]);
		});
	})(callback);
}

function getFacebookExtendedPermissions(perms, callback) {
	if (!window.FB) {
		safeCall(callback, [null]);
		return;
	}
	
	(function (perms, callback) {
		FB.login(function (login_response) {
				if (!login_response || !login_response.authResponse) {
					login_response = null;
				}
				safeCall(callback, [login_response]);
				//needed to prevent the cookie from being cleared
				FB.getLoginStatus();
		}, {scope:perms});
	})(perms, callback);
}

function getFacebookProfilePicture(user_id) {
	if (!user_id) {
		user_id = 1;
	}
	
	return 'https://graph.facebook.com/' + user_id + '/picture';
}

function showAboutProfile(id, sid, yt_hash, cover_img) {
	$('#bioWrapper').children().css('display', '');
	var bioSlideshowMusicWrapper = document.getElementById('bioSlideshowMusicWrapper');
	var bioSlideshowMusic = document.getElementById('bioSlideshowMusic');
	document.getElementById('about'+id).style.display = 'block';
	var domain_url = 'http://www.kaptur.com/';
	if (location.href.indexOf('http://stg.') === 0) domain_url = 'http://stg.kaptur.com/';
	var segment_url = domain_url+'?p=n&sid='+sid;
	var swf_src = domain_url+'v2/resources/slickboard/slideshow.swf?xml_source='+escape(domain_url)+'%3Fp%3Dslickboard_xml%26sid%3D'+sid+'%26about_bio%3D1';
//http%3A%2F%2Fdq.aws-dev.kaptur.com%2F%3Fp%3Dslickboard_xml%26sid%3D94acdd9c22b2745e9c9004f8122fe85cfa7526ffb35c4a112d11bf2acdf7b761%26about_bio%3D1';
	document.getElementById('aboutSlideshowWrapper').innerHTML = '<object id="aboutSlideshow" type="application/x-shockwave-flash" width="452" height="282px" data="'+swf_src+'"><param name="movie" value="'+swf_src+'" /><a href="'+segment_url+'" target="_blank"><div style="margin-left:29px;width:376px;text-align:center"><img src="'+cover_img+'" style="max-width:376px;max-height:282px;border:0" /></div></a></object>';
	document.getElementById('aboutSlideshowLink').href = segment_url;
	
	if (yt_hash) {
		bioSlideshowMusicWrapper.style.display = '';
		bioSlideshowMusic.innerHTML = '<embed width="200" height="25" allowscriptaccess="always" quality="high" id="bioSlideshowMusicPlayer" src="http://www.youtube.com/v/'+yt_hash+'&amp;autoplay=1" type="application/x-shockwave-flash"></embed>';
	} else {
		bioSlideshowMusicWrapper.style.display = 'none';
		bioSlideshowMusic.innerHTML = '';
	}document.getElementById('bioWrapper').style.display = '';
	document.getElementById('aboutSlideshowMusicWrapper').style.display = '';
	document.getElementById('bioEmptyWrapper').style.display = 'none';
}

function stopAboutSlideshowMusic() {
	var bioSlideshowMusicPlayer = document.getElementById('bioSlideshowMusicPlayer');
	if (bioSlideshowMusicPlayer) {
		document.getElementById('bioSlideshowMusic').innerHTML = '<embed width="200" height="25" allowscriptaccess="always" quality="high" id="bioSlideshowMusicPlayer" src="'+removeAutoplay(bioSlideshowMusicPlayer.src)+'" type="application/x-shockwave-flash"></embed>';
	}
}

function parseCookies() {
	var cookies = document.cookie.split('; ');
	var cookies_hash = {};
	for (var i = 0; i < cookies.length; i++) {
		var cookie_item = cookies[i];
		var separator_index = cookie_item.indexOf('=')+1;
		cookies_hash[cookie_item.substr(0, separator_index-1)] = cookie_item.substr(separator_index);
	}
	return cookies_hash;
}

function getObjectType (type) {
	var obj_type = -1;
	switch (type) {
		case "photo":
			obj_type = 5;
			break;
	}
	
	return obj_type;
}

function parseDate(date, timezone_offset, format) {
    var day, month, year, d;
    
    date = date.split('/');
    if (date) {
        day = date[1];
        month = date[0] - 1;
        year = date[2];
        
        d = new Date();
        d.setUTCFullYear(year, month, day);
        d.setUTCHours(0, 0, 0, 0);
        if (timezone_offset) {
            d.setMinutes(Math.floor(timezone_offset * -60));
        }
        if (!d.getTime()) {
            d = null;
        }
    }
    
    return d;
}

var getPageBaseUrl = (function () {
	var url = location.protocol + '//' + location.host + '/';
	return function () {
		return url;
	};
})();

function isMobile() {
	if (navigator.userAgent && (navigator.userAgent.match(/Android/i) ||
		navigator.userAgent.match(/webOS/i) ||
		navigator.userAgent.match(/iPhone/i) ||
		navigator.userAgent.match(/iPod/i) ||
		navigator.userAgent.match(/iPad/i))
	) return true;
}

function isMobileApp() {
	if (!dataFlags) dataFlags = {};
	if (dataFlags.mobileUser == null) {
		var isMobile = (navigator.userAgent.indexOf('Mobile') != -1 && navigator.userAgent.indexOf('Safari') == -1);
		dataFlags.mobileUser = isMobile;
		return isMobile;
	} return dataFlags.mobileUser;
}

/**
 * days in a month with the month starting at 0
 */
function getDaysInMonth(month, year) {
	month = parseInt(month, 10);
	year = parseInt(year, 10);
	if (month % 2) {
		if (month == 1) {
			if (isLeapYear(year)) {
				return 29;
			} else {
				return 28;
			}
		} else if (month < 7) {
			return 30;
		} else {
			return 31;
		}
	} else {
		if (month < 7) {
			return 31;
		} else {
			return 30;
		}
	}
}

function isLeapYear(year) {
	if (year % 4) {
		return false;
	} else {
		if (year % 100) {
			return true;
		} else {
			if (year % 400) {
				return false;
			} else {
				return true;
			}
		}
	}
}

