/* meal editing scripts */
function addFileField() {
	// find out how many fields we have -- each field is followed by a text node, and the whole thing starts out with a text node
	// so calculate appropriately
	//if ($("fileFields").childNodes.length == 3)
	//	lastFieldNumber = 0; // special case to start, since there's two blank text nodes
	//else
	lastFieldNumber = $("fileFields").childNodes.length - 3;

	lastField = $("pics[" + (lastFieldNumber) + "][uploaded_data]");
	if (lastField.value.length > 0) { // if we have a file there 
		newFileField = document.createElement("input");
		newFileField.type = "file";
		newFileField.id = "pics[" + (lastFieldNumber + 1) + "][uploaded_data]";
		newFileField.name = newFileField.id;
		newFileField.onchange = addFileField;
		
		div = document.createElement("div");
		div.appendChild(newFileField);
		$("fileFields").appendChild(div);
	}
}

/* name and message functions */
function fileFieldIdFromId(id){
	return "pics[" + id + "][uploaded_data]";
}

function formId(fileFieldId){
	return "form" + fileFieldId;
}

function fileFieldFromFormId(formId){
	return formId.replace(/form/, "");
}

function uploadingMessageId(fileFieldId) {
	return "message" + fileFieldId;
}

function cancelLinkId(fileFieldId) {
	return "cancelLink" + fileFieldId
}

function restartLinkId(fileFieldId) {
	return "restartLink" + fileFieldId
}

function uploadingMessageBase(fileFieldId){
	return "Uploading " + $(fileFieldId).value + "...";
}

function uploadingMessageInProgress(fileFieldId) {
	return uploadingMessageBase(fileFieldId) + " (" + cancelMessage(fileFieldId) + ")";
}

function uploadingMessageComplete(fileFieldId){
	return uploadingMessageBase(fileFieldId) + "done!";
}

function uploadingMessagePossibleTimeout(fileFieldId) {
	return uploadingMessageBase(fileFieldId) + "this seems to be taking a while.  (" + restartMessage(fileFieldId) + ") (" + cancelMessage(fileFieldId) + ")";
}

function uploadingMessageRetryAfterError(fileFieldId) {
	return uploadingMessageBase(fileFieldId) + "an error occurred!  Retrying upload...  (" + cancelMessage(fileFieldId) + ")";
}

function restartMessage(fileFieldId) {
	return "<a href='#' id='" + restartLinkId(fileFieldId) + "' onclick='resubmitForm(\"" + fileFieldId + "\"); return false;'>restart upload</a>";
}

function cancelMessage(fileFieldId) {
	return "<a href='#' id='" + cancelLinkId(fileFieldId) + "' onclick='cancelUpload(\"" + fileFieldId + "\"); return false;'>cancel</a>";
}

/* timer and status functions */
var fileUploadTimers = [];

function setUploadTimer(fileFieldId) {
	if (!fileUploadTimers[fileFieldId])
		fileUploadTimers[fileFieldId] = {};
		
	fileUploadTimers[fileFieldId]["upload"] = setTimeout("autoSubmit('" + fileFieldId + "')", 2000);
	fileUploadTimers[fileFieldId]["status"] = "started";
}

function clearUploadTimer(fileFieldId){
	if (fileUploadTimers[fileFieldId])
		clearTimeout(fileUploadTimers[fileFieldId]["upload"]);
}

function setTimeoutTimer(fileFieldId){
	if (!fileUploadTimers[fileFieldId])
		fileUploadTimers[fileFieldId] = {};
		
	fileUploadTimers[fileFieldId]["timeout"] = setTimeout("possibleTimeout('" + fileFieldId + "')", 60000);	
}

function clearTimeoutTimer(fileFieldId){
	if (fileUploadTimers[fileFieldId])
		clearTimeout(fileUploadTimers[fileFieldId]["timeout"]);	
}

function uploadComplete(fileFieldId) {
	clearTimeoutTimer(fileFieldId);
	fileUploadTimers[fileFieldId]["status"] = "complete";
}

function wasUploadCanceled(fileFieldId) {
	return fileUploadTimers[fileFieldId]["status"] == "canceled";
}

function setCanceledStatus(fileFieldId) {
	clearTimeoutTimer(fileFieldId);
	fileUploadTimers[fileFieldId]["status"] = "canceled";
	$(uploadingMessageId(fileFieldId)).innerHTML = "File " + $(fileFieldId).value + " canceled.  " + restartMessage(fileFieldId);	
}

