var SELECT_MESSAGES_ALL = 0;
var SELECT_MESSAGES_NONE = 1;
var SELECT_MESSAGES_TOGGLE = 2;

// ----------------------------------
// Back buttons and sliders
// ----------------------------------
function slideAndShowConversations() {
  $('conversations_container').morph('left: 40px', {duration: 0.5});
  $('conversation_new_container').morph('left: 780px', {duration: 0.5});
  $('messages_container').morph('left: 780px', {duration: 0.5});
}

function slideAndShowNewConversation() {
  $('conversations_container').morph('left: -755px', {duration: 0.5});
  $('conversation_new_container').morph('left: 40px', {duration: 0.5});
}

function slideAndShowMessages() {
  $('conversations_container').morph('left: -755px', {duration: 0.5});
  $('messages_container').morph('left: 40px', {duration: 0.5});
  $('message_questions_container').morph('left: 780px', {duration: 0.5});
}

function slideAndShowMessageQuestionSets(s) {
  var back = $('message_questions_back');
  back.stopObserving('click');
  back.observe('click', function(event) {
    slideAndShowMessages();
  });

  $('messages_container').morph('left: -755px', {duration: 0.5});
  $('message_questions_container').morph('left: 40px', {duration: 0.5});
  $('message_question_container').morph('left: 795px', {duration: 0.5});
  $('message_question_solution_container').morph('left: 1590px', {duration: 0.5});
}


// ----------------------------------
// Conversations
// ----------------------------------
function loadConversations(first) {
  spinnerShow('conversations_indeterminate');
  msgDivClear('conversations_msg');
  ajaxWrapper('api/messages/', {course: courseID}, function(json) { return json.conversations; }, loadConversationsSuccess, loadConversationsFailure);
  if (!first)
    slideAndShowConversations();
}

function loadConversationsSuccess(json) {
  drawConversations(json.conversations);
  currentTab.uponNotify(json);
  spinnerHide('conversations_indeterminate');
}

function loadConversationsFailure(transport, msg) {
  msgDivDisplay('conversations_msg', msg || 'An error occured while loading your conversations.');
  spinnerHide('conversations_indeterminate');
}

var CONVERSATION_TEMPLATE = new Template('<td class="archive"><input type="checkbox" id="archive_#{id}"></td><td class="description"><div class="title">#{unread_str}#{title}</div><div class="meta">From #{author}#{question_str}. Last updated #{timestamp}</div></td><td class="count">#{nmessages}</td>');
function drawConversations(conversations) {
  var archive = $('conversations_archive');
  archive.stopObserving('click');
  archive.observe('click', function(event) {
    doArchiveConversations(conversations);
  })
  
  var button = $('conversations_read');
  button.stopObserving('click');
  button.observe('click', function(event) {
    doMarkAsReadConversations(conversations);
  })

  button = $('conversations_select_all');
  button.stopObserving('click');
  button.observe('click', function(event) {
    doSelectMessages(conversations, SELECT_MESSAGES_ALL);
  });

  button = $('conversations_select_none');
  button.stopObserving('click');
  button.observe('click', function(event) {
    doSelectMessages(conversations, SELECT_MESSAGES_NONE);
  });

  button = $('conversations_select_toggle');
  button.stopObserving('click');
  button.observe('click', function(event) {
    doSelectMessages(conversations, SELECT_MESSAGES_TOGGLE);
  });

  button = $('conversations_new');
  button.stopObserving('click');
  button.observe('click', function(event) {
    loadNewConversation();
  });

  var none = $$('#conversations_list tfoot').first();
  var container = $$('#conversations_list tbody').first();
  container.update();
  
  if (conversations.size() == 0) {
    none.show();
    return;
  }
  none.hide();
  
  conversations.each(function(conversation) {
    var row = new Element('tr');
    if (conversation.unread)
      conversation.unread_str = '<img src="/images/unread.png" alt=""> ';
    if (conversation.question)
      conversation.question_str = ' in relation to "' + conversation.question + '"';
    container.appendChild(row);
    row.insert(CONVERSATION_TEMPLATE.evaluate(conversation));

    $$('#conversations_list .description').last().observe('click', function(event) {
      loadMessages(conversation);
    });
  });
}


