var pendingMessages = new Array();
var syncTimer = null;
var timeoutTimer = null;
var heartbeatTimer = null;
var currentlyOnlineTimer = null;
var authorId = null;

ajaxCaller.shouldDebug = false;
ajaxCaller.shouldMakeHeaderMap = false;

var MIN_TEXTAREA_ROWS = 3;
var MAX_TEXTAREA_ROWS = 30;

var REFRESH_PERIOD = 5000;
var TIMEOUT_TIME = 10*60*1000; // Will *always* time out after 10 mins
var HEARTBEAT_PERIOD = 2000;
var CURRENTLY_ONLINE_PERIOD = 2000;

window.onload = function() {
  $("authorIdSpec").value = "Anon" + Math.floor(10000 * Math.random());
  authorId = $("authorIdSpec").value;
  $("updateAuthorId").onclick = function() {authorId = $("authorIdSpec").value;}
  synchronise();
  startPeriodicSync();
  $("timeoutMessage").style.display = "none";
  timeoutTimer = setTimeout(onTimeout, TIMEOUT_TIME);
  sendHeartbeat();
  heartbeatTimer = setInterval(sendHeartbeat, HEARTBEAT_PERIOD);
  updateCurrentlyOnline();
  currentlyOnlineTimer = setInterval(updateCurrentlyOnline, CURRENTLY_ONLINE_PERIOD);
}

function sendHeartbeat() {
  vars = {
    renew: true,
    author: authorId
  };
  ajaxCaller.postForPlainText("session.phtml", vars, function() {});
}

function startPeriodicSync() {
  stopPeriodicSync();
  syncTimer = setInterval(synchronise, REFRESH_PERIOD);
}

function stopPeriodicSync() {
  clearInterval(syncTimer);
}

function resize(textarea) {

    var textRows = textarea.value.split('\n');
    var newRowAmount = textRows.length + 2;

    for ( var i=0; i<textRows.length; i++ ) {
      if ( textRows[i].length > textarea.cols ) {
        newRowAmount += Math.floor(textRows[i].length/textarea.cols);
      }
    }
    newRowAmount = Math.max(newRowAmount, 3);
    newRowAmount = Math.min(newRowAmount, 30);
    textarea.rows = newRowAmount;

}

function onMessagesLoaded(xml, callingContext) {
  window.status = "loaded";
  var wikiMessages = xml.getElementsByTagName("message");
  var messagesHTML = "";
  while ($("messages").hasChildNodes()) {
    $("messages").removeChild($("messages").firstChild);
  }
  for (var i=0; i<wikiMessages.length; i++) {
    var messageNode = wikiMessages[i];
    var content = getChildValue(messageNode, "content");
    content = (content==null ? "" : unescape(content));
    var serverMessage = {
        id: this.getChildValue(messageNode, "id"),
        lastAuthor: this.getChildValue(messageNode, "lastAuthor"),
        ranking: this.getChildValue(messageNode, "ranking"),
        content: content
    };

    var messageArea = document.createElement("textarea");
    messageArea.className = "messageArea";
    messageArea.id = serverMessage.id;
    messageArea.serverMessage = serverMessage;
    messageArea.rows = 3;
    messageArea.cols = 80;
    messageArea.value = serverMessage.content;
    messageArea.onmouseout = onMessageMouseOut;
    messageArea.onmouseover = onMessageMouseOver;
    messageArea.onfocus = onMessageFocus;
    messageArea.onblur = onMessageBlur;

    lastAuthor = document.createElement("div");
    lastAuthor.className = "lastAuthor";
    lastAuthor.innerHTML = serverMessage.id + "."
      + "<em>" + serverMessage.lastAuthor + "</em>"+"."
      + serverMessage.ranking+"."+i;

    messageDiv = document.createElement("div");
    messageDiv.className = "messageDiv";
    messageDiv.appendChild(lastAuthor);
    messageDiv.appendChild(messageArea);

    $("messages").appendChild(messageDiv);

    resize(messageArea);

  }
}

function getChildValue(parentNode, childName) {
  var childNode = parentNode.getElementsByTagName(childName)[0];
  return childNode.firstChild == null ? null : childNode.firstChild.nodeValue;
}

function createSpacer(event) {
  var div = document.createElement("div");
  div.className = "spacer";
  div.appendChild(document.createTextNode(" "));
  return div;
}

function getMessage(event) {
  event = event || window.event;
  return event.target || event.srcElement;
}

function onMessageMouseOver(event) {
  var message = getMessage(event);
  if (!message.hasFocus) {
    message.style.borderStyle="dotted";
    message.style.borderColor="black";
  }
}

function onMessageMouseOut(event) {
  var message = getMessage(event);
  if (!message.hasFocus) {
    message.style.borderStyle="solid";
    message.style.borderColor="white";
  }
}

function onMessageFocus(event) {
  var message = getMessage(event);
  message.hasFocus=true;
  message.style.borderStyle="solid";
  message.style.borderColor="black";
  message.style.backgroundColor="white";
  stopPeriodicSync();
}

function onMessageBlur(event) {
  var message = getMessage(event);
  message.hasFocus=false;
  message.style.borderStyle="solid";
  message.style.borderColor="white";
  message.style.backgroundColor="#cccccc";
  resize(message);

  var initialMessageContent = message.serverMessage.content;

  if (message.value != initialMessageContent) {
    pendingMessages[message.id] = true;
    message.style.backgroundColor = "#ffcc33";
  }

  startPeriodicSync();

}

function synchronise() {

  var messageTags = "";
  for (messageId in pendingMessages) {
    var initialServerMessage = $(messageId).serverMessage;
    messageTags += "<message>";
    messageTags += "<id>" + messageId + "</id>";
    messageTags += "<lastAuthor>" + authorId + "</lastAuthor>";
    messageTags += "<ranking>" + initialServerMessage.ranking + "</ranking>";
    messageTags += "<content>" + escape($(messageId).value) + "</content>";
    messageTags += "</message>";

    $(messageId).style.backgroundColor = "#cccccc";
  }

  var changesOccurred = (messageTags!="");
  if (!changesOccurred) {
    ajaxCaller.getXML("content.phtml?messages", onMessagesLoaded);
    return;
  }

  var changeSpec = "<messages>" + messageTags + "</messages>";
  ajaxCaller.postBody
    ("content.phtml", null, onMessagesLoaded, true, null, "text/xml", changeSpec);
  pendingMessages = new Array();
}

function onTimeout() {
  new Effect.BlindDown($("timeoutMessage"));
  stopPeriodicSync();
  clearInterval(heartbeatTimer);
  clearInterval(currentlyOnlineTimer);
  var messageAreas = getElementsByClassName("messageArea");
  for (i=0; i<messageAreas.length; i++) {
    messageAreas[i].onmouseout = null;
    messageAreas[i].onmouseover = null;
    messageAreas[i].onfocus = null;
    messageAreas[i].onblur = null;
  }
}

function updateCurrentlyOnline() {
  ajaxCaller.getXML("session.phtml?current", function(xml) {
    $("currentlyOnline").innerHTML = "<ul>";
    var authors = xml.getElementsByTagName("author");
    for (var i=0; i<authors.length; i++) {
      var authorName = authors[i].firstChild.nodeValue;
      $("currentlyOnline").innerHTML += "<li> " + authorName + "</li>";
    }
    $("currentlyOnline").innerHTML += "</ul>";
  });
}