function clearCancellation(fileFieldId) {
	fileUploadTimers[fileFieldId]["status"] = "started";
	//$(uploadingMessageId(fileFieldId)).innerHTML = "File " + $(fileFieldId).value + " restarting.";	
}


function uploadsInProgress() {
	uploadNodes = $("fileFields").descendants();
	currentlyUploading = [];
	for (i = 0; i < uploadNodes.length; i++){
		if (uploadNodes[i].tagName == "FORM"){
			fileFieldId = fileFieldFromFormId(uploadNodes[i].id);
			//console.log("Got %s from %s", fileFieldId, uploadNodes[i].id);
			if (fileUploadTimers[fileFieldId] && fileUploadTimers[fileFieldId]["status"] == "started")
				currentlyUploading.push(fileFieldId);
		}
	}
	return currentlyUploading;
}

/* DOM manipulation */

function addiFrameFileField(field){
	fileFields = $("fileFields").descendants();
	//console.log("Adding file field to list of %d fields", fileFields.length);
	form = $(formId(fileFields.length - 1));
	
	if (fileFields.length == 0 || !field || field.value.length > 0) {
		//console.log("Creating file field.");
		// if the last field has been set
		newFieldId = fileFieldIdFromId(fileFields.length);
		
		//console.log("Creating file field.");
		newFileField = document.createElement("input");
		newFileField.type = "file";
		newFileField.id = newFieldId;
		newFileField.name = newFileField.id;
		newFileField.onchange = function() { 
			//console.log("Submitting timer.");
			setAutoSubmitTimer(newFileField);
		};
		
		// create the iframe
		//console.log("Creating iFrame.");
		iFrame = document.createElement("iframe");
		iFrame.className = "hidden";
		iFrame.id = "iFrame" + newFieldId;
		iFrame.name = iFrame.id;
		
		// create the form
		//console.log("Creating form.");
		form = document.createElement("form");
		form.method = "POST";
		form.className = "iFrameFileUpload";
		form.action = "/meal/presubmit_picture";
		form.target = iFrame.id;
		form.id = formId(newFieldId);
		form.enctype = "multipart/form-data";
		
		// add the form
		//console.log("Appending form.");
		form.appendChild(newFileField);
		$("fileFields").appendChild(form);
		$("fileFields").appendChild(iFrame);
		//console.log("Form appended.");
	}
	//else
		//console.log("Not adding.");
}

function resubmitForm(fileFieldId, isError){
	// copies a form element, moving its children to the new copy, in order to submit it again
	// since Firefix 3 (at least) won't let you submit a form through Javascript twice
	formToCopy = $(formId(fileFieldId));
		
	form = document.createElement("form");
	form.method = formToCopy.method;
	form.className = formToCopy.className;
	form.action = formToCopy.action;
	form.target = formToCopy.target;
	form.id = formToCopy.id;
	form.enctype = formToCopy.enctype;
	
	elementsToCopy = formToCopy.descendants();
	for (i = 0; i < elementsToCopy.length; i++){
		element = elementsToCopy[i];
		//console.log("Appending child %s", element);
		form.appendChild(element);
	}
	
	parent = formToCopy.parentNode;
	formToCopy.parentNode.removeChild(formToCopy)
	parent.appendChild(form);
	//console.log("Form appended.");
	
	clearCancellation(fileFieldId);
	
	autoSubmit(fileFieldId, isError);
}

function setAutoSubmitTimer(field){
	//console.log("Starting to set timer.");
	clearUploadTimer(field.id);
	
	if (field.value.length > 0) {
		setUploadTimer(field.id);
		//console.log("Timer set.");
	
		// add the next one
		addiFrameFileField(field);
	}
	else {
		//console.log("Timer not set -- field %s is empty.", field.id)
	}
}