// ----------------------------------
// Archive
// ----------------------------------
function doArchiveConversations(conversations) {
  var data = [];
  msgDivClear('conversations_archive_msg');
  conversations.each(function(conversation) {
    if ($('archive_' + conversation.id).checked)
      data.push(conversation.id);
  });
  if (data.size() == 0) {
    msgDivDisplay('conversations_archive_msg', 'You did not select any messages to archive.', false);
    return;
  }
  spinnerShow('conversations_indeterminate');
  msgDivClear('conversations_msg');
  ajaxWrapper('api/messages/archive', {course: courseID, conversations: data.toJSON()}, null, doArchiveConversationsSuccess, doArchiveConversationsFailure);
}

function doArchiveConversationsSuccess(json) {
  loadConversationsSuccess(json);
}

function doArchiveConversationsFailure(transport, msg) {
  msgDivDisplay('conversations_msg', msg || 'An error occured while trying to archive your conversations.', false);
  spinnerHide('conversations_indeterminate');
}


// ----------------------------------
// Mark as Read
// ----------------------------------
function doMarkAsReadConversations(conversations) {
  var data = [];
  msgDivClear('conversations_archive_msg');
  conversations.each(function(conversation) {
    if ($('archive_' + conversation.id).checked)
      data.push(conversation.id);
  });
  if (data.size() == 0) {
    msgDivDisplay('conversations_archive_msg', 'You did not select any messages to mark as read.', false);
    return;
  }
  spinnerShow('conversations_indeterminate');
msgDivClear('conversations_msg');
  ajaxWrapper('api/messages/mark_as_read', {course: courseID, conversations: data.toJSON()}, null, doMarkAsReadConversationsSuccess, doMarkAsReadConversationsFailure);
}

function doMarkAsReadConversationsSuccess(json) {
  loadConversationsSuccess(json);
}

function doMarkAsReadConversationsFailure(transport, msg) {
  msgDivDisplay('conversations_msg', msg || 'An error occured while trying to mark your conversations as read.', false);
  spinnerHide('conversations_indeterminate');
}


// ----------------------------------
// Selecting Messages
// ----------------------------------
function doSelectMessages(conversations, mode) {
  conversations.each(function(conversation) {
    var e = $('archive_' + conversation.id);
    switch (mode) {
    case SELECT_MESSAGES_ALL:
      e.checked = true;
      break;
    case SELECT_MESSAGES_NONE:
      e.checked = false;
      break;
    case SELECT_MESSAGES_TOGGLE:
      e.checked = !e.checked;
      break;
    }
  });
}


// ----------------------------------
// Messages
// ----------------------------------
function leaveMessages() {
  $('messages_reply_content').disabled = true;
  $('messages_reply_preview').disabled = true;
  $('messages_reply_reply').disabled = true;
  $('messages_reply_content_preview').update();
  msgDivClear('messages_reply_msg');

  var x = $('messages_view_user');
  x.stopObserving('click');
  x.hide();

  loadConversations();
}

function loadMessages(conversation) {
  spinnerShow('messages_indeterminate');
  msgDivClear('messages_msg');
  $('messages_heading').innerHTML = conversation.title;
  ajaxWrapper('api/messages/show', {course: courseID, conversation: conversation.id}, function(json) { return json.messages; }, loadMessagesSuccess.curry(conversation), loadMessagesFailure);
  slideAndShowMessages();
}

function loadMessagesSuccess(conversation, json) {
  drawMessages(conversation, json.messages, json.is_admin);
  
  var content = $('messages_reply_content');
  content.disabled = false;
  content.value = '';

  var preview = $('messages_reply_preview');
  preview.disabled = false;
  preview.stopObserving('click');
  preview.observe('click', function(event) {
    doMessageReplyPreview(conversation);
  });

  var reply = $('messages_reply_reply');
  reply.disabled = true;
  reply.stopObserving('click');
  reply.observe('click', function(event) {
    doMessageReply(conversation);
  });

  var back = $('messages_back');
  back.stopObserving('click');
  back.observe('click', function(event) {
    leaveMessages();
  });

  currentTab.uponNotify(json);
  spinnerHide('messages_indeterminate');
}

