/* Collection of updates methods */
var Updates = {
  
  loadedTabIds: [],
  selectedTabIndex: 0,
  composeDims: {
    min: {width: 194, height: 32},
    max: {width: 398, height: 125}
  },
  submitting: false, // record if we're submitting something so we can avoid double posts
  
  /* Register a new tab */
  addTab: function(tab) {
    this.loadedTabIds.push(tab.container.id);
    if (!tab.hidden) {
        this.selectedTabIndex = this.loadedTabIds.length - 1;
    }
  },
  
  /* Switch between update blocks */
  toggle: function() { 
    var tabs = document.getElement('.updates-title').getElements('.updates-tab');
    var selectedTab = tabs[this.selectedTabIndex];
    var otherTab = tabs[(this.selectedTabIndex + 1) % 2];
    
    // Change selection
    selectedTab.removeClass('selected');
    otherTab.addClass('selected');
    
    // Copy link from other tab
    var a = otherTab.getElement('a').clone().set('text', '');
    
    // Add elements to link
    selectedTab.getElement('h2').clone().inject(a);
    
    // Add link to tab
    selectedTab.innerHTML = '';
    a.inject(selectedTab);
    
    // Remove link from other tab
    otherTab.adopt(otherTab.getElement('h2'));
    otherTab.getElement('a').dispose();
    
    // Show/hide updates
    $(this.loadedTabIds[this.selectedTabIndex]).setStyle('display', 'none');
    $(this.loadedTabIds[(this.selectedTabIndex + 1) % 2]).setStyle('display', '');
    
    // Update selectedTabIndex
    this.selectedTabIndex = (this.selectedTabIndex + 1) % 2;
  },
  
  /* Resize, if required, the compose textarea */
  composeDisplay: function(focused, callback) {
    focused = (focused != undefined) ? focused : false;
    var composeDiv = $('update-compose');
    var textarea = composeDiv.getElement('textarea');
    var controls = $(textarea.parentNode).getElement('.update-compose-controls');
    var hasBook = $('ComposeBookSelect_hidden').value !== '';
    var isEmpty = textarea.value.trim() === '';
    var isDefault = textarea.value.trim() == textarea.defaultValue;
    
    // Resize textarea
    var settings = {};
    if (hasBook) {
      settings.width = this.composeDims.min.width;
      settings.height = this.composeDims.max.height;
    } else {
      if ((isEmpty || isDefault) && !focused) {
        settings.width = this.composeDims.max.width;
        settings.height = this.composeDims.min.height;
      } else {
        settings.width = this.composeDims.max.width;
        settings.height = this.composeDims.max.height;
      }
    }
    
    this.resizeTextarea(textarea, settings);
    if (callback != undefined) {
      callback.delay(700);
    }
    
    var effect = new Fx.Morph(controls);
    
    // Show controls
    if (hasBook || !isDefault || focused) {
      if (controls.getStyle('display') == 'none') {
        controls.setStyles({opacity: 0, display: ''});
        effect.start({opacity: 1});
      }
    }
    
    // Hide controls
    else {
      controls.setStyles({opacity: 0, display: 'none'});
      effect.start({opacity: 0});
    }
    
    // Reset textarea
    if (focused && isDefault) {
      textarea.value = '';
    }
  },
  
  /* Actions to perform when the compose textarea is focused */
  composeFocus: function() {
    this.composeDisplay(true);
  },
  
  /* Choose a book when composing */
  composeChooseBook: function() {
    var bookId = $('ComposeBookSelect_hidden').value;
    if (bookId === '') {
      return;
    }
    var composeDiv = $('update-compose');
    var textarea = composeDiv.getElement('textarea');
    new Request({
      url: LIVING_SITE_URL+'/books/book_summary/'+bookId+'/'+$time(),
      method: 'get',
      onComplete: function() {
        
        var response = this.response.text;
        var bookDiv = $('book_summary_preview');
        bookDiv.setStyle('opacity', 0);
        
        var showBook = function() {
          bookDiv.innerHTML = response;
          
          // Show 'remove' button
          Updates.composeInjectRemoveBookButton(bookDiv);
          var effect = new Fx.Morph(bookDiv);
          effect.start({opacity: 1});
        };
        
        if (bookDiv.innerHTML === '') {
          Updates.composeDisplay(false, showBook);
        } else {
          showBook();
        }
      }
    }).send();
  },
  
  /* Add the remove book button */
  composeInjectRemoveBookButton: function(bookDiv) {
    new Element('img', {
      align: 'absmiddle',
      title: UPDATE_REMOVE,
      alt: UPDATE_REMOVE,
      src: '/img/button_remove_off.png',
      events: {
        mouseup: function() {
          btup(this);
        },
        mousedown: function() {
          btdown(this);
        },
        mouseout: function() {
          btup(this);
          unhlight(this);
        },
        mouseover: function() {
          hlight(this);
        },
        click: function() {
          Updates.composeRemoveBook();
        }
      },
      styles: {
        cursor: 'pointer',
        'margin-top': '5px'
      }
    }).inject(bookDiv);
  },
  
  /* Remove a book when composing */
  composeRemoveBook: function() {
    var composeDiv = $('update-compose');
    var bookId = $('ComposeBookSelect_hidden').value;
    if (bookId === '') {
      return;
    }
    var textarea = composeDiv.getElement('textarea');
    var bookDiv = $('book_summary_preview');
    $('ComposeBookSelect_hidden').value = '';
    var effect = new Fx.Morph(bookDiv);
    effect.start({opacity: 0}).chain(function() {
      bookDiv.empty();
      $('ComposeBookSelect').value = $('ComposeBookSelect').defaultValue;
      Updates.composeDisplay();
    });
  },
  
  /* Submit a composed public update */
  composeSubmit: function() {
    if (this.submitting) {
      return;
    }
    this.submitting = true; 
    var composeDiv = $('update-compose');
    var textarea = composeDiv.getElement('textarea');
    var message = textarea.value;
    if (message.trim() === '' || message.trim() == textarea.defaultValue) {
      alert(UPDATES_ALERT_EMPTY_COMMENT);
      textarea.select();
      return;
    }
    var updateId = $('ComposeUpdateId').value;
    var bookId = $('ComposeBookSelect_hidden').value;
    new Request({
      url: LIVING_SITE_URL+'/updates/compose/'+updateId+'/'+$time(),
      method: 'post',
      data: {
        message: message,
        bookId: bookId
      },
      onComplete: function() {
        
        // Refresh the public updates
        if (updateId == '0') {
          Updates.refresh(['public','highlight']);
        }
        
        // Update exiting update
        else {
          var updateDiv = $('up-' + updateId);
          var oldBookSummary = updateDiv.getElement('.book-summary');
          if (oldBookSummary !== null) {
            oldBookSummary.dispose();
          }
          if (bookId !== '') {
            composeDiv.getElement('.book-summary').clone().injectTop(updateDiv.getElement('.update-public-message'));
          }
          updateDiv.getElements('.update-public-message p').each(function(p) {
            p.dispose();
          });
          var reference = updateDiv.getElement('.update-public-message a.blue_text');
          if (reference === null) {
            reference = updateDiv.getElement('.update-public-message');
          }
          var lines = message.split('\n');
          for (var i = lines.length - 1; i >= 0; i--) {
            if (lines[i] !== '') {
              new Element('p').set('text', lines[i]).injectAfter(reference);
            }
          }
        }
        Updates.submitting = false;
        Updates.composeReset();
      },
      onFailure: function() {
        Updates.submitting = false;
      }
    }).send();
  },
  
  /* Edit a message */
  composeEdit: function(updateDiv) {
    for (var i = document.getScroll().y; i >= 150; i-=4) {
      window.scrollTo(0, i);
    }
    
    var composeDiv = $('update-compose');
    var textarea = composeDiv.getElement('textarea');
    
    // Set update ID
    $('ComposeUpdateId').value = updateDiv.id.split('-')[1];
    
    // Set book and 'remove' button
    var bookSummary = updateDiv.getElement('.book-summary');
    if (bookSummary !== null) {
      var bookPreview = $('book_summary_preview');
      var bookId = bookSummary.getElement('a').getAttribute('href').split('/')[3];
      $('ComposeBookSelect_hidden').value = bookId;
      bookPreview.innerHTML = '';
      this.composeDisplay(false, function() {
        bookSummary.clone().inject(bookPreview);
        Updates.composeInjectRemoveBookButton(bookPreview);
        if (bookPreview.getStyle('opacity') != 1) {
          var effect = new Fx.Morph(bookPreview);
          effect.start({opacity: 1});
        }
      });
    }
    
    // Set message
    textarea.value = '';
    updateDiv.getElements('.update-public-message p').each(function(p) {
      if (p.className != 'time') {
        textarea.value += p.innerHTML + '\n';
      }
    });
    
    textarea.focus();
  },
  
  /* Reset the compose 'form' */
  composeReset: function() {
    var composeDiv = $('update-compose');
    var input = $('ComposeBookSelect');
    $('ComposeBookSelect_hidden').value = '';
    $('ComposeUpdateId').value = '0';
    input.value = input.defaultValue;
    
    var textarea = composeDiv.getElement('textarea');
    textarea.value = textarea.defaultValue;
    
    var bookPreview = $('book_summary_preview');
    if (bookPreview.innerHTML !== '') {
      bookPreview.empty();
    }
    
    this.composeDisplay();
  },
  
  /* Resize a textarea - could be used elsewhere if required */
  resizeTextarea: function(ta, settings) {
    var textarea = $(ta);
    var textColour = textarea.getStyle('color');
    var bgColour = textarea.getStyle('background-color');
    var fader = new Fx.Morph(textarea, {duration: 250});
    var resizer = new Fx.Morph(textarea, {duration: 250});
    
    // Height
    if ('height' in settings && parseInt(textarea.getStyle('height'), 10) != eval('settings.height')) {
      fader.start({color: bgColour}).chain(function() {
        resizer.start({height: settings.height}).chain(function() {
          fader.start({color: textColour});
        });
      });
    }
    
    // Width
    if ('width' in settings && parseInt(textarea.getStyle('width'), 10) != eval('settings.width')) {
      fader.start({color: bgColour}).chain(function() {
        resizer.start({width: settings.width}).chain(function() {
          fader.start({color: textColour});
        });
      });
    }
  },
  
  /* Refresh updates, optionally by filter which may be a string defining one filter or array defining one or more */
  refresh: function(filter) {
    var update;
    for (var i = this.loadedTabIds.length - 1; i >= 0; i--) {
      eval('update = ' + this.loadedTabIds[i] + ';');
      if (filter == undefined || filter == update.filter || (typeof filter == 'object' && filter.contains(update.filter))) {
        update.refresh();
      }
    }
  },
  
  /* Make a string of update IDs and their associated comments for telling the server which to exclude */
  hashToString: function(hash) {
    var str = '';
    hash.each(function(value, key){
      str = str + key;
      if (value.length > 0) {
        str = str + ':';
        str = str + value.join(',');
      }
      str = str + ';';
    });
    return str;
  },
  
  /* Show more of a post or comment */
  showMore: function(type, id, el) {
    var url;
    switch (type) {
      case 'post':
        url = '/updates/getUpdateText/' + id;
        break;
      case 'comment':
        url = '/updates/editCommentText/' + id;
        break;
      default:
        return;
    }
    var div = $(el).parentNode.parentNode;
    loadingIndicator(div);
    new Request({
      url: url,
      method: 'get',
      onComplete: function(response) {
        div.set('html', response);
      }
    }).send();
  }
};

