/* Copyright (c) 2007 Infoteria Corp USA. All rights reserved. */

Chatroom = Class.create();
Chatroom.prototype = {
  initialize: function(options)
  {
    if (/MSIE/.test(navigator.userAgent)) 
    {
      this.IE  = true;
      this.IE7 = /MSIE 7\.0/.test(navigator.userAgent);
      
      if (this.IE7)
      {
        this.scrollElement = window;
        this.lastOffsetHeight = document.documentElement.offsetHeight;
      }
      else
      {
        this.scrollElement = $('ieWrapper');
      }
    }
    else
    {
      this.scrollElement = window;
    }

    this.soundEnabled = true;
    
    Object.extend(this, options.chatroom);

    this.chatSystem = new ChatSystem(
      Object.extend(options.chatsystem, {
        enterComplete: this.enterComplete.bind(this),
        beginNotifyMessages: this.beginNotifyMessages.bind(this),
        notifyMessage: this.notifyMessage.bind(this),
        endNotifyMessages: this.endNotifyMessages.bind(this),
        notifyConnected: this.notifyConnected.bind(this),
        notifyDisconnected: this.notifyDisconnected.bind(this),
        sayComplete: this.sayComplete.bind(this),
        exitComplete: this.exitComplete.bind(this),
        updateRoster: this.updateRoster.bind(this),
        notifyInitialHandle: this.notifyInitialHandle.bind(this),
        notifyReload: this.notifyReload.bind(this),
        setHandleComplete: this.notifySetHandleComplete.bind(this)
      }
    ));

    Event.observe(window, 'load', this.scrollToBottom.bind(this));
    Event.observe(window, 'load', function() { new Draggable('profile') });
    Event.observe(window, 'blur', this.onBlur.bindAsEventListener(this));
    Event.observe(window, 'focus', this.onFocus.bindAsEventListener(this));
    Event.observe('speakField', 'focus', this.onFocus.bindAsEventListener(this));
    Event.observe(window, 'resize', this.onResize.bindAsEventListener(this));
    Event.observe(this.scrollElement, 'scroll', this.onScroll.bind(this));
    
    this.newMessagePattern = /^\[(\d+)\] /;
    
    this.profile = new Profile({ url: options.chatroom.profileUrl });
    
    if (this.hasFlash() && this.soundUrl)
    {
      try
      {
        this.sound = new Sound();
        this.soundLoaded = false;
      }
      catch (e)
      {
        this.sound = null;
        this.soundEnabled = false;
      }
    }
    
    this.lastPrivateMessageIds = new Array();
  },

  beginNotifyMessages: function()
  {
    this.messageCount = 0;
    this.foreignMessageCount = 0;
    this.scrollWhenFinished = this.isScrolledToBottom();
  }, 
  
  notifyMessage: function(msg, render, realtime)
  {
    var redundant = false;
    
    if (render && !$('msg-' + msg.id))
    {
      if (msg.txt)
      {
        if (msg.target_client_id)
        {
          var img = this.signedIn ? this.privateMsgHandledImage : this.privateMsgAnonymousImage;
          var hdl = msg.hdl || (this.signedIn ? this.defaultNickname : this.privateMsgAnonymousLocalHandle);
          var target_hdl = msg.target_handle && msg.target_handle.length > 0 ? msg.target_handle : this.privateMsgAnonymousRemoteHandle;

          msg.h = this.privateMsgTemplate.replace(/%%hdl%%/g, this.replacerize(this.sanitize(hdl))).
            replace(/%%img%%/g, img).
            replace(/%%target_hdl%%/g, this.replacerize(this.sanitize(target_hdl))).
            replace(/%%target_client_id%%/g, msg.target_client_id).
            replace(/%%target_img%%/g, msg.target_image).
            replace(/%%msgid%%/g, 'pending-' + msg.localId).replace(/%%msg%%/, this.replacerize(this.decorate(msg.type, this.sanitize(msg.txt))));

            redundant = this.lastMessageType == 'private' && msg.type == 'private' && msg.target_handle == this.lastTargetHandle && 
              msg.target_client_id == this.lastTargetClientId;
        }
        else
        {
          msg.h = this.publicMsgTemplate.replace(/%%hdl%%/g, this.replacerize(this.sanitize(msg.hdl))).
            replace(/%%msgid%%/g, 'pending-' + msg.localId).replace(/%%msg%%/, this.replacerize(this.decorate(msg.type, this.sanitize(msg.txt))));

          redundant = this.lastMessageType == 'user' && msg.type == 'user' && msg.client == this.lastSpeaker && msg.hdl == this.lastHandle;
        }
      }
      else
      {
        if (msg.type == 'private')
        {
          redundant = this.lastMessageType == 'private' && msg.hdl == this.lastHandle && msg.client == this.lastSpeaker;
        }
        else if (msg.type == 'user')
        {
          redundant = this.lastMessageType == 'user' && msg.type == 'user' && msg.client == this.lastSpeaker && msg.hdl == this.lastHandle;
        }
      }
      
      var el = $('messages');
      var nc = el.childNodes.length;

      new Insertion.Bottom('messages', msg.h);
      
      for (var i = nc; i < el.childNodes.length; i++)
      {
        var thisEl = el.childNodes[i];

        if (thisEl.nodeType == 1)
        {
          if (!msg.txt && msg.client == this.clientId && (Element.hasClassName(thisEl, 'handle') || Element.hasClassName(thisEl, 'messageText') || msg.type == "system"))
          {
            Element.addClassName(thisEl, 'me');
          }

					if (Element.hasClassName(thisEl, 'handle'))
					{
						if (redundant)
						{
							Element.addClassName(thisEl, 'redundant');
							this.lastHandleId = null;
						}
						else
						{
  						this.lastHandleId = thisEl.id;
						}
					}
          
          if (Element.hasClassName(thisEl, 'messageText'))
          {
            if (this.IE && !this.IE7 && msg.type != 'private')
            {
              prepPermalink(thisEl);
            }
            
            if (msg.type == 'private')
            {
              if (redundant)
  						{
  						                  Element.addClassName(this.lastPrivateMessageIds.last(), 'notLast');
                
                var reply = document.getElementsByClassName('reply', this.lastPrivateMessageIds.last())[0];
                if (reply)
                {
                  reply.remove();
                }
  						}
  						else
  						{
  						    						  this.lastPrivateMessageIds.clear();
  						}

              if (msg.localId)
              {
                this.lastPrivateMessageIds.push('private-msg-pending-' + msg.localId);
                              }
              else if (msg.temp_id)
              {
                this.lastPrivateMessageIds.push('private-msg-' + msg.temp_id);
                
                if (this.lastPrivateMessageIds.length > 1)
                {
                  this.lastPrivateMessageIds.shift();
                }
    				  }
            }            
            
            this.lastTextMessageId = thisEl.id;
          }
          
          if (Element.hasClassName(thisEl, 'message'))
          {
            this.lastMessageId = thisEl.id;
          }
        }
      }
      
      if (realtime && msg.type != "system")
      {
        this.highlightLastMessage();
        this.messageCount++;

        if (msg.client != this.clientId)
        {
          this.foreignMessageCount++;
        }
      }
    
      if (msg.type != "system")
      {
        this.lastSpeaker = msg.client;
				this.lastMessageType = msg.type;
				this.lastHandle = msg.hdl;
				
				if (msg.type == 'private')
				{
				  this.lastTargetHandle = msg.target_handle;
				  this.lastTargetClientId = msg.target_client_id;
			  }
			  else
			  {
			    this.lastTargetClientId = this.lastTargetHandle = null;
			    this.lastPrivateMessageIds.clear();
			  }
      }
      else
      {
        this.lastSpeaker = this.lastMessageType = this.lastTargetHandle = this.lastTargetClientId = null;
        this.lastPrivateMessageIds.clear();
      }
    }
  },
  
  endNotifyMessages: function()
  {
    this.afterMessagesInserted(this.scrollWhenFinished);
  },
  
  afterMessagesInserted: function(forceScroll)
  {
    if (this.isScrolledToBottom() || forceScroll)
    {
      this.scrollToBottom();
    }
    
    if ((this.blurred || !this.isScrolledToBottom()) && this.foreignMessageCount > 0)
    {
      if (match = document.title.match(this.newMessagePattern))
      {
        document.title = document.title.replace(this.newMessagePattern, '[' + (parseInt(match[1]) + this.messageCount).toString() + '] ');
      }
      else
      {
        document.title = '[' + this.messageCount + '] ' + document.title;
      }
    }
    
    if (this.isScrolledToBottom())
    {
      this.pruneMessages();
    }
    
    if (this.sound && this.soundEnabled && this.foreignMessageCount > 0)
    {
      this.playSound();
    }
  },
  
  highlightLastMessage: function()
  {
    if (this.lastHandleId)
    {
      var endcolor = '#ffffff';
      if (Element.hasClassName(this.lastHandleId, 'private'))
      {
        if (Element.hasClassName(this.lastHandleId, 'me'))
        {
          endcolor = '#f9fff8';
        }
        else
        {
          endcolor = '#f3fdfd';
        }
      }
      new Effect.Highlight(this.lastHandleId, { endcolor: endcolor, restorecolor: endcolor });
    }
    
    if (this.lastTextMessageId)
    {
      var endcolor = '#ffffff';
      if (Element.hasClassName(this.lastTextMessageId, 'private'))
      {
        if (Element.hasClassName(this.lastTextMessageId, 'me'))
        {
          endcolor = '#f9fff8';
        }
        else
        {
          endcolor = '#f3fdfd';
        }
      }
      new Effect.Highlight(this.lastTextMessageId, { endcolor: endcolor, restorecolor: endcolor });
    }
  },

  sayComplete: function(response)
  {
    if (response.msgs)
    {
      for (var i = 0; i < response.msgs.length; i++)
			{
			  var id = (response.msgs[i].type == 'private' ? 'private-msg-pending-' : 'msg-pending-') + response.l[i];
			  Element.replace(id, response.msgs[i].h);
			  
			  if (response.msgs[i].type == 'private')
			  {
			    var index = this.lastPrivateMessageIds.length == 1 ? 0 : Element.hasClassName(this.lastPrivateMessageIds[0], 'pending') ? 0 : 1;
			    var new_id = 'private-msg-' + response.r[i];
			    
			              
			    this.lastPrivateMessageIds[index] = new_id;

			    if (this.lastPrivateMessageIds.length > 1)
			    {
			      if (index == 1)
			      {
              			        Element.addClassName(this.lastPrivateMessageIds[1], 'notLast');
			      }
			      			      
			      this.lastPrivateMessageIds.shift();
			      			    }
			  }
			  
			  id = 'timestamp-pending-' + response.l[i];
			  $(id).innerHTML = response.ts[i];
			  $(id).title = response.fts[i];
			  Element.removeClassName($(id).parentNode, 'pending');
		  }
    }
    else if (response.mi)
    {
      for (var i = 0; i < response.mi.length; i++)
			{
			  var id = 'msg-pending-' + response.mi[i].l;
			  var new_id = 'msg-' + response.mi[i].r;
			  $('saying-' + id).remove();
			  $(id).id = new_id;
			  Element.removeClassName(new_id, 'pending');
			  $(new_id).title = response.mi[i].fts;
        
			  id = 'permalink-msg-pending-' + response.mi[i].l;
			  new_id = 'permalink-msg-' + response.mi[i].r;
			  $(id).id = new_id;
		    $(new_id).href = response.mi[i].link;

			  id = 'timestamp-pending-' + response.mi[i].l;
			  new_id = 'timestamp-' + response.mi[i].r;
			  $(id).id = new_id;
			  $(new_id).innerHTML = response.mi[i].ts;
			  $(new_id).title = response.mi[i].fts;
		  }
    }
    else if (response.pmfail)
    {
      alert("Sorry, but " + response.pmfail.handle + " has left the room, and so can't receive any private messages.");
      
      if ($('profilePM'))
      {
        Effect.BlindUp('profilePM', {
          duration: 0.4,
          afterFinish: function() { Element.remove('profilePM') }
        });
      }
    }
    
    this.afterMessagesInserted(true);
    $('speakFormSubmit').value = "Say it!";
    
    if ($('profilePMSubmit') != null)
    {
      $('profilePMSubmit').value = 'Say it privately!';
    }
  },

  enterComplete: function(response)
  {
  },

  notifyConnected: function()
  {
    if ($('connectionStatus'))
    {
      $('connectionStatus').className = 'connected';
      // $('speakField').disabled = false;
      $('speakFormSubmit').disabled = false;
      $('initialHandle').disabled = false;
      $('initialHandleSubmit').disabled = false;
      Element.hide('initialHandleProgress');
      if (!$('chatFooterWrapper').visible)
      {
        // Effect.BlindDown('chatFooterWrapper', { duration: 0.4 } );
      }
    }
  },
  
  notifyDisconnected: function()
  {
    if (!this.leaving && $('connectionStatus'))
    {
      $('connectionStatus').className = 'disconnected';
      // $('speakField').disabled = true;
      $('speakFormSubmit').disabled = true;
      $('initialHandle').disabled = true;
      $('initialHandleSubmit').disabled = true;
      Element.show('initialHandleProgress');
      if ($('chatFooterWrapper').visible)
      {
        // Effect.BlindUp('chatFooterWrapper', { duration: 0.4 } );
      }
    }
    
    window.observer = null;
  },

  startup: function()
  {
    this.chatSystem.enter();
    this.scrollToBottom();
  },

  _onload: function()
  {
    this.buttonSync('speakFormSubmit', 'speakField');
    
    window.setTimeout(this.startup.bind(this), 100);
  },

  buttonSync: function(button, field)
  {
    $(button).disabled = $F(field).blank();
  },
  
  doMessageKeypress: function(e, field, isPrivate)
  {
    if (e.keyCode == Event.KEY_RETURN && !e.shiftKey) {
      Event.stop(e);
      
      if ($F(field).blank()) { return }
      
      if (!isPrivate) {
        this.say();
      } else {
        if (field.id == 'profilePMText')
        {
          chatroom.profile.onSubmit();
        }
      }
    }
    else if (e.keyCode == Event.KEY_ESC)
    {
      if (field.id == 'profilePMText')
      {
        chatroom.profile.hide();
      }
    }
  },
  
  doMessageKeyup: function(e, button, field)
  {
    this.buttonSync(button, field);
  },

  beforeMessageSubmitted: function(buttonId, fieldId)
  {
    var button = $(buttonId);
    var field = $(fieldId);
    
    button.value = 'Sending...';
    button.disabled = true;
    
    field.value = '';
    Field.activate(field);
    
    this.buttonSync(button, field);
  },

  say: function()
  {
    var msg = $F('speakField');
    this.beforeMessageSubmitted('speakFormSubmit', 'speakField');
    this.chatSystem.say(msg);
  },
  
  pm: function(textId, clientIdId, handleId, imageId, submitId)
  {
    var text = $F(textId);
    var targetClientId = $F(clientIdId);
    var targetHandle = $F(handleId);
    var targetImage = $F(imageId);
    this.beforeMessageSubmitted(submitId, textId);
    this.chatSystem.pm(text, targetClientId, targetHandle, targetImage);
	},
  
  updateRoster: function(roster)
  {
    Element.replace('roster', roster);
    var item = $('roster-' + this.clientId);
    if (item)
    {
      Element.addClassName(item, 'me');
    }
  },
  
  exit: function(url)
  {
    this.leaving = true;
    this.notifyLeaving();
    this.chatSystem.exit();
    if (url)
    {
      setTimeout(function() { window.location.href = url; }, 500);
    }
  },
  
  notifyLeaving: function()
  {
    if ($('connectionStatus'))
    {
      $('connectionStatus').className = 'leaving';
      $('speakField').disabled = true;
      $('speakFormSubmit').disabled = true;
    }
  },
  
  exitComplete: function(response)
  {
  },

  doInitialHandleKeypress: function(e)
  {
    if (e.keyCode == Event.KEY_RETURN)
    {
      if ($F('initialHandle').blank())
      {
        Event.stop(e);
      }
    }
    
    return false;
  },
  
  doInitialHandleKeyup: function(e)
  {
    this.buttonSync('initialHandleSubmit', 'initialHandle');
  },
  
  notifyInitialHandle: function(handle)
  {
    if (handle == null)
    {
      $('chatFooterWrapper').className = 'hasNoHandle';
      $('initialHandle').value = this.suggestedNickname;
      Effect.BlindDown('chatFooterWrapper', {
        duration: 0.4,
        afterFinish: function() { Field.activate('initialHandle'); }
      });
    }
    else
    {
      this.setHandleUI(handle, true);
    }
  },
  
  setHandle: function(handle, initial)
  {
    if (this.handleLengthLimit)
    {
      handle = handle.truncate(this.handleLengthLimit, '');
    }
    
    $('speakField').disabled = true;
    $('speakFormSubmit').disabled = true;
    
    if (initial)
    {
      $('initialHandle').disabled = true;
      $('initialHandleSubmit').disabled = true;
      Element.show('initialHandleProgress');
    }
    
    this.chatSystem.sethandle(handle);
  },

  setHandleUI: function(handle, effects)
  {
    var display_handle = this.sanitize(handle);
    $('speakHandle').innerHTML = display_handle;
    var footer = $('chatFooterWrapper');
    
    if (effects)
    {
      if (handle && !handle.blank() && ($('connectionStatus').className != 'disconnected'))
      {
        if (Element.hasClassName(footer, 'hasNoHandle'))
        {
          Effect.BlindUp(footer, { duration: 0.4,
            afterFinish: function(effect)
            {
              footer.className = 'hasHandle';
              chatroom.showFooter('speakField');
            }
          });
        }
        else
        {
          chatroom.showFooter('speakField');
        }
      }
      else
      {
        if (Element.hasClassName(footer, 'hasHandle'))
        {
          Effect.BlindUp(footer, { duration: 0.4,
            afterFinish: function(effect)
            {
              footer.className = 'hasNoHandle';
              chatroom.showFooter('initialHandle');
            }
          });
        }
        else
        {
          chatroom.showFooter('initialHandle');
        }
      }
    }
  },
  
  scrollToBottom: function()
  {
    if (!this.lastMessageId || !$(this.lastMessageId))
    {
      var msgs = document.getElementsByClassName('message', 'messages');
      if (msgs.length > 0)
      {
        this.lastMessageId = msgs[msgs.length - 1].id;
      }
    }

    if (this.lastMessageId)
    {
      if (this.IE && !this.IE7)
      {
        $('ieScrollAnchor').scrollIntoView(true);
      }
      else
      {
        var element = $(this.lastMessageId);
        var x = element.x ? element.x : element.offsetLeft,
            y = element.y ? element.y : element.offsetTop;
        
        window.scrollTo(x, y + element.clientHeight);
      }
    }
    
    if (!this.blurred)
    {
      this.clearDocumentTitle();
    }
  },
  
  clearDocumentTitle: function()
  {
    document.title = document.title.replace(this.newMessagePattern, '');
  },
  
  notifyReload: function()
  {
    window.location.reload();
  },
  
  notifySetHandleComplete: function(response)
  {
    $('speakField').disabled = false;
    Field.activate('speakField');
    
    if (response.handle)
    {
      this.setHandleUI(response.handle, response.old_handle == null);
    }
  },
  
  hasFlash: function()
  {
    try
    {
      new ActiveXObject('ShockwaveFlash.ShockwaveFlash');
      return true;
    } 
    catch (e) 
    {
      var mt = navigator.mimeTypes['application/x-shockwave-flash'];
      return mt && mt.enabledPlugin;
    }
  },
  
  playSound: function()
  {
    try
    {
      if (this.sound && this.soundEnabled && !this.soundLoaded)
      {
        this.sound.loadSound(this.soundUrl, true);
        this.soundLoaded = true;
      }
      else if (this.sound && this.soundEnabled)
      {
        this.sound.stop();
        this.sound.start();
      }
      
      return true;
    }
    catch (e)
    {
      return false;
    }
  },
  
  enableSound: function(enable, play)
  {
    var soundToggle = $(this.soundControlId);
    var wasEnabled = this.soundEnabled;
    
    if (this.sound)
    {
      this.soundEnabled = enable;
    
      if (!enable)
      {
        soundToggle.className = 'off';
      }
      else
      {
        soundToggle.className = 'on';
        
        if (play) 
        { 
          if (!this.playSound())
          {
            this.enableSound(false, false);
          }
        }
      }
    }
    
    return this.soundEnabled;
  },
  
  toggleSound: function()
  {
    if (!this.hasFlash() && this.soundUrl)
    {
      try
      {
        this.sound = new Sound();
        this.soundLoaded = false;
      }
      catch (e)
      {
        this.sound = null;
        this.soundEnabled = false;
      }
    }

    var enabled = this.enableSound(!this.soundEnabled, true);
    this.chatSystem.setsound(enabled);
  },
  
  isScrolledToBottom: function()
  {
    var scrollOffset, windowHeight, pageHeight;

    if (this.IE7)
    {
      scrollOffset = document.documentElement.scrollTop;
      windowHeight = document.documentElement.offsetHeight;
      pageHeight = document.body.clientHeight;
    }
    else if (this.IE)
    {
      scrollOffset = this.scrollElement.scrollTop;
      windowHeight = this.scrollElement.clientHeight;
      pageHeight = this.scrollElement.scrollHeight;
    }
    else
    {
      scrollOffset = Math.max(document.documentElement.scrollTop, document.body.scrollTop);
      windowHeight = (window.innerHeight || document.body.clientHeight);
      pageHeight = Math.max(document.documentElement.offsetHeight, document.body.scrollHeight);
    }
    
    return (scrollOffset + windowHeight >= (pageHeight - 10));
  },
  
  onBlur: function(event)
  {
    this.blurred = true;
  },
  
  onFocus: function(event)
  {
    this.blurred = false;

    if (this.isScrolledToBottom())
    {
      this.clearDocumentTitle();
    }
  },
  
  onResize: function(event)
  {
    if (!this.IE7 || this.lastOffsetHeight != document.documentElement.offsetHeight)
    {
      if (this.IE7)
      {
        this.lastOffsetHeight = document.documentElement.offsetHeight;
      }

      this.scrollToBottom();
    }
  },
  
  onScroll: function(event)
  {
    if (this.isScrolledToBottom())
    {
      this.scrollToBottom();
      this.pruneMessages();
    }
  },
  
  sanitize: function(txt)
  {
    return txt.replace(/&/g, "&amp;").replace(/>/g, "&gt;").replace(/</g, "&lt;");
  },
  
  replacerize: function(txt)
  {
    return txt.replace(/\$/g, "$$$$");
  },
  
  pruneMessages: function()
  {
    if (this.messageListLimit)
    {
      var container = $('messages');
      var items = $A(container.getElementsByTagName('li'));
      
      var i = 1;
      while (items.length - i > this.messageListLimit)
      {
        var thisItem = items[i];

        if (Element.hasClassName(thisItem, 'handle'))
        {
          container.removeChild(thisItem);
          container.removeChild(items[i + 1]);
          container.removeChild(items[i + 2]);
          i += 3;
        }
        else if (Element.hasClassName(thisItem, 'message'))
        {
          container.removeChild(thisItem);
          container.removeChild(items[i + 1]);
          i += 2;
        }
        else if (Element.hasClassName(thisItem, 'timemark'))
        {
          container.removeChild(thisItem);
          i++;
        }
        else
        {
          i++;
        }
      }
    }
  },
  
  showFooter: function(fieldToFocus)
  {
    if (!$('chatFooterWrapper').visible()) {
      Effect.BlindDown($('chatFooterWrapper'), {
        duration: 0.4,
        afterFinish: function() { this.scrollToBottom(); Field.focus(fieldToFocus); }.bind(this)
      });
    }
  }
}

