// 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.

/*
In the absence of any formal way to specify interfaces in JavaScript,
here's a skeleton implementation of a playground transport.

        function Transport() {
                // Set up any transport state (eg, make a websocket connection).
                return {
                        Run: function(body, output, options) {
                                // Compile and run the program 'body' with 'options'.
				// Call the 'output' callback to display program output.
                                return {
                                        Kill: function() {
                                                // Kill the running program.
                                        }
                                };
                        }
                };
        }

	// The output callback is called multiple times, and each time it is
	// passed an object of this form.
        var write = {
                Kind: 'string', // 'start', 'stdout', 'stderr', 'end'
                Body: 'string'  // content of write or end status message
        }

	// The first call must be of Kind 'start' with no body.
	// Subsequent calls may be of Kind 'stdout' or 'stderr'
	// and must have a non-null Body string.
	// The final call should be of Kind 'end' with an optional
	// Body string, signifying a failure ("killed", for example).

	// The output callback must be of this form.
	// See PlaygroundOutput (below) for an implementation.
        function outputCallback(write) {
        }
*/

function HTTPTransport() {
	'use strict';

	// TODO(adg): support stderr

	function playback(output, events) {
		var timeout;
		output({Kind: 'start'});
		function next() {
			if (!events || events.length === 0) {
				output({Kind: 'end'});
				return;
			}
			var e = events.shift();
			if (e.Delay === 0) {
				output({Kind: 'stdout', Body: e.Message});
				next();
				return;
			}
			timeout = setTimeout(function() {
				output({Kind: 'stdout', Body: e.Message});
				next();
			}, e.Delay / 1000000);
		}
		next();
		return {
			Stop: function() {
				clearTimeout(timeout);
			}
		}
	}

	function error(output, msg) {
		output({Kind: 'start'});
		output({Kind: 'stderr', Body: msg});
		output({Kind: 'end'});
	}

	var seq = 0;
	return {
		Run: function(body, output, options) {
			seq++;
			var cur = seq;
			var playing;
			$.ajax('/compile', {
				type: 'POST',
				data: {'version': 2, 'body': body},
				dataType: 'json',
				success: function(data) {
					if (seq != cur) return;
					if (!data) return;
					if (playing != null) playing.Stop();
					if (data.Errors) {
						error(output, data.Errors);
						return;
					}
					playing = playback(output, data.Events);
				},
				error: function() {
					error(output, 'Error communicating with remote server.');
				}
			});
			return {
				Kill: function() {
					if (playing != null) playing.Stop();
					output({Kind: 'end', Body: 'killed'});
				}
			};
		}
	};
}

function SocketTransport() {
	'use strict';

	var id = 0;
	var outputs = {};
	var started = {};
	var websocket;
	if (window.location.protocol == "http:") {
		websocket = new WebSocket('ws://' + window.location.host + '/socket');
	} else if (window.location.protocol == "https:") {
		websocket = new WebSocket('wss://' + window.location.host + '/socket');
	}

	websocket.onclose = function() {
		console.log('websocket connection closed');
	}

	websocket.onmessage = function(e) {
		var m = JSON.parse(e.data);
		var output = outputs[m.Id];
		if (output === null)
			return;
		if (!started[m.Id]) {
			output({Kind: 'start'});
			started[m.Id] = true;
		}
		output({Kind: m.Kind, Body: m.Body});
	}

	function send(m) {
		websocket.send(JSON.stringify(m));
	}

	return {
		Run: function(body, output, options) {
			var thisID = id+'';
			id++;
			outputs[thisID] = output;
			send({Id: thisID, Kind: 'run', Body: body, Options: options});
			return {
				Kill: function() {
					send({Id: thisID, Kind: 'kill'});
				}
			};
		}
	};
}

function PlaygroundOutput(el) {
	'use strict';

	return function(write) {
		if (write.Kind == 'start') {
			el.innerHTML = '';
			return;
		}

		var cl = 'system';
		if (write.Kind == 'stdout' || write.Kind == 'stderr')
			cl = write.Kind;

		var m = write.Body;
		if (write.Kind == 'end') {
			m = '\nProgram exited' + (m?(': '+m):'.');
		}

		if (m.indexOf('IMAGE:') === 0) {
			// TODO(adg): buffer all writes before creating image
			var url = 'data:image/png;base64,' + m.substr(6);
			var img = document.createElement('img');
			img.src = url;
			el.appendChild(img);
			return;
		}

		// ^L clears the screen.
		var s = m.split('\x0c');
		if (s.length > 1) {
			el.innerHTML = '';
			m = s.pop();
		}

		m = m.replace(/&/g, '&amp;');
		m = m.replace(/</g, '&lt;');
		m = m.replace(/>/g, '&gt;');

		var needScroll = (el.scrollTop + el.offsetHeight) == el.scrollHeight;

		var span = document.createElement('span');
		span.className = cl;
		span.innerHTML = m;
		el.appendChild(span);

		if (needScroll)
			el.scrollTop = el.scrollHeight - el.offsetHeight;
	}
}

