// public

// swf uploader stuff

var swfu;
function initSwfu() {
	swfu = new SWFUpload({
		flash_url: baseUrl + "swfupload/swfupload_f9.swf",
		upload_url: baseUrl + "mediaUpload.php",
		file_size_limit: "8000", // 8MB

		file_queue_error_handler: function(file, error, msg) {
			GLog.write("Queue error: " + error + " " + msg);
		},
		file_dialog_complete_handler: function(nSelected, nQueued) {
			$("swfuSelect").disable();
			this.startUpload();
			$("swfuStatus").innerHTML = "Uploading...";
		},
		upload_error_handler: function(file, error, msg) {
			GLog.write("Upload error: " + error + " " + msg);
		},
		upload_success_handler: function(file, data) {
			$("swfuStatus").innerHTML = "Upload successful!";
			var result = eval("(" + data + ")");
		},
		upload_complete_handler: function(file) {
			$("swfuSelect").enable();
		}
	});
}

function submitUrl(form) {
	$("mediaUrlStatus").innerHTML = "Processing... ";
	$(form).request({ onSuccess: onSuccessUrl });
}
function onSuccessUrl(transport) {
	var result = eval("(" + transport.responseText + ")");
	if (result == 0) {
		$("mediaUrlStatus").innerHTML = "Processing... success!";
		rangeChanged();
	}
	else {
		$("mediaUrlStatus").innerHTML = "Error: please try again.";
	}
}

// plugins

var plugins = [];

/////

var hoveredAnnotation = null;

var Annotation = Class.create({
	initialize: function(media, parent, start, len, data) {
		this.media = media;
		this.parent = (typeof(parent) == "object" ? parent : media.annotations[parent]);
		this.start = start;
		this.len = len;
		this.end = start + len;
		this.data = data;
	},
	show: function() {
		if (!this.media.div) { return; }
		var tag = isTag(this.data);
		var spanInfo = ["span", {onmouseover:  hoverAnnotation,
		                         onmouseout :unhoverAnnotation}, this.data];
		if (isTag(this.data)) {
			spanInfo[0] = "span.tag";
			spanInfo[1].onclick = toggleTag;
		}
		this.li = buildElement(["li", {},
			spanInfo,
			["ul.annotations", {},
				["li", {"style.display": "none"},
					["input.text", {value: newChildPrompt, defaultValue: newChildPrompt,
					                onblur: freezeNewTag}]
				]
			]
		]);
		this.li.annotation = this;
		var span = this.li.down("span");
		var ul = this.media.div.down("ul.rootAnnotations");
		if (!this.parent) {
			ul.previous(".ulHead").innerHTML = "Annotations: ";
		}
		else {
			if (!this.parent.li) { return; }
			ul = this.parent.li.down("ul");
		}
		ul.lastChild.insert({before: this.li});
		for (var i = 0; i < plugins.length; i++) { plugins[i].onshowAnnotation(this); }
		if (this.parent) { this.parent.updateDelete(); }
	},
	assignId: function(id) {
		this.id = id;
		var childUl = this.li.down("ul");
		childUl.insert({before: buildElement(["img.annotationCtl", {
			src: baseUrl + "go-jump.png", onclick: promptChildAnnotation,
			onmouseover: hoverAnnotationCtl, onmouseout: unhoverAnnotationCtl,
			alt: "Add a child annotation"
		}])});
		childUl.insert({before: buildElement(["img.annotationCtl", {
			src: baseUrl + "b_drop.png", onclick: delAnnotation,
			onmouseover: hoverAnnotationCtl, onmouseout: unhoverAnnotationCtl,
			alt: "Delete this annotation"
		}])});
		this.media.annotations[id] = this;
	},
	updateDelete: function() {
		var deleteImg = this.li.down("img.annotationCtl", 1);
		if (this.li.down("ul.annotations").childNodes.length == 1) {
			deleteImg.show();
		}
		else {
			deleteImg.hide();
		}
	},
	destroy: function() {
		this.li.remove();
		this.media.annotations[this.id] = undefined;
		if (this.parent) { this.parent.updateDelete(); }
	},
	noComma: function() {}
});