/* Class to manage updating */
function Updater(container, filter, id) {
  this.container = $(container);
  this.filter = (filter == undefined) ? 'regular' : filter;
  this.id = (id == undefined) ? 0 : id;
  this.hidden = false;
  this.refreshing = false;
  this.timer = null;
  this.interval = 30000; // ms
  this.loaded = null;
  this.debugOutput = $('debugOutput');
  this.commentsVisible = 2;
  
  var self = this; // an alternate name for 'this' so can be used within child classes
  
  this.init = function(){
    this.debug('Initialising');
    
    // Fill the container for the first time if empty
    if (this.container.innerHTML.trim() === '') {
      this.debug('Loading updates');
      new Request({
        url: LIVING_SITE_URL+'/updates/getUpdatesAjax/'+this.filter+'/'+this.id+'/'+$time(),
        method: 'get',
        onComplete: function(response) {
          self.container.set('html', response);
        }
      }).send();
    } else {
      this.debug('Skipping loading');
    }
    
    self.setLoaded();
  };
  
  this.start = function(){
    this.debug('Refreshing');
    
    // Auto init
    if (this.loaded === null) {
      this.init();
    }
    
    this.timer = setTimeout(function(){
      self.refresh();
    }, this.interval);
  };
  
  this.stop = function(){
    this.debug('Stopped');
    clearTimeout(this.timer);
  };
  
  this.setLoaded = function(){
    var tmpHash = new Hash();
    var updates = this.container.getElements('div.update');
    var updateId;
    var commentId;
    var commentIds = [];
    updates.each(function(update){
      updateId = update.getProperty('id').substring(3);
      commentIds = [];
      update.getElements('div.update-comment').each(function(comment){
        commentId = comment.getProperty('id').substring(3);
        commentIds.push(commentId);
      });
      
      tmpHash.set(updateId, commentIds);
    });
    this.loaded = tmpHash;
  };
  
  this.refresh = function() {
    clearTimeout(this.timer);
    this.start();
    if (this.refreshing) {
      this.debug('Already refreshing');
      return;
    }
    if (this.loaded === null) {
      this.debug('Not loaded');
      return;
    }
    this.refreshing = true;
    var updates = this.container.getElements('div.update');
    var firstSeparator = this.container.getElement('.blue_separator');
    var updatesId = this.id;
    
    // See if any new updates or comments are available
    new Request({
      url: LIVING_SITE_URL+'/updates/getNew/'+this.filter+'/'+this.id+'/'+$time(),
      method: 'post',
      data: {omit: Updates.hashToString(self.loaded)},
      evalResponse: true,
      onComplete: function() {
      
        // Updates
        newUpdates.updates.each(function(updateId){ // newUpdates is created in the response
          self.debug('New update, ' + updateId);
          // Check we don't have this update already
          if (!self.loaded.get(updateId)) {
            new Request({
              url: LIVING_SITE_URL+'/updates/getUpdate/'+self.filter+'/'+updateId+'/'+updatesId+'/'+$time(),
              method: 'get',
              onFailure: function(){
                self.debug('Getting update failed');
                self.loaded.set(updateId, []); // add to list to avoid getting again
              },
              onComplete: function() {
                var wrapper = new Element('div');
                wrapper.innerHTML = this.response.text;
                wrapper.getElement('div').injectAfter(firstSeparator);
                self.loaded.set(updateId, []);
              }
            }).send();
          } else {
            self.debug('Skipping already loaded update, ' + updateId);
          }
        });
        
        // Comments
        newUpdates.comments.each(function(commentIds, updateId){
          commentIds.each(function(commentId){
            self.debug('New comment, ' + commentId);
            // Check we don't have this comment already
            if (self.loaded.get(updateId) && !self.loaded.get(updateId).contains(commentId)) {
              new Request({
                url: LIVING_SITE_URL+'/updates/getComment/'+commentId+'/'+$time(),
                method: 'get',
                onComplete: function() {
                  var wrapper = new Element('div');
                  if (!wrapper) {
                    return;
                  }
                  wrapper.innerHTML = this.response.text;
                  
                  var update = self.getUpdate(updateId);
                  var comment = wrapper.getElement('div');
                  var comments = update.getElement('.update-comments');
                  var existingComments = update.getElements('.update-comment');
                  var footer;
                  
                  if (comments === null) {
                    comments = new Element('div', {
                      'class': 'update-comments'
                    }).injectBefore(update.getElement('.blue_separator'));
                    /*footer = new Element('div', {
                      'class': 'update-comment-footer'
                    }).inject(comments);
                    var form = new Element('form', {
                      method: 'post',
                      action: '#',
                      events: {
                        submit: function() {
                          return false;
                        }
                      }
                    }).inject(footer);*/
                    /*new Element('input', {
                      type: 'text',
                      'class': 'comment',
                      events: {
                        blur: function() {
                          updateCommentOnblur(this);
                        },
                        click: function() {
                          updateCommentOnclick(this);
                        },
                        keypress: function(event){
                          if(getKeyNum(event)==13) {
                            self.submitComment(this.form, updateId);
                            return false;
                          }
                        }
                      },
                      value: UPDATES_WRITE_A_COMMENT,
                      name: 'data[UpdateComment][comment]'
                    }).inject(form);*/
                  } else {
                    footer = comments.getElement('.update-comment-footer');
                  }
                  if (!footer) {
                    comment.inject(comments);
                  } else {
                    comment.injectBefore(footer);
                  }
                  self.setCommentToggle(updateId);
                  // scroll new comment into view if off page
                  var winTop = window.getScrollTop();
                  var winHeight = window.getHeight();
                  var elTop = comment.getTop();
                  var elHeight = comment.getSize().y;
                  if (winTop + winHeight < elTop) {
                      window.scrollTo(0, elTop - winHeight + elHeight + 40);
                  }
                  self.loaded.get(updateId).push(commentId);
                }
              }).send();
            } else {
              self.debug('Skipping already loaded comment, ' + commentId);
            }
          });
        });
        self.refreshing = false;
      }
    }).send();
  };
  
  /* Submit a comment to an update */
  this.submitComment = function(form, updateId) {
    var commentEl = form.elements[0];
    var comment = commentEl.value.trim();
    
    if (comment === '' || comment == commentEl.defaultValue) {
      alert(UPDATES_ALERT_EMPTY_COMMENT);
      commentEl.select();
      return;
    }
    
    new Request({
      url: LIVING_SITE_URL+'/updates/comment/'+updateId+'/'+$time(),
      method: 'post',
      data: {comment: comment},
      onComplete: function(){
        var result = this.response.text;
        if (result == '1') { // ok
          commentEl.value = commentEl.defaultValue;
          updateCommentOnblur(commentEl);
          if (UPDATES_COMMENT_SAVED !== '') {
            alert(UPDATES_COMMENT_SAVED);
          }
          self.refresh();
        } else { // failed
          alert(UPDATES_COMMENT_NOT_SAVED);
        }
      }
    }).send();
  };
  
  /* Show/hide comments */
  this.toggleComments = function(updateId) {
    var update = this.getUpdate(updateId);
    var comments = update.getElement('.update-comments'); 
    if (!comments) {
      return;
    }
    if (comments.getElement('div.hidden')) { // show
      comments.getElements('.update-comment').each(function(comment){
        comment.removeClass('hidden');
      });
    } else {                                 // hide
      var nComments = comments.getElements('.update-comment').length;
      var i = 0;
      comments.getElements('.update-comment').each(function(comment){
        if (i++ < nComments - this.commentsVisible) {
          comment.addClass('hidden');
        }
      }, this);
      if ((update.getTop() - window.getScrollTop()) < 0) { // if update is not visible...
        window.scrollTo(0, update.getTop()); // scroll to it (Fx.SmoothScroll is not available)
      }
    }
    this.setCommentToggle(updateId);
  };
  
  /* Set the link which shows or hides comments */
  this.setCommentToggle = function(updateId) {
    var update = this.getUpdate(updateId);
    var comments = update.getElement('.update-comments').getElements('.update-comment');
    var link = update.getElement('.updates-toggle-comments');
    
    if (comments.length <= this.commentsVisible) {
      if (link !== null) {
        link.dispose();
      }
      return;
    }
    
    if (link === null) {
      link = new Element('a', {
        'class': 'updates-toggle-comments',
        'href': '#'
      });
      link.setProperty('onclick', this.container.id + '.toggleComments('+updateId+'); return false;');
      link.injectBefore(update.getElement('.blue_separator'));
    }
    
    var hidden = false;
    for (var i = comments.length - 1; i >= 0; i--) {
      if (comments[i].hasClass('hidden')) {
        hidden = true;
        break;
      }
    }
    
    if (!hidden) {
      link.innerHTML = UPDATES_HIDE_COMMENTS;
    } else {
      var text = (comments.length == 1) ? UPDATES_SHOW_BOOK_COMMENTS_SINGULAR : UPDATES_SHOW_BOOK_COMMENTS_PLURAL;
      link.innerHTML = text.replace('%count%', comments.length);
    }
  };
  
  /* Get an update div within this container */
  this.getUpdate = function(id) {
    return document.getElement('#up-'+id, this.container);
  };
  

  /* Delete an update */
  this.deleteUpdate = function(id, conf, remove, isAdmin) {
    if (conf == undefined) {conf = true;}
    if (remove == undefined) {remove = true;}
    if (isAdmin == undefined) {isAdmin = false;}
    var confMessage = isAdmin ? UPDATE_CONFIRM_DELETION_ADMIN : UPDATE_CONFIRM_DELETION;
    if (conf && confMessage !== '' && !confirm(confMessage)) {
      return;
    }
    new Request({
      url: LIVING_SITE_URL+'/updates/delete/'+id+'/'+$time(),
      method: 'get',
      onComplete: function() {
        if (this.response.text == '1' && remove) {
          var update = self.getUpdate(id);
          var slide = new Fx.Slide(update);
          slide.slideOut().chain(function() {
            update.dispose();
          });
        }
      }
    }).send();
  };

  /* 'Like/unlike' an update */
  this.like = function(updateId, liked) {
    new Request({
      url: LIVING_SITE_URL+'/updates/like/'+updateId+'/'+liked+'/'+$time(),
      method: 'get',
      onComplete: function(){
        if (this.response.text != '1') {
          alert(this.response.text);
          return;
        }
        var likeCount = $('up-'+updateId).getElement('.like-count');
        var nLike = likeCount.innerHTML * 1;
        if (liked) {
          likeCount.innerHTML = ++nLike;
          $('like_'+updateId).title = UPDATES_UNLIKE;
          /*var update = self.getUpdate(updateId);
          var comments = update.getElement('.update-comments');
          if (comments !== null ) { // comments exist
            new Element('div', {
              'class': 'update-action-info'
            }).appendText(UPDATES_YOU_LIKE_THIS).injectTop(comments);
          } else { // no exiting comments
            comments = new Element('div', {
              'class': 'update-comments'
            }).injectBefore(update.getElement('.blue_separator'));
            new Element('div', {
              'class': 'update-action-info'
            }).appendText(UPDATES_YOU_LIKE_THIS).injectTop(comments);
          }
          comments.removeClass('hidden');*/
        } else {
          nLike--;
          if (nLike > 0) { // only show if greater than 0
            likeCount.innerHTML = nLike;
          } else {
            likeCount.innerHTML = '';
          }
          $('like_'+updateId).title = UPDATES_LIKE;
        }
        // Change count title
        if (nLike > 0) {
          var titleStr = nLike > 1 ? UPDATES_PEOPLE_LIKE_PLURAL : UPDATES_PEOPLE_LIKE_SINGULAR;
          likeCount.title = titleStr.replace(/%count%/, nLike);
        } else {
          likeCount.title = '';
        }
      }
    }).send();
  };
  
  /* Report an update */
  this.report = function(updateId) {
    new Request({
      url: LIVING_SITE_URL+'/updates/report/'+updateId+'/'+$time(),
      method: 'get',
      onComplete: function(){
        alert(UPDATES_REPORT_THANKS);
      }
    }).send();
  };
  
  this.highlight = function(updateId) {
    var update = this.getUpdate(updateId);
    var url;
    if (!update.hasClass('update-highlighted')) {
      new Request({
        url: LIVING_SITE_URL+'/updates/highlight/'+updateId+'/1/'+$time(),
        method: 'get',
        onComplete: function(){
          update.addClass('update-highlighted');
        }
      }).send();
    } else {
      new Request({
        url: LIVING_SITE_URL+'/updates/highlight/'+updateId+'/0/'+$time(),
        method: 'get',
        onComplete: function(){
          update.removeClass('update-highlighted');
        }
      }).send();
    }
  };
  
  this.debug = function(message) {
    if (this.debugOutput === null) {return;}
    this.debugOutput.set('text', this.container.id + ': ' + message + "\n" + this.debugOutput.get('text'));
  };
}