(function() {
  function lineHighlight(error) {
    var regex = /prog.go:([0-9]+)/g;
    var r = regex.exec(error);
    while (r) {
      $(".lines div").eq(r[1]-1).addClass("lineerror");
      r = regex.exec(error);
    }
  }
  function highlightOutput(wrappedOutput) {
    return function(write) {
      if (write.Body) lineHighlight(write.Body);
      wrappedOutput(write);
    }
  }
  function lineClear() {
    $(".lineerror").removeClass("lineerror");
  }

  // opts is an object with these keys
  //  codeEl - code editor element
  //  outputEl - program output element
  //  runEl - run button element
  //  fmtEl - fmt button element (optional)
  //  fmtImportEl - fmt "imports" checkbox element (optional)
  //  shareEl - share button element (optional)
  //  shareURLEl - share URL text input element (optional)
  //  shareRedirect - base URL to redirect to on share (optional)
  //  vetEl - vet button element (optional)
  //  toysEl - toys select element (optional)
  //  enableHistory - enable using HTML5 history API (optional)
  //  transport - playground transport to use (default is HTTPTransport)
  //  enableShortcuts - whether to enable shortcuts (Ctrl+S/Cmd+S to save) (default is false)
  function playground(opts) {
    var code = $(opts.codeEl);
    var transport = opts['transport'] || new HTTPTransport();
    var running;

    // autoindent helpers.
    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);
    }

    // NOTE(cbro): e is a jQuery event, not a DOM event.
    function handleSaveShortcut(e) {
      if (e.isDefaultPrevented()) return false;
      if (!e.metaKey && !e.ctrlKey) return false;
      if (e.key != "S" && e.key != "s") return false;

      e.preventDefault();

      // Share and save
      share(function(url) {
        window.location.href = url + ".go?download=true";
      });

      return true;
    }

    function keyHandler(e) {
      if (opts.enableShortcuts && handleSaveShortcut(e)) return;

      if (e.keyCode == 9 && !e.ctrlKey) { // tab (but not ctrl-tab)
        insertTabs(1);
        e.preventDefault();
        return false;
      }
      if (e.keyCode == 13) { // enter
        if (e.shiftKey) { // +shift
          run();
          e.preventDefault();
          return false;
        } if (e.ctrlKey) { // +control
          fmt();
          e.preventDefault();
        } else {
          autoindent(e.target);
        }
      }
      return true;
    }
    code.unbind('keydown').bind('keydown', keyHandler);
    var outdiv = $(opts.outputEl).empty();
    var output = $('<pre/>').appendTo(outdiv);

    function body() {
      return $(opts.codeEl).val();
    }
    function setBody(text) {
      $(opts.codeEl).val(text);
    }
    function origin(href) {
      return (""+href).split("/").slice(0, 3).join("/");
    }

    var pushedEmpty = (window.location.pathname == "/");
    function inputChanged() {
      if (pushedEmpty) {
        return;
      }
      pushedEmpty = true;
      $(opts.shareURLEl).hide();
      window.history.pushState(null, "", "/");
    }
    function popState(e) {
      if (e === null) {
        return;
      }
      if (e && e.state && e.state.code) {
        setBody(e.state.code);
      }
    }
    var rewriteHistory = false;
    if (window.history && window.history.pushState && window.addEventListener && opts.enableHistory) {
      rewriteHistory = true;
      code[0].addEventListener('input', inputChanged);
      window.addEventListener('popstate', popState);
    }

    function setError(error) {
      if (running) running.Kill();
      lineClear();
      lineHighlight(error);
      output.empty().addClass("error").text(error);
    }
    function loading() {
      lineClear();
      if (running) running.Kill();
      output.removeClass("error").text('Waiting for remote server...');
    }
    function noError() {
      lineClear();
      if (running) running.Kill();
      output.removeClass("error").text('No errors.');
    }
    function run() {
      loading();
      running = transport.Run(body(), highlightOutput(PlaygroundOutput(output[0])));
    }

    function fmt() {
      loading();
      var data = {"body": body()};
      if ($(opts.fmtImportEl).is(":checked")) {
        data["imports"] = "true";
      }
      $.ajax("/fmt", {
        data: data,
        type: "POST",
        dataType: "json",
        success: function(data) {
          if (data.Error) {
            setError(data.Error);
          } else {
            setBody(data.Body);
            setError("");
          }
        }
      });
    }

    function vet() {
      loading();
      var data = {"body": body()};
      $.ajax("/vet", {
        data: data,
        type: "POST",
        dataType: "json",
        success: function(data) {
          if (data.Errors) {
            setError(data.Errors);
          } else {
            noError();
          }
        },
        error: function() {
          setError('Error communicating with remote server.');
        }
      });
    }

    var shareURL; // jQuery element to show the shared URL.
    var sharing = false; // true if there is a pending request.
    var shareCallbacks = [];
    function share(opt_callback) {
      if (opt_callback) shareCallbacks.push(opt_callback);

      if (sharing) return;
      sharing = true;

      var sharingData = body();
      $.ajax("/share", {
        processData: false,
        data: sharingData,
        type: "POST",
        contentType: "text/plain; charset=utf-8",
        complete: function(xhr) {
          sharing = false;
          if (xhr.status != 200) {
            alert("Server error; try again.");
            return;
          }
          if (opts.shareRedirect) {
            window.location = opts.shareRedirect + xhr.responseText;
          }
          var path = "/p/" + xhr.responseText;
          var url = origin(window.location) + path;

          for (var i = 0; i < shareCallbacks.length; i++) {
            shareCallbacks[i](url);
          }
          shareCallbacks = [];

          if (shareURL) {
            shareURL.show().val(url).focus().select();

            if (rewriteHistory) {
              var historyData = {"code": sharingData};
              window.history.pushState(historyData, "", path);
              pushedEmpty = false;
            }
          }
        }
      });
    }

    $(opts.runEl).click(run);
    $(opts.fmtEl).click(fmt);
    $(opts.vetEl).click(vet);

    if (opts.shareEl !== null && (opts.shareURLEl !== null || opts.shareRedirect !== null)) {
      if (opts.shareURLEl) {
        shareURL = $(opts.shareURLEl).hide();
      }
      $(opts.shareEl).click(function() {
        share();
      });
    }

    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);
          }
        });
      });
    }
  }

  window.playground = playground;
})();
