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

var emptyFunction = function() {};

String.prototype.blank = function() {
  return this.length == 0 || this.match(/^\s*$/);
};

// Add ISO8601 functions to Date
//
Date.prototype.setISO8601 = function (string) {
  	var regexp = "([0-9]{4})(-([0-9]{2})(-([0-9]{2})" +
      	"(T([0-9]{2}):([0-9]{2})(:([0-9]{2})(\.([0-9]+))?)?" +
      	"(Z|(([-+])([0-9]{2}):([0-9]{2})))?)?)?)?";
  	var d = string.match(new RegExp(regexp));

  	var offset = 0;
  	var date = new Date(d[1], 0, 1);

  	if (d[3]) { date.setMonth(d[3] - 1); }
  	if (d[5]) { date.setDate(d[5]); }
  	if (d[7]) { date.setHours(d[7]); }
  	if (d[8]) { date.setMinutes(d[8]); }
  	if (d[10]) { date.setSeconds(d[10]); }
  	if (d[12]) { date.setMilliseconds(Number("0." + d[12]) * 1000); }
  	if (d[14] && d[14] != 'Z') {
      	offset = (Number(d[16]) * 60) + Number(d[17]);
      	offset *= ((d[15] == '-') ? 1 : -1);
  	}

  	offset -= date.getTimezoneOffset();
  	time = (Number(date) + (offset * 60 * 1000));
  	this.setTime(Number(time));
};

Date.prototype.toISO8601String = function (format, offset) {
  	/* accepted values for the format [1-6]:
   	1 Year:
     	  YYYY (eg 1997)
      2 Year and month:
        YYYY-MM (eg 1997-07)
      3 Complete date:
        YYYY-MM-DD (eg 1997-07-16)
      4 Complete date plus hours and minutes:
        YYYY-MM-DDThh:mmTZD (eg 1997-07-16T19:20+01:00)
      5 Complete date plus hours, minutes and seconds:
        YYYY-MM-DDThh:mm:ssTZD (eg 1997-07-16T19:20:30+01:00)
      6 Complete date plus hours, minutes, seconds and a decimal
        fraction of a second
        YYYY-MM-DDThh:mm:ss.sTZD (eg 1997-07-16T19:20:30.45+01:00)
  	*/
  	if (!format) { var format = 6; }
  	if (!offset) {
      	var offset = 'Z';
      	var date = this;
  	} else {
      	var d = offset.match(/([-+])([0-9]{2}):([0-9]{2})/);
      	var offsetnum = (Number(d[2]) * 60) + Number(d[3]);
      	offsetnum *= ((d[1] == '-') ? -1 : 1);
      	var date = new Date(Number(Number(this) + (offsetnum * 60000)));
  	}

  	var zeropad = function (num) { return ((num < 10) ? '0' : '') + num; };

  	var str = "";
  	str += date.getUTCFullYear();
  	if (format > 1) { str += "-" + zeropad(date.getUTCMonth() + 1); }
  	if (format > 2) { str += "-" + zeropad(date.getUTCDate()); }
  	if (format > 3) {
      	str += "T" + zeropad(date.getUTCHours()) +
             	":" + zeropad(date.getUTCMinutes());
  	}
  	if (format > 5) {
      	var secs = Number(date.getUTCSeconds() + "." +
                 	((date.getUTCMilliseconds() < 100) ? '0' : '') +
                 	zeropad(date.getUTCMilliseconds()));
      	str += ":" + zeropad(secs);
  	} else if (format > 4) { str += ":" + zeropad(date.getUTCSeconds()); }

  	if (format > 3) { str += offset; }
  	return str;
};

function toggleDetails(container)
{
  var details = document.getElementsByClassName('details', $(container))[0];
  if (Element.visible(details))
  {
    $(container).removeClassName('detailed');
    Effect.toggle(details, 'blind', { duration: 0.2 });
  } else {
    $(container).addClassName('detailed');
    Effect.toggle(details, 'blind', { duration: 0.2 });
  }
}