// TODO MK one rainy day, move the rest of the functions in this file into the Updates or Updater objects

/* Onclick functionality for update comments */
function updateCommentOnclick(ta) {
  $(ta.parentNode).setStyle('display', '');
  if (ta.value == ta.defaultValue) {
    ta.select();
  }
}

/* Onfocus functionality for update comments */
function updateCommentOnfocus(ta) {
  var ta = $(ta);
  if (ta.value.trim() === '') {
    ta.value = ta.defaultValue;
  }
  ta.addClass('comment-active');
  $(ta.parentNode).getChildren().setStyle('display', '');
}

/* Onblur functionality for update comments */
function updateCommentOnblur(ta, isFooter) {
  if (ta.value.trim() === '') {
    ta.value = ta.defaultValue;
  }
  if (ta.value == ta.defaultValue) {
    ta.removeClass('comment-active');
    if (isFooter) { // hide all but the textarea
      $(ta.parentNode).getChildren().each(function(el) {
        if (el.nodeName != 'TEXTAREA') {
          el.setStyle('display', 'none');
        }
      });
    } else {
      $(ta.parentNode).setStyle('display', 'none');
    }
  }
}

/* Onkeyup functionality for update comments */
function updateCommentOnkeyup(ta) {
  updateCommentResize(ta);
}