function autoSubmit(fileFieldId, isError) {
	// submit the form through the iFrame
	// also set up the autoresponse
	// the iFrame result will trigger that via the onFileUpload method
	//console.log("Auto-submitting (error? %d).", isError);
	if (!document.onFileUpload)
		document.onFileUpload = fileUploadCompleted;	

	// get the form and replace it with an uploading box
	form = $(formId(fileFieldId));
	fileField = $(fileFieldId);
	//console.log("Form element is %s", form);
	
	if (!$(uploadingMessageId(fileFieldId))) {
		uploading = document.createElement("div");
		uploading.id = uploadingMessageId(fileFieldId);
		form.appendChild(uploading);
	}

	if (!isError) {
		cancelLink = $(cancelLinkId(fileFieldId));
		if (cancelLink)
			cancelLink.parentNode.removeChild(cancelLink);
		
		restartLink = $(restartLinkId(fileFieldId));
		if (restartLink)
			restartLink.parentNode.removeChild(restartLink);
			
		uploading.innerHTML = uploadingMessageInProgress(fileFieldId);
	}
	else
		uploading.innerHTML = uploadingMessageRetryAfterError(fileFieldId);
		
	fileField.style.display = "none";
	
	// set the timer to alert the user if this is taking too long so they can restart if desired
	setTimeoutTimer(fileFieldId);
		
	//console.log("Submitting form.");
	//formSubmitted()
	form.submit();
	//console.log("Form submitted.");
}

function cancelUpload(fileFieldId){
	setCanceledStatus(fileFieldId);
}

function possibleTimeout(fileFieldId) {
	// we simply update the form
	$(uploadingMessageId(fileFieldId)).innerHTML = uploadingMessagePossibleTimeout(fileFieldId);
}

function fileUploadCompleted(data) {
	//console.log("Upload completed.");
	
	fileDatabaseId = data["database_id"];
	filePageId = data["page_id"];
	fileImageSrc = data["pic_url"];

	// check for cancellation
	if (wasUploadCanceled(fileFieldIdFromId(filePageId))) {
		//console.log("Upload was canceled.");
		return;
	}

	if (!(data["status"] == "success" && fileDatabaseId && filePageId && fileImageSrc)) {
		// renew the form, then submit it again
	//console.log("Error! %s, %s", data["status"], fileDatabaseId && filePageId && fileImageSrc);
		resubmitForm(fileFieldIdFromId(filePageId), true);
		return;
	}
	// need to check for error here
	
	
	// add the uploaded picture to the list to add
	$("uploadedPics").value += "," + fileDatabaseId;

	uploadComplete(fileFieldIdFromId(filePageId));

	// remove the uploading form
	message = $(uploadingMessageId(fileFieldIdFromId(filePageId)));
	message.innerHTML = uploadingMessageComplete(fileFieldIdFromId(filePageId));
	
	// show the image
	div = document.createElement("div");
	div.className = "imageHolderInGallery";
	div.id = "imageHolder" + fileDatabaseId;
	
	anchor = document.createElement("a");
	anchor.href = "#"
	anchor.id = fileDatabaseId;
	anchor.onclick = function() { deleteToggle(this.id); return false; };
	
	img = document.createElement("img");
	img.src = fileImageSrc;

	anchor.appendChild(img);
	div.appendChild(anchor);
	$("galleryImages").appendChild(div);
}

/* meal submission */

/*
function submitMeal() {
	statusDiv = $("statusMessage");
	statusDiv.innerHTML = "Submitting meal...";
	
	$('mealForm').onsubmit();
}
*/

/* facebook */
/* respond to the button being clicked */
function facebook_button_onclick(nextJS) { 
	// initialize Facebook 
	FB.init("648eb898d6cf1d3d0521ebb86397c816", "/xd_receiver.html"); 
	// set up the callback 
	FB.Facebook.get_sessionState().waitUntilReady(function() { 
		// when we're authenticated, send the browser to a  page to process the facebook authentication
		// and then send it back to the current page
		if (!nextJS)
			window.location = "/account/account?tab=facebook&return=" + escape(window.location);
		else
			if (typeof nextJS == "function")
				nextJS();
			else if (typeof nextJS == "string")
				eval(nextJS);
	}); // trigger the whole process FB.Connect.requireSession(); } 
}

function newFBAccountLinkComplete(){
	beginTabLoading();
	$("facebookSettingsForm").onsubmit();
}

function fbLogout() { 
	// initialize Facebook then log the user out
	FB.Connect.logout(function() {});	
}

/* google maps */
// allows you to store map data for multiple maps in a hash based on the map container's ID
// this should also allow us to support Ajax-delivered maps...

var mapData = {};