function toggleFavorite(room_id)
{
  new Ajax.Request('/account/toggle_favorite/' + room_id);
}

function toggleRadar(room_id)
{
  new Ajax.Request('/account/toggle_radar/' + room_id);
}

function toggleLoginDialog()
{
  if (Element.visible('loginDialog'))
  {
    Element.removeClassName('signIn', 'active');
    Effect.toggle('shade', 'appear', { from: 0.5, to: 0, duration: 0.1 });
    Effect.toggle('loginDialog', 'appear', { duration: 0.2 });
  }
  else
  {
    Element.addClassName('signIn', 'active');
    Effect.toggle('shade', 'appear', { from: 0, to: 0.5, duration: 0.1 });
    Effect.toggle('loginDialog', 'appear', { duration: 0.2, afterFinish: function() { Field.activate('login_dialog_email'); } });
  }
}

function loginDialogKeyHandler(e)
{
  if (e.keyCode == Event.KEY_ESC) { toggleLoginDialog(); }
	return false;
}

StoppablePeriodicalExecuter = Class.create();
Object.extend(Object.extend(StoppablePeriodicalExecuter.prototype, PeriodicalExecuter.prototype), 
 {
  initialize: function(callback, frequency) 
  {
    this.callback = callback;
    this.frequency = frequency;
    this.currentlyExecuting = false;
    this.timer = null;
    this.start();
  },

  start: function() 
  {
    if (this.timer == null)
    {
      this.timer = setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);
    }
  },

  stop: function() 
  {
    clearInterval(this.timer);
    this.timer = null;
  }
});

function calendarLoading(loading)
{
}

function replaceWithObjectTag(id, objectClass, data, wmode)
{
  var str = "<object class='" + objectClass + "' type='application/x-shockwave-flash' data='" + data + 
    "'><param name='movie' value='" + data + "'/><param name='wmode' value='" + wmode + "'/></object>";
    
  Element.replace(id, str);
}

AjaxStatusChecker = Class.create();
AjaxStatusChecker.prototype = {
  initialize: function(element, url, options)
  {
    this.element = $(element);
    this.url = url;
    this.options = options || {};
    this.options.frequency = this.options.frequency || 0.3;
    
    this.observer = null;
    Event.observe(this.element, "keyup", this.onKeyUp.bindAsEventListener(this));
  },
  
  onKeyUp: function(event) 
  {
    if (this.observer) 
    {
      clearTimeout(this.observer);
    }
    
    // Safari doesn't fire key events while in the input method mode, and only fire KEY_RETURN at exit.
    if (event.keyCode != Event.KEY_RETURN || (/Safari/).test(navigator.userAgent))
  	{
      this.observer = setTimeout(this.onObserverEvent.bind(this), this.options.frequency * 1000);
    }
  },
  
  onObserverEvent: function() 
  {
    var params = encodeURIComponent('value') + '=' + encodeURIComponent($F(this.element));
    new Ajax.Request(this.url, { "parameters" : params});
  }
};

function showChangeImage()
{
  $('showChangeImage').hide();
  Effect.BlindDown('changeImage', {
    duration: 0.2,
    afterFinish: function() { Field.activate('imageFile'); }
  });
}

function showProgressIndicator(element)
{
    Element.addClassName(element, 'inProgress');
}


function removeFavorite(roomName, roomId, listId)
{
  if (confirm('Do you really want to remove "' + roomName + '" from your favorites?'))
  {
    new Ajax.Request('/account/toggle_favorite/' + roomId,
      { onSuccess: new Effect.toggle(listId, 'appear') }
    );
  }
}

function removeRadar(roomName, roomId, listId)
{
  if (confirm('Do you really want to stop monitoring "' + roomName + '"?'))
  {
    new Ajax.Request('/account/toggle_radar/' + roomId,
      { onSuccess: new Effect.toggle(listId, 'appear') }
    );
  }
}

function showPaste(pasteLink)
{
  Element.addClassName(pasteLink.parentNode.parentNode, 'raw');
}

function showMessageHighlight(permalink)
{
  Element.addClassName(permalink.parentNode, 'highlight');
}