function updateCommentResize(ta) {
  var lines = 0;
  var charsPerLine = Math.floor(ta.getSize().x / 4.5);
  ta.value.split('\n').each(function(line){
    lines += Math.max(Math.ceil(line.length/charsPerLine), 1);
  });
  ta.setStyle('height', ((lines + 2) * 1.25) + 'em');
}

function updateCommentCancel(btn, isFooter) {
  ta = btn.parentNode.getElement('textarea');
  btn.parentNode.setStyle('display', 'none');
  ta.value = ta.defaultValue;
  updateCommentResize(ta);
}

/* Recommend a book to a user who is not currently reading one */
function recommendToUserNotReading(username) {
  var bookId = $('UpdatesRecommendBook_hidden').value;
  if (bookId === '') {
    return;
  }
  new Request({
    url: LIVING_SITE_URL+'/books/recommend/'+bookId+'/'+username+'/'+$time(),
    method: 'get',
    onComplete: function(){
      if (this.response.text == '1'){
        alert(SUCCESS);
        $('UpdatesRecommendBook').value = $('UpdatesRecommendBook').defaultValue;
      } else {
        alert(this.response.text);
      }
    }
  }).send();
}

/* Delete a comment */
function deleteUpdateComment(id) {
  if (UPDATE_CONFIRM_COMMENT_DELETION_ADMIN !== '' && !confirm(UPDATE_CONFIRM_COMMENT_DELETION_ADMIN)) {
    return;
  }
  new Request({
    url: LIVING_SITE_URL+'/updates/deleteComment/'+id+'/'+$time(),
    method: 'get',
    onComplete: function() {
      var comment = $('uc-'+id);
      var commentToggle = comment.getParent().getParent().getElement('.updates-toggle-comments');
      if (commentToggle) {
        commentToggle.dispose();
      }
      var comments = comment.getParent().getElements('.update-comment');
      var toRemove = comment;
      if (comments.length == 1) {
        toRemove = comment.getParent(); // remove all the comment elements
      }
      var slide = new Fx.Slide(toRemove);
      slide.slideOut().chain(function(){
        toRemove.getParent().dispose();
      });      
    }
  }).send();
}