function initializeMap(mapName, centerLat, centerLng, dataSet, markerMakerFunction){
  if (!GBrowserIsCompatible())
		return false;
	
	var newMap;
	
	eval(mapName + "Object = new GMap2(document.getElementById('" + mapName + "')); newMap = " + mapName + "Object;");

	if (!newMap)
		return false;
	
	newMap.setCenter(new GLatLng(centerLat, centerLng));
	bounds = new GLatLngBounds();
		
	for (i = 0; i < dataSet.length; i++) {
		newMarker = markerMakerFunction(dataSet[i]);
		
		if (newMarker) {
			newMap.addOverlay(newMarker);
			bounds.extend(newMarker.getLatLng());
		}
	}
	
	if (dataSet.length > 1) {
	  newMap.setZoom(newMap.getBoundsZoomLevel(bounds));
	}
	else
	  newMap.setZoom(11);
	  
	newMap.addControl(new GSmallMapControl());
	
	newMap.markerMakerFunction = markerMakerFunction;

	return true;
}

var googleGeocoder;

function updateLocation(dataField, mapName) {
	// get the coordinates first
	//console.log("Updating with coordinates %s", $(dataField).value);
	//console.log("Data field is %s", dataField)
	
	if (!googleGeocoder) 
		googleGeocoder = new GClientGeocoder();
	
	googleGeocoder.getLatLng($(dataField).value, function(point){ newCenter(point, mapName) });
}

function newCenter(point, mapName) {
	if (!point) // we should probably alert the user somehow
		return false;
		
	var objectForMap, mapInitializer, dataSet;
	try {
		eval("objectForMap = " + mapName + "Object;")
		eval("mapInitializer = " + mapName + "MapInitializer; dataSet = mapData[\"" + mapName + "\"];");
	}
	catch(e) {
		mapInitializer = false;
	}

	if (!objectForMap && mapInitializer && $(mapName) && dataSet) {
		// we have a map waiting to be initialized
		mapInitializer = mapInitializer.replace(/<CTRLAT>/, point.lat() + "").replace(/<CTRLNG>/, point.lng() + "");
		if (!dataSet) 
				eval(mapName + "Data = [{lat: " + point.lat() + ", lng: " + point.lng() + " }];");
		else {
			dataSet[0].lat = point.lat();
			dataSet[0].lng = point.lng();
		}

		$("meal_location").value = dataSet[0].lat + "/" + dataSet[0].lng		
		eval(mapInitializer);
	}
	else if (objectForMap) {
		// we have an already initialized map
		objectForMap.setCenter(point);
		objectForMap.clearOverlays();
		if (objectForMap.markerMakerFunction){
			marker = objectForMap.markerMakerFunction({ lat: point.lat(), lng: point.lng() })
			objectForMap.addOverlay(marker);
			$("meal_location").value = marker.getLatLng().lat() + "/" + marker.getLatLng().lng();
		}
	}
	
	$("location").value = $("meal_location").value;
}

function createMealMarker(mealData) {
  // Set up our GMarkerOptions object
  markerOptions = { draggable:false };
	var point = new GLatLng(mealData.lat, mealData.lng);
  var marker = new GMarker(point, markerOptions);

  GEvent.addListener(marker, "click", function() {
    marker.openInfoWindowHtml("<div class='markerText'><a href='/" + mealData.id + "'>" + mealData.username + "'s " + mealData.name + "</a><br/>" + mealData.description + "</div><div class='clearFloat'>&nbsp;</div>");
  });

  return marker;
}

function createSingleMealMarker(mealData) {
  // Set up our GMarkerOptions object
  markerOptions = { draggable:false };
	var point = new GLatLng(mealData.lat, mealData.lng);
  var marker = new GMarker(point, markerOptions);

  return marker;
}

function createEditableMealMarker(mealData) {
  // Set up our GMarkerOptions object
  markerOptions = { draggable:true };
	var point = new GLatLng(mealData.lat, mealData.lng);
  var marker = new GMarker(point, markerOptions);

  GEvent.addListener(marker, "dragend", function(mark) {
    $("location").value = marker.getLatLng().lat() + "/" + marker.getLatLng().lng();
  });

  return marker;
}


/* meal editing - picture deletion */

var verified = false;

function checkForDeletions(){
	if (!verified){
		if ($("picsToDelete").value != "")
			verified = confirm("Are you sure you want to delete these pictures?  Once deleted, they cannot be recovered.  (You can always upload them again, of course.)");
		else
			verified = true;
	}
	return verified;
}

function ensureAllUploadsDone() {
	goingUploads = uploadsInProgress();
	if (goingUploads.length > 0)
		return confirm("There are " + goingUploads.length + " uploads still in progress.  Do you want to abort them?  If not, hit cancel and wait for them to complete.");
	else
		return true;
}