function hideMessageHighlight(permalink)
{
  Element.removeClassName(permalink.parentNode, 'highlight');
}

function showPara(message)
{
  var permalink = $('permalink-' + message.id);
  
  if (Element.empty(permalink))
  {
    permalink.innerHTML = '&para;';
  }
}

function hidePara(message)
{
  var permalink = $('permalink-' + message.id);
  
  if (!Element.empty(permalink))
  {
    permalink.innerHTML = '';
    Element.removeClassName(message, 'highlight');
  }
}

function prepPermalink(message)
{
  message.onmouseover = function() { showPara(this); };
  message.onmouseout = function() { hidePara(this); };
}

function hidePermalinking(permalinking) {
  var message = permalinking.parentNode;
  Effect.BlindUp(permalinking, { duration: 0.2, afterFinish: function() {
    message.removeClassName('stickyHighlight');
    prepPermalink(message);
    permalinking.remove();      
  } });
}

function togglePermalink(element)
{
  var msgId = element.parentNode.id;
  
  if (msgId.match(/pending/)) {
    // Still not committed
    return false;
  }
  
  var message = $(msgId);
  var permalinking = $('permalinking-' + msgId);

  if (permalinking) {
    hidePermalinking(permalinking);
  }
  else
  {
    // Close first if one is expanded elsewhere
    var e = document.getElementsByClassName('permalinking', 'messages')[0];
    if (e) {
      hidePermalinking(e);
      hidePara(e.parentNode);
      prepPermalink(e.parentNode);
    }
    
    var permalink = document.getElementsByClassName('permalink', message)[0].href;
    
    permalinking = $(document.createElement('div'));
    permalinking.hide();
    permalinking.addClassName('permalinking');
    permalinking.id = 'permalinking-' + msgId;
    permalinking.innerHTML = $('permalinkTemplate').innerHTML.replace(/%%permalink%%/g, permalink).replace(/%%msgid%%/g, msgId);
    message.appendChild(permalinking);
    var permalink_text = document.getElementsByClassName('permalinkUrl', message)[0];
    permalink_text.value = permalink;
    
    message.addClassName('stickyHighlight');
    message.onmouseover = '';
    message.onmouseout = '';
    permalink.innerHTML = '&para;';
    
    Effect.BlindDown(permalinking, { duration: 0.2, afterFinish: function() {
      Field.activate(permalink_text);
    } });
  }
}

function troppus()
{
  var a = document.createElement("a");
  var b = "troppus".match(/./g).reverse().join("")+String.fromCharCode(0x40)+
    "rgnil".match(/./g).reverse().join("")+String.fromCharCode(46)+
    "moc".match(/./g).reverse().join("");
  a.href = ":otliam".match(/./g).reverse().join("")+b;
  a.appendChild(document.createTextNode(b));
  $('troppus').appendChild(a);
}

function toggleMoreResults(moreContainerId, link)
{
  Effect.toggle(moreContainerId, 'blind', { from: 0, to: 0.5, duration: 0.1 });
  
  parentContainer = $(moreContainerId).parentNode;
  if (Element.hasClassName(parentContainer, 'more'))
  {
    Element.removeClassName(parentContainer, 'more');
  }
  else
  {
    Element.addClassName(parentContainer, 'more');
  }
  
  var text = link.innerHTML;
  link.innerHTML = link.rel;
  link.rel = text;
}

function imageLoaded(element)
{
  if ( element.width > 400 ) { Element.addClassName(element, 'shrink'); }
  if (typeof chatroom != 'undefined' && chatroom.isScrolledToBottom())
  {
    chatroom.scrollToBottom();
  }
}

function extractId(s) {
  return s.slice(s.lastIndexOf('-') + 1);
}

function deleteMessage(msgId, roomId) {
  if (confirm('Do you really want to delete this message?')) {
    new Ajax.Request('/room/' + roomId + '/delete_message/' + msgId,
      { onSuccess: new Effect.BlindUp($(msgId), { duration: 0.2 }) }
    );
  }
}