Profile = Class.create();
Profile.prototype = {
  initialize: function(options)
  {
    this.options = options;
    this.url = this.options.url;
    this.clientId = '';
    this.wrapper = $('profile');
    this.innards = $('profileDetails');
  },
  
  onKeyPress: function(event) 
  {
    if (event.keyCode == Event.KEY_ESC)
    {
      this.hide();
    }
  },
  
  updateAndToggle: function(clientId, msgId, handle)
  {
    if (Element.visible(this.wrapper))
    {
      if (this.clientId != clientId)
      {
        Effect.toggle(this.wrapper, 'appear', {
          duration: 0.2,
          from: 0.95,
          afterFinish: function() { chatroom.profile.updateAndShow(clientId, msgId, handle) } });
      }
      else
      {
        this.hide();
      }
    }
    else
    {
      this.updateAndShow(clientId, msgId, handle);
    }
  },
  
  updateAndShow: function(clientId, msgId, handle)
  {
    var parameters = 'room_id=' + chatroom.roomId + '&client_id=' + clientId + '&my_client_id=' + chatroom.clientId;
    
    if (msgId && msgId.length > 0)
    {
      parameters += '&msg_id=' + msgId;
    }
    
    new Ajax.Updater(this.innards, this.url, {
      parameters: 'room_id=' + chatroom.roomId + '&client_id=' + clientId + '&my_client_id=' + chatroom.clientId + '&msg_id=' + msgId,
      onComplete: function(transport)
      {
        if (transport.status >= 200 && transport.status < 300)
        {
          chatroom.profile.clientId = clientId;
        
          Effect.Appear(chatroom.profile.wrapper, {
            duration: 0.2,
            to: 0.95,
            afterFinish: function()
            {
              if ($('profilePMText') != null)
              {
                Field.activate('profilePMText');
                chatroom.buttonSync('profilePMSubmit', 'profilePMText');
              }
              else
              {
                $('hideProfile').focus();
              }
            }
          });
        }
      }
    });
  },
  
  hide: function()
  {
    Effect.Fade(this.wrapper, {
      duration: 0.2,
      from: 0.95,
      beforeStart: activateSpeakFieldOrInitialHandle
    });
  },
  
  onSubmit: function()
  {
    chatroom.pm('profilePMText', 'profilePMTargetClientId', 'profilePMTargetHandle', 'profilePMTargetImage', 'profilePMSubmit'); 
    return false;
  }
}

function showExtendedRoomDescription()
{
  $('descriptionExtender').hide();
  $('extendedDescription').show();
}

function hideExtendedRoomDescription()
{
  $('extendedDescription').hide();
  $('descriptionExtender').show();
}

function showExtendedRoomTagCloud()
{
  $('showExtendedRoomTagCloud').hide();
  $('extendedTagCloud').show();
}

function hideExtendedRoomTagCloud()
{
  $('extendedTagCloud').hide();
  $('showExtendedRoomTagCloud').show();
}

function activateSpeakFieldOrInitialHandle()
{
  Field.activate(Element.hasClassName('chatFooterWrapper', 'hasNoHandle') ? 'initialHandle' : 'speakField');
}