/* Process a friend request action */
function updatesFriendRequestAction(friendReqId, status, updateId) {
  var data = {status:status, id:friendReqId};
  new Request({
    url: LIVING_SITE_URL+'/messages/change_friend_status/' +$time(),
    method: 'post',
    data:data,
    onComplete: function(){
      if(this.response.text != '1') {
        alert(this.response.text);
     }
      
      var update = $('up-'+updateId);
      var messageEl = update.getElement('.update-message');
      eval('var message = UPDATE_FRIEND_REQUEST_' + status.toUpperCase() + ';');
      var re = /<a[^<]*<\/a>/;
      var lnk = re.exec(messageEl.innerHTML);
      messageEl.innerHTML = message.replace('%username%', lnk);
      
      updater_regular.deleteUpdate(updateId, false, false);
    }
  }).send();
}

/* Process a group request action */
function updatesGroupRequestAction(groupReqId, status, updateId) {
  var data = {status:status, id:groupReqId};
  new Request({
    url: LIVING_SITE_URL+'/messages/change_vrg_member_status/' +$time(),
    method: 'post',
    data:data,
    onComplete: function(){
      if(this.response.text != '1') {
        alert(this.response.text);
        return;
      }
      
      var update = $('up-'+updateId);
      var messageEl = update.getElement('.update-message');
      var statusStr = (status == '1') ? 'ACCEPTED' : 'IGNORED';
      eval('var message = UPDATE_GROUP_REQUEST_' + statusStr + ';');
      var lnkMatches = messageEl.innerHTML.match(/<a[^<]*<\/a>/g);
      
      var newMessage = message.replace('%username%', lnkMatches[0]);
      newMessage = newMessage.replace('%group%', lnkMatches[1]);
      messageEl.innerHTML = newMessage;
      
      updater_group.deleteUpdate(updateId, false, false);
    }
  }).send();
}