var mediaInstances = [];
var selectedSound = null;
var Media = Class.create({
	initialize: function(id, start, len) {
		this.id = id;
		this.start = 1000 * start;
		this.len = 1000 * len;
		this.end = this.start + this.len;
		if (mediaInstances[id]) { mediaInstances[id].destroy(); }
		mediaInstances[id] = this;
		this.annotations = {};
	},
	fullData: function() { return this.loc; },
	hasGeo: function() {
		return this.loc && this.loc.length && (this.loc[0] || this.loc[1]);
	},
	showDiv: function() {
		if (this.div) { return; }
		this.div = $($("soundTemplate").cloneNode(true));
		this.div.id = "";
		this.fields = this.div.getElementsByClassName("templateField");
		if (this.hasGeo()) {
			setValue(this.fields[0], formatLoc(this.loc[0]));
			setValue(this.fields[1], formatLoc(this.loc[1]));
		}
		else {
			this.div.down("table.latlng").hide();
			var nogeoMarker = this.div.down("div.nogeoMarker");
			var img = nogeoMarker.down("img");
			img.src = urlMarker;
			nogeoSetDraggable(img);
			nogeoMarker.show();
		}
		var startHTML = this.fields[2].innerHTML = formatDate(this.start);
		var end = formatDate(this.end);
		var space = startHTML.indexOf(" ");
		this.fields[3].innerHTML = (startHTML.substring(0,space) == end.substring(0,space) ?
		                            end.substring(space) : end);
		this.div.sound = this;
		$("sounds").insert(this.div);
	},
	killDiv: function() {
		if (!this.div) { return; }
		this.deselect();
		this.div.remove();
		this.div = null;
	},
	select: function() {
		if (this == selectedSound) { return; }
		if (selectedSound) { selectedSound.deselect(); }
		this.div.id = "selectedSound";
		selectMarker(this.id);
		selectedSound = this;
		if (this.div.getElementsByClassName("ulHead")[0].innerHTML.substr(0,5) == "Click") {
			this.showAnnotations();
		}
		redraw();
	},
	deselect: function() {
		if (this != selectedSound) { return; }
		this.div.id = "";
		deselectMarker(getMarkerBySoundId(this.id));
		if (playSpeed != 0) { this.playPause(); } // stop playback, if any
		selectedSound = null;
		abortSynnotation();
		redraw();
	},
	setLoc: function(gLatLng) {
		this.loc[0] = gLatLng.lat();
		this.loc[1] = gLatLng.lng();
		if (this.div) {
			setValue(this.fields[0], formatLoc(this.loc[0]));
			setValue(this.fields[1], formatLoc(this.loc[1]));
			this.div.down("table.latlng").show(); // for newly located sounds
		}
		new Ajax.Request(baseUrl + "setLoc.php", {method: "post",
			parameters: {id: this.id, loc: gLatLng.toUrlValue()}
		});
	},
	skipBackward: function() { timePos = this.start; redraw(); },
	skipForward : function() { timePos = this.end;   redraw(); },
	playPause: function() {
		var img = this.div.down("div.playback").down("img", 1);
		if (playSpeed == 0) {
			if (timePos < this.start || timePos > this.end) {
				this.skipBackward();
			}
			img.src = baseUrl + "media-playback-pause.png";
			playSpeed = 1;
			playStart();
		}
		else {
			img.src = baseUrl + "media-playback-start.png";
			playSpeed = 0;
			playStop();
		}
	},
	showAnnotations: function(data) {
		if (!data) {
			new Ajax.Request(baseUrl + "annotation.php", {method: "get",
				parameters: {action: "read", id: this.id},
				onSuccess: onloadAnnotations
			});
			return;
		}
		if (!this.div) { return; } // too slow, user must have moved away
		var ulHead = this.div.down(".ulHead");
		var ul = this.div.down("ul.rootAnnotations");
		ul.insert(buildElement(["li", {},
			["input.text", {value: newTagPrompt, defaultValue: newTagPrompt,
			                onfocus: activateSelf, onblur: freezeNewTag}]
		]));
		var newAnnotations = data.annotations;
		ulHead.innerHTML = "No annotations found";
		for (var i = 0; i < newAnnotations.length; i++) {
			var sqlObj = newAnnotations[i];
			var annotation = new Annotation(this, sqlObj.parent, Number(sqlObj.start),
			                                      sqlObj.len, sqlObj.data);
			annotation.show();
			annotation.assignId(sqlObj.id);
		}
	},
	destroy: function() {
		this.killDiv();
	}
});
function getSound(node) { return $(node).up("div.soundInstance").sound; }


var mediaHandlers = [];

var selectedSound = null;


function showSounds(sounds) {
	var unknownIds = [];
	for (var i = 0; i < sounds.length; i++) {
		if (sounds[i].fullData()) {
			sounds[i].showDiv();
			sounds[i].div.hereToStay = true;
		}
		else {
			unknownIds.push(sounds[i].id);
		}
	}
	var soundDivs = $("sounds").childNodes;
	for (var i = 0; i < soundDivs.length; i++) { // weed out those not in sounds
		if (soundDivs[i].hereToStay) {
			soundDivs[i].hereToStay = undefined;
		}
		else {
			var sound = soundDivs[i].sound;
			if (sound.hasGeo() || !($("withNoGeo").checked)) {
				sound.killDiv();
				i--;
			}
		}
	}
	if (unknownIds.length > 0) {
		new Ajax.Request(baseUrl + "sounds.php", {method: "get",
			parameters: {ids: new String(unknownIds)},
			onSuccess: onloadSounds
		});
	}
	if (sounds.length == 1 && unknownIds.length == 0) { // select sole sound
		sounds[0].select();
	}
}