function deleteToggle(id){
	
	// add or remove the image from the list 
	picsThere = $("picsToDelete").value.split(",")
	undeleting = false;

	for (i = 0; i < picsThere.length; i++){
			if (picsThere[i] == id){
			picsThere.splice(i, 1);
			undeleting = true;
		}
	}

	if (!undeleting)
		picsThere.push(id);
		
	$("picsToDelete").value = picsThere.join(",");
	
	// now change the look
	if (undeleting)
		$("imageHolder" + id).className = $("imageHolder" + id).className.replace(/imageMarkedToDelete/, "");
	else
		$("imageHolder" + id).className += " imageMarkedToDelete";
}

function submitMeal() {
//console.log("Submit meal called.");
	if (!checkForDeletions() || !ensureAllUploadsDone()) {
		verified = false;
		return false;
	}
	
	$("mealForm").onsubmit();
	
	try { 
		// lightwindow hasn't been thoroughly tested on other platforms, and I don't want a javascript error here to break meal submission
		if (myLightWindow) {
			statusMessage = document.createElement("div");
			statusMessage.id = "statusMessage";
			statusMessage.className = "statusMessage";
			statusMessage.innerHTML = "Processing Meal...";
			$("statusMessageContainer").appendChild(statusMessage);
		
			myLightWindow.activateWindow({href: '#statusMessageContainer', height: 30, width: 300});
		
			statusMessage.parentNode.removeChild(statusMessage);
		}
	}
	catch (e){}
}

function processMealSubmission(request) {
	//console.log("Meal submission received!");
	
	data = request.responseJSON;
	errorString = "An error occurred!  Your meal may have been created -- please open a new window and check the home page."
	if (!data) {
		alert(errorString);
		return;
	}
	
	if (data["action"] == "facebook") {
		$("statusMessage").innerHTML = "Communicating with Facebook...";
		//FB.Connect.showFeedDialog(data["template_id"], data["template_data"], null, null, null, FB.RequireConnect.promptConnect, function() { mealProcessingComplete(data["destination"]) }, "Want to share this meal?", story);		
		//streamPublish(String user_message,  Object attachment,  Object action_links,  String target_id,  String user_message_prompt,  Function callback,  Boolean auto_publish,  String actor_id)
		FB.Connect.streamPublish(data["user_message"], data["attachment"], data["action_link"], null, data["user_message_prompt"], function() { mealProcessingComplete(data["destination"]) })
	}
	else if (data["destination"]){
		mealProcessingComplete(data["destination"]);
	}
	else
		alert(errorString);
}

function mealProcessingComplete(destination) {
	//console.log("Meal completed!");
	$("statusMessage").innerHTML = "Loading your meal...";
	window.location = destination;
}

/* tabs */
var currentTab;

function loadDefaultTab(tabName, url){
	new Ajax.Request(url, 
					{ onSuccess: function(response) {
							switchTabTo(tabName, response);
						}
					}
				);
}

function beginTabLoading() {
	document.getElementById("tabLoadingImage").style.visibility = "visible";
}

function endTabLoading() {
	$("tabLoadingImage").style.visibility = "hidden";
}


function switchTabTo(tab, request) {
	// swap the active status for the formerly current and current
  
 	if (currentTab){
		$(currentTab + "LinkInactive").style.display = "none";
		$(currentTab + "Link").style.display = "inline";
		//$(currentTab + "Link").className = "inactiveTab";
		$(currentTab + "Body").style.display = "none";
 	}

	currentTab = tab;
	//$(currentTab + "LinkInactive").className = "activeTab";
	$(currentTab + "LinkInactive").style.display = "inline";
	$(currentTab + "Link").style.display = "none";
	$(currentTab + "Body").style.display = "block";
	
	if (request) {
		endTabLoading();
		
		$(currentTab + "Body").innerHTML = request.responseText;
		try {
			request.responseText.evalScripts();
		}
		catch (err) {
			//if (console)
				//console.log("Error executing scripts from AJAX response:\n %s",err);
		}
		
		if ($(currentTab + "Body").getAttribute("cacheable") == "true") {
		  // if it's cacheable, update the link, which is inside the named span
		  $(currentTab + "Link").firstDescendant().writeAttribute("onclick", "switchTabTo('" + tab + "');");
	  }
	}
}