/* Onclick event for editing comments */
function updatesEditCommentClick(commentId) {
  var wrapper = $('uctext-'+commentId);
  if (wrapper == undefined) {
    return;
  }
  
  var commentText = '';
  wrapper.getElements('p').each(function(el) {
    commentText += el.innerHTML + '\n';
  });
  
  var inputField = new Element('textarea', {
    'value': commentText,
    'class': 'comment-active'
  }).setStyle('margin', '5px 0 0 9px');
  
  var saveButton = new Element('img', {
    'src': '/img/button_save_off.png',
    'title': UPDATE_SAVE,
    'alt': UPDATE_SAVE,
    'styles': {
      'cursor': 'pointer',
      'padding-top': '5px',
      'padding-left': '49px'
    },
    'events': {
      'click': function(){
        updatesSaveComment(commentId);
      },
      'mouseover': function(e){
        butt = e.target || e.srcElement;
        hlight(butt);
      },
      'mouseout': function(e){
        butt = e.target || e.srcElement;
        btup(butt);
      },
      'mouseup': function(e){
        butt = e.target || e.srcElement;
        btup(butt);
      },
      'mousedown': function(e){
        butt = e.target || e.srcElement;
        btdown(butt);
      }
    }
  });
  
  var removeButton = new Element('img', {
    'src': '/img/button_remove_off.png',
    'title': UPDATE_REMOVE,
    'alt': UPDATE_REMOVE,
    'styles': {
      'cursor': 'pointer',
      'padding-left': '5px',
      'padding-top': '5px'
    },
    'events': {
      'click': function(){
        deleteUpdateComment(commentId);
      },
      'mouseover': function(e){
        butt = e.target || e.srcElement;
        hlight(butt);
      },
      'mouseout': function(e){
        butt = e.target || e.srcElement;
        btup(butt);
      },
      'mouseup': function(e){
        butt = e.target || e.srcElement;
        btup(butt);
      },
      'mousedown': function(e){
        butt = e.target || e.srcElement;
        btdown(butt);
      }
    }
  });
  
  removeButton.injectAfter(wrapper);
  saveButton.injectAfter(wrapper);
  new Element('br').injectAfter(wrapper);
  inputField.injectAfter(wrapper);
  wrapper.dispose();
}