function thawField(field) {
	$(field).removeClassName("fieldHover");
	var input = buildElement(["input.text templateField", {onblur: freezeField}]);
	input.style.width = field.getWidth() + "px";
	input.value = field.innerHTML;
	field.replace(input);
	input.activate();
	input.field = field;
}
function freezeField() { // private
	var input = this;
	var field = input.field;
	var float = parseFloat(input.value);
	if (field.innerHTML != input.value && !isNaN(float)) {
		field.update(formatLoc(float));
		input.replace(field); // must happen in the middle
		var soundDiv = field.up(".soundInstance");
		var fields = soundDiv.getElementsByClassName("templateField");
		var loc = new GLatLng(getValue(fields[0]), getValue(fields[1]));
		var id = soundDiv.sound.id;
		getMarkerBySoundId(id).setLatLng(loc);
		new Ajax.Request(baseUrl + "setLoc.php", {method: "post",
			parameters: {id: id, loc: loc.toUrlValue()}
		});
	}
	else {
		input.replace(field);
	}
}



function rangeChanged() {
	var b = map.getBounds();
	var params = {
		sw: b.getSouthWest().toUrlValue(),
		ne: b.getNorthEast().toUrlValue(),
		w: 400, h: 400,
		tmin: Math.round(0.001*minTime), tlen: Math.round(0.001*timeRange),
		nogeo: ($("withNoGeo").checked ? 1 : 0)
	};

	if (projName) { params.name = projName; }

	var tags = $("tags").childNodes;
	if (tags.length > 0) {
		var s = "";
		for (var i = 0; i < tags.length; i++) { s += ("," + tags[i].innerHTML); }
		params.tags = s.substr(1);
	}

	new Ajax.Request(baseUrl + "media.php", {method: "get",
		parameters: params, onSuccess: onloadMedia
	});
}

function onloadMedia(transport) {
	var data = eval("(" + transport.responseText + ")");
	for (var i = 0; i < mediaHandlers.length; i++) {
		mediaHandlers[i](data);
	}
}

////////////////////////////////////////////////////////////////////////////////

function onloadSounds(transport) {
	var data = eval("(" + transport.responseText + ")");
	var sounds = $("sounds");
	for (var i = 0; i < data.length; i++) {
		var row = data[i];
		var sound = mediaInstances[row[0]];
		if (!sound) { GLog.write("Media " + row[0] + " not found"); continue; }
		sound.loc = [row[1], row[2]];
		sound.showDiv();
	}
	if (sounds.childNodes.length == 1) { // select sole sound
		sounds.firstChild.sound.select();
	}
}

function clearMapSoundDivs() {
	var soundDivs = $("sounds").childNodes;
	for (var i = 0; i < soundDivs.length; i++) {
		var sound = soundDivs[i].sound;
		if (sound.hasGeo() || !($("withNoGeo").checked)) {
			sound.killDiv();
			i--;
		}
	}
}

////////////////////////////////////////////////////////////////////////////////
// annotation stuff

var newTagPrompt = "Add a new annotation";
var newChildPrompt = "Add a child annotation";

// ajax handlers
function onloadAnnotations(transport) {
	var data = eval("(" + transport.responseText + ")");
	var sound = mediaInstances[data.mediaId];
	if (!sound) { return; } // shouldn't happen
	sound.showAnnotations(data);
}
function onloadInsertAnnotation(transport, annotation) {
	var data = eval("(" + transport.responseText + ")");
	var sound = mediaInstances[data.mediaId];
	if (!sound) { return; } // should not happen
	annotation.assignId(data.tagId);
	var ul = annotation.li.parentNode;
	if (ul.hasClassName("rootAnnotations") || ul.childNodes.length > 2) {
		ul.lastChild.show();
	}
}


function activateSelf() {
	this.oldValue = this.value;
	if (this.value == this.defaultValue) {
		this.clear();
	}
}

function freezeNewTag() {
	var input = this;
	var data = input.value;
	if (data.blank()) {
		input.value = input.defaultValue;
		return;
	}
	if (data == this.oldValue || data == this.defaultValue) { return; }
	var media = getSound(input);
	var ul = input.up("ul");
	var parent = (ul.hasClassName("rootAnnotations") ? 0 : ul.up("li").annotation.id);
	addAnnotation(media, parent, 0, 0, data);
	input.up("li").hide(); // until we get confirmation
	input.value = newTagPrompt;
}
function addAnnotation(media, parent, start, len, data) {
	var annotation = new Annotation(media, parent, start, len, data);
	annotation.show();
	new Ajax.Request(baseUrl + "annotation.php", {method: "post",
		parameters: {action: "create",
		             mediaId: media.id, parent: parent, data: data, start: start, len: len},
		onSuccess: function(transport) { onloadInsertAnnotation(transport, annotation); }
	});
}

// image handlers
function promptChildAnnotation() {
	var ul = this.next("ul");
	ul.lastChild.show();
	ul.down("input.text").activate();
}
function delAnnotation() {
	var annotation = this.up("li").annotation;
	new Ajax.Request(baseUrl + "annotation.php", {method: "post",
		parameters: {action: "delete", id: annotation.id}
	});
	annotation.destroy();
}
function hoverAnnotation() {
	hoveredAnnotation = this.up("li").annotation;
	redraw();
}
function unhoverAnnotation() {
	hoveredAnnotation = null;
	redraw();
}

function   hoverAnnotationCtl() { this.addClassName("annotationCtlHover"); }
function unhoverAnnotationCtl() { this.removeClassName("annotationCtlHover"); }
