// Copyright 2012 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// opts is an object with these keys
// 	codeEl - code editor element 
// 	outputEl - program output element
// 	runEl - run button element
// 	shareEl - share button element (optional)
// 	shareURLEl - share URL text input element (optional)
// 	shareRedirect - base URL to redirect to on share (optional)
// 	preCompile - callback to mutate request data before compiling
// 	postCompile - callback to read response data after compiling
//      simple - use plain textarea instead of CodeMirror.
//      toysEl - select element with a list of toys.
function playground(opts) {
	var simple = opts['simple'];
	var code = $(opts['codeEl']);
	var editor;

	// autoindent helpers for simple mode.
	function insertTabs(n) {
		// find the selection start and end
		var start = code[0].selectionStart;
		var end   = code[0].selectionEnd;
		// split the textarea content into two, and insert n tabs
		var v = code[0].value;
		var u = v.substr(0, start);
		for (var i=0; i<n; i++) {
			u += "\t";
		}
		u += v.substr(end);
		// set revised content
		code[0].value = u;
		// reset caret position after inserted tabs
		code[0].selectionStart = start+n;
		code[0].selectionEnd = start+n;
	}
	function autoindent(el) {
		var curpos = el.selectionStart;
		var tabs = 0;
		while (curpos > 0) {
			curpos--;
			if (el.value[curpos] == "\t") {
				tabs++;
			} else if (tabs > 0 || el.value[curpos] == "\n") {
				break;
			}
		}
		setTimeout(function() {
			insertTabs(tabs, 1);
		}, 1);
	}

	function keyHandler(e) {
		if (simple && e.keyCode == 9) { // tab
			insertTabs(1);
			e.preventDefault();
			return false;
		}
		if (e.keyCode == 13) { // enter
			if (e.shiftKey) { // +shift
				run();
				e.preventDefault();
				return false;
			} else if (simple) {
				autoindent(e.target);
			}
		}
		return true;
	}
	if (simple) {
		code.unbind('keydown').bind('keydown', keyHandler);
	} else {
		editor = CodeMirror.fromTextArea(
			code[0],
			{
				lineNumbers: true,
				indentUnit: 8,
				indentWithTabs: true,
				onKeyEvent: function(editor, e) { keyHandler(e); }
			}
		);
	}
	var output = $(opts['outputEl']);

	function clearErrors() {
		if (!editor) {
			return;
		}
		var lines = editor.lineCount();
		for (var i = 0; i < lines; i++) {
			editor.setLineClass(i, null);
		}
	}
	function highlightErrors(text) {
		if (!editor) {
			return;
		}
		var errorRe = /[a-z]+\.go:([0-9]+): /g;
		var result;
		while ((result = errorRe.exec(text)) != null) {
			var line = result[1]*1-1;
			editor.setLineClass(line, "errLine")
		}
	}
	function body() {
		if (editor) {
			return editor.getValue();
		}
		return $(opts['codeEl']).val();
	}
	function setBody(text) {
		if (editor) {
			editor.setValue(text);
			return;
		}
		$(opts['codeEl']).val(text);
	}
	function origin(href) {
		return (""+href).split("/").slice(0, 3).join("/");
	}

	var seq = 0;
	function run() {
		clearErrors();
		output.removeClass("error").html(
			'<div class="loading">Waiting for remote server...</div>'
		);
		seq++;
		var cur = seq;
		var data = {"body": body()};
		if (opts['preCompile']) {
			opts['preCompile'](data);
		}
		$.ajax("/compile", {
			data: data,
			type: "POST",
			dataType: "json",
			success: function(data) {
				if (seq != cur) {
					return;
				}
				pre = $("<pre/>");
				output.empty().append(pre);
				if (opts['postCompile']) {
					opts['postCompile'](data);
				}
				if (!data) {
					return;
				}
				if (data.compile_errors != "") {
					pre.text(data.compile_errors);
					output.addClass("error");
					highlightErrors(data.compile_errors);
					return;
				}
				var out = ""+data.output;
				if (out.indexOf("IMAGE:") == 0) {
					var img = $("<img/>");
					var url = "data:image/png;base64,";
					url += out.substr(6)
					img.attr("src", url);
					output.empty().append(img);
					return;
				}
				pre.text(out);
			},
			error: function(xhr) {
				var text = "Error communicating with remote server.";
				console.log(xhr.status);
				if (xhr.status == 501) {
					text = xhr.responseText;
				}
				output.addClass("error").text(text);
			}
		});
	}
	$(opts['runEl']).click(run);

	if (opts['shareEl'] != null && (opts['shareURLEl'] != null || opts['shareRedirect'] != null)) {
		var shareURL;
		if (opts['shareURLEl']) {
			shareURL = $(opts['shareURLEl']).hide();
		}
		var sharing = false;
		$(opts['shareEl']).click(function() {
			if (sharing) return;
			sharing = true;
			$.ajax("/share", {
				processData: false,
				data: body(),
				type: "POST",
				complete: function(xhr) {
					sharing = false;
					if (xhr.status == 501) {
						alert(xhr.responseText);
						return;
					}
					if (xhr.status != 200) {
						alert("Server error; try again.");
						return;
					}
					if (opts['shareRedirect']) {
						window.location = opts['shareRedirect'] + xhr.responseText;
					}
					if (shareURL) {
						var url = origin(window.location) + "/p/" + xhr.responseText;
						shareURL.show().val(url).focus().select();
					}
				}
			});
		});
	}

	if (opts['toysEl'] != null) {
		$(opts['toysEl']).bind('change', function() {
			var toy = $(this).val();
			$.ajax("/doc/play/"+toy, {
				processData: false,
				type: "GET",
				complete: function(xhr) {
					if (xhr.status != 200) {
						alert("Server error; try again.")
						return;
					}
					setBody(xhr.responseText);
				}
			});
		});
	}

	return editor;
}