function loadMessagesFailure(transport, msg) {
  msgDivDisplay('messages_msg', msg || 'An error occured while loading the messages for this conversation.');
  spinnerHide('messages_indeterminate');
}

var MESSAGE_TEMPLATE = new Template('<div class="message" id="message_#{id}"><div class="message_content confluence">#{html}</div><div class="meta">#{user_footer}</div></div>');
function drawMessages(conversation, messages, is_admin) {
  var container = $('messages_list');
  container.update();
  messages.each(function(message) {
    message.user_footer = userFooter(message);
    container.innerHTML += MESSAGE_TEMPLATE.evaluate(message);
    MathJax.Hub.Queue(['Typeset', MathJax.Hub, 'message_' + message.id]);
  });

  if (is_admin) {
    var showUser = $('messages_view_user');
    showUser.observe('click', function(event) {
      var context = {prefix: 'message_', user: messages[0].author_id, user_name: messages[0].author};
      slideAndShowMessageQuestionSets(context);
      loadQuestionSets(context);
    });
    showUser.show();
  }
}



// ----------------------------------
// Reply Preview
// ----------------------------------
function doMessageReplyPreview(conversation) {
  spinnerShow('messages_indeterminate');
  $('messages_reply_reply').disabled = true;
  msgDivClear('messages_reply_msg');
  $('messages_reply_content_preview').update()
  ajaxWrapper('api/messages/render', {content: $('messages_reply_content').value}, function(json) { return json.html; }, doMessageReplyPreviewSuccess, doMessageReplyPreviewFailure);
}

function doMessageReplyPreviewSuccess(json) {
  $('messages_reply_content_preview').innerHTML = '<h3>Preview</h3>\n' + json.html;
  MathJax.Hub.Queue(['Typeset', MathJax.Hub, 'messages_reply_content_preview']);
  $('messages_reply_reply').disabled = false;
  spinnerHide('messages_indeterminate');
}

function doMessageReplyPreviewFailure(transport, msg) {
  msgDivDisplay('messages_reply_msg', msg || 'An error occurred while trying to preview your reply.', false);
  spinnerHide('messages_indeterminate');
}



// ----------------------------------
// Reply
// ----------------------------------
function doMessageReply(conversation) {
  spinnerShow('messages_indeterminate');
  $('messages_reply_reply').disabled = true;
  msgDivClear('messages_reply_msg');
  $('messages_reply_content_preview').update()
  ajaxWrapper('api/messages/reply', {course: courseID, conversation: conversation.id, content: $('messages_reply_content').value}, null, doMessageReplySuccess.curry(conversation), doMessageReplyFailure);
}

function doMessageReplySuccess(conversation, json) {
  spinnerHide('messages_indeterminate');
  loadMessages(conversation);
}

function doMessageReplyFailure(transport, msg) {
  msgDivDisplay('messages_reply_msg', msg || 'An error occurred while trying to send your reply.', false);
  spinnerHide('messages_indeterminate');
}



// ----------------------------------
// New Conversation
// ----------------------------------
function leaveNewConversation() {
  $('conversation_new_back').stopObserving('click');
  $('conversation_new_to').disabled = true;
  $('conversation_new_reply').disabled = true;
  $('conversation_new_subject').disabled = true;
  $('conversation_new_question').disabled = true;
  $('conversation_new_content').disabled = true;
  $('conversation_new_preview').disabled = true;
  $('conversation_new_preview').stopObserving('click');
  $('conversation_new_send').disabled = true;
  $('conversation_new_send').stopObserving('click');
  $('conversation_new_content_preview').update();
  msgDivClear('conversation_new_msg');
  loadConversations();
}