/* Save an edited comment */
function updatesSaveComment(commentId) {
  var wrapper = $('uc-'+commentId);
  var ta = wrapper.getElement('textarea');
  var text = ta.value;
  if (text.trim() === '') {
    alert(UPDATES_ALERT_EMPTY_COMMENT);
    return;
  }
  new Request({
    url: LIVING_SITE_URL+'/updates/editComment/'+commentId+'/'+$time(),
    method: 'post',
    data: {comment:text},
    onComplete: function(){
      if (this.response.text == '1') {
        var span = new Element('span', {
          'id': 'uctext-' + commentId,
          'events': {
            'click': function(){
              updatesEditCommentClick(commentId);
            }
          }
        });
        text.split('\n').each(function(para) {
          span.appendChild(new Element('p').appendText(para));
        });
        span.injectBefore(ta);
        ta.dispose();
        span.nextSibling.dispose();
        span.nextSibling.dispose();
        span.nextSibling.dispose();
      }
    }
  }).send();
}

/* Add a discussion on a profile page */
function updatesOpenDiscussion(filter, id, last) {
  if ($('newDiscussion')) {
    return;
  }

  var firstSeparator;
  if (last) {
    firstSeparator = document.getElement('#add_comment_new');
  } else {
    firstSeparator = document.getElement('.updates').getElement('.blue_separator');
  }
  if ($('updates_info')) {
    $('updates_info').dispose();
  }
  newDiscussion = new Element('div', {
    id: 'newDiscussion'
  }).injectAfter(firstSeparator);

  var inputField = new Element('textarea', {
    'class': 'update-edit-field'
  });

  var saveButton = new Element('img', {
    'src': '/img/button_save_off.png',
    'title': UPDATE_SAVE,
    'alt': UPDATE_SAVE,
    'styles': {
      'cursor': 'pointer',
      'padding-top': '5px'
    },
    'events': {
      'click': function(){
        updatesAddDiscussion(filter, id);
      },
      'mouseover': function(e){
        butt = e.target || e.srcElement;
        hlight(butt);
      },
      'mouseout': function(e){
        butt = e.target || e.srcElement;
        btup(butt);
      },
      'mouseup': function(e){
        butt = e.target || e.srcElement;
        btup(butt);
      },
      'mousedown': function(e){
        butt = e.target || e.srcElement;
        btdown(butt);
      }
    }
  });

  var cancelButton = new Element('img', {
    'src': '/img/button_remove_off.png',
    'title': UPDATE_REMOVE,
    'alt': UPDATE_REMOVE,
    'styles': {
      'cursor': 'pointer',
      'padding-left': '5px',
      'padding-top': '5px'
    },
    'events': {
      'click': function(){
        newDiscussion.dispose();
      },
      'mouseover': function(e){
        butt = e.target || e.srcElement;
        hlight(butt);
      },
      'mouseout': function(e){
        butt = e.target || e.srcElement;
        btup(butt);
      },
      'mouseup': function(e){
        butt = e.target || e.srcElement;
        btup(butt);
      },
      'mousedown': function(e){
        butt = e.target || e.srcElement;
        btdown(butt);
      }
    }
  });

  new Element('h3', {
    styles: {
      padding: '6px 0'
    }
  }).appendText(UPDATE_BOOK_COMMENT_NEW).inject(newDiscussion);
  inputField.inject(newDiscussion);
  new Element('br').inject(newDiscussion);
  saveButton.inject(newDiscussion);
  cancelButton.inject(newDiscussion);
  inputField.focus();
}

/* Add a discussion */
function updatesAddDiscussion(filter, id) {
  var wrapper = $('newDiscussion');
  if (!wrapper) {
    return;
  }
  var text = wrapper.getElement('textarea').value;
  if (text.trim() === '') {
    alert(UPDATES_ALERT_EMPTY_COMMENT);
    return;
  }
  new Request({
    url: LIVING_SITE_URL+'/updates/addDiscussion/'+filter+'/'+id+'/'+$time(),
    method: 'post',
    data: {comment:text},
    onComplete: function(){
      if (this.response.text == '1') {
        wrapper.dispose();
        eval('updater_'+filter+'.refresh();');
      }
    }
  }).send();
  var firstpost = document.getElement('.updates-title');

  if (firstpost) {
    var scroll =  new Fx.Scroll(window, {
      wait: false,
      duration: 1000
    });
    scroll.start(0, 490);
  }
}