function loadNewConversation() {
  spinnerShow('conversation_new_indeterminate');
  msgDivClear('conversations_archive_msg');
  $('conversation_new_to_row').hide();
  $('conversation_new_reply_row').hide();

  var back = $('conversation_new_back');
  back.observe('click', function(event) {
    leaveNewConversation();
  });
  
  var subject = $('conversation_new_subject');
  subject.disabled = false;
  subject.value = '';
  
  var content = $('conversation_new_content');
  content.disabled = false;
  content.value = '';
  
  var preview = $('conversation_new_preview');
  preview.disabled = false;
  preview.observe('click', function(event) {
    doNewConversationPreview();
  });

  var send = $('conversation_new_send');
  send.disabled = true;
  send.observe('click', function(event) {
    doNewConversationSend();
  });
  
  ajaxWrapper('api/messages/new_conversation', {course: courseID}, null, loadNewConversationSuccess, loadNewConversationFailure);
  slideAndShowNewConversation();
}

function loadNewConversationSuccess(json) {
  // update the TO fields
  var s = $('conversation_new_to');
  s.disabled = false;
  s.update();
  json.to.each(function(group) {
    var optgroup = new Element('optgroup', {label: group.name});
    s.appendChild(optgroup);
    group.people.each(function(address) {
      var opt = new Element('option', {value: address[0]});
      optgroup.appendChild(opt);
      opt.insert(address[1]);
    });
  });
  
  // update the REPLY fields
  s = $('conversation_new_reply');
  s.disabled = false;
  s.update();
  json.reply.each(function(address) {
    var opt = new Element('option', {value: address[0]});
    s.appendChild(opt);
    opt.insert(address[1]);
  });
  
  // update the list of questions
  s = $('conversation_new_question');
  s.disabled = false;
  s.update();
  var opt = new Element('option', {value: '', selected: 'selected'});
  s.appendChild(opt);
  opt.insert('-');
  json.qnsets.each(function(qnset) {
    var optgroup = new Element('optgroup', {label: qnset.name});
    s.appendChild(optgroup);
    qnset.questions.each(function(question) {
      opt = new Element('option', {value: question.id});
      optgroup.appendChild(opt);
      opt.insert(question.name);
    });
  });
  
  // show advanced fields if admin
  if (json.is_admin) {
    $('conversation_new_to_row').show();
    $('conversation_new_reply_row').show();
  }

  spinnerHide('conversation_new_indeterminate');
}

function loadNewConversationFailure(transport, msg) {
  msgDivDisplay('conversation_new_msg', msg || 'An error occured while trying to display this page.', false);
  spinnerHide('conversation_new_indeterminate');
}


function doNewConversationPreview() {
  spinnerShow('conversation_new_indeterminate');
  msgDivClear('conversation_new_msg');
  $('conversation_new_content_preview').update();
  ajaxWrapper('api/messages/render', {content: $('conversation_new_content').value}, function(json) { return json.html; }, doNewConversationPreviewSuccess, doNewConversationPreviewFailure);
}

function doNewConversationPreviewSuccess(json) {
  $('conversation_new_send').disabled = false;
  $('conversation_new_content_preview').innerHTML = '<h3>Preview</h3>\n' + json.html;
  MathJax.Hub.Queue(['Typeset', MathJax.Hub, 'conversation_new_content_preview']);
  spinnerHide('conversation_new_indeterminate');
}

function doNewConversationPreviewFailure(transport, msg) {
  $('conversation_new_send').disabled = true;
  msgDivDisplay('conversation_new_msg', msg || 'An error occurred while trying to generate your preview.', false);
  spinnerHide('conversation_new_indeterminate');
}

function doNewConversationSend() {
  spinnerShow('conversation_new_indeterminate');
  msgDivClear('conversation_new_msg');
  $('conversation_new_content_preview').update();
  $('conversation_new_send').disabled = true;
  var data = {course: courseID, to: $('conversation_new_to').value, reply: $('conversation_new_reply').value, subject: $('conversation_new_subject').value, content: $('conversation_new_content').value};
  if ($('conversation_new_question').value)
    data['question'] = $('conversation_new_question').value;
  ajaxWrapper('api/messages/create', data, null, doNewConversationSendSuccess, doNewConversationSendFailure);
}

function doNewConversationSendSuccess(json) {
  spinnerHide('conversation_new_indeterminate');
  leaveNewConversation();
}

function doNewConversationSendFailure(transport, msg) {
  msgDivDisplay('conversation_new_msg', msg || 'An error occured while trying to create your new message.', false);
  spinnerHide('conversation_new_indeterminate');
}

