// === Get/Hide/Show/Toggle ===

function ge()
{
  var ea;
  for( var i = 0; i < arguments.length; i++ ) {
    var e = arguments[i];
    if( typeof e == 'string' )
      e = document.getElementById(e);
    if( arguments.length == 1 )
      return e;
    if( !ea )
      ea = new Array();
    ea[ea.length] = e;
  }
  return ea;
}

function show()
{
  for( var i = 0; i < arguments.length; i++ ) {
    var element = ge(arguments[i]);
    if (element && element.style) element.style.display = '';
  }
  return false;
}

function hide()
{
  for( var i = 0; i < arguments.length; i++ ) {
    var element = ge(arguments[i]);
    if (element && element.style) element.style.display = 'none';
  }
  return false;
}

function shown(el) {
    el = ge(el);
    return (el.style.display != 'none');
}

function toggle()
{
  for( var i = 0; i < arguments.length; i++ ) {
    var element = ge(arguments[i]);
    element.style.display = (element.style.display == 'block') ? 'none' : 'block';
  }
  return false;
}

function remove_node(node)
{
  if (node.removeNode)
    node.removeNode(true);
  else {
    for (var i=node.childNodes.length-1; i>=0; i--)
      remove_node(node.childNodes[i]);
      node.parentNode.removeChild(node);
    }
  return null;
}

// === Event Info Access ===

function mouseX(event)
{
  return event.pageX || (event.clientX +
    (document.documentElement.scrollLeft || document.body.scrollLeft));
}

function mouseY(event)
{
  return event.pageY || (event.clientY +
    (document.documentElement.scrollTop || document.body.scrollTop));
}

function pageScrollX()
{
  return document.body.scrollLeft || document.documentElement.scrollLeft;
}

function pageScrollY()
{
  return document.body.scrollTop || document.documentElement.scrollTop;
}

function elementX(obj)
{
  var curleft = 0;
  if (obj.offsetParent) {
    while (obj.offsetParent) {
      curleft += obj.offsetLeft;
      obj = obj.offsetParent;
    }
  }
  else if (obj.x)
    curleft += obj.x;
  return curleft;
}

function elementY(obj)
{
  var curtop = 0;
  if(obj.offsetParent) {
    while (obj.offsetParent) {
      curtop += obj.offsetTop;
      obj = obj.offsetParent;
    }
  }
  else if (obj.y)
    curtop += obj.y;
  return curtop;
}

// === Onload Registry ===

function onloadRegister(handler) {
  if (window.onload) {
    var old=window.onload;
    window.onload=function() { old(); handler(); };
  }
  else {
    window.onload=handler;
  }
}

// === Placeholder Text ===

function placeholderSetup(id) {
	var el = ge(id);
	if(!el) return;
	/*if(el.type != 'text') return;*/
	
	var ph = el.getAttribute("placeholder");
	if( ph && ph != "" ) {
		el.value = ph;
		el.style.color = '#777';
		el.is_focused = 0;
		el.onfocus = placeholderFocus;
		el.onblur = placeholderBlur;
	}
}

function placeholderFocus() {
  if(!this.is_focused) {
    this.is_focused = 1;
    this.value = '';
    this.style.color = '#000';

    var rs = this.getAttribute("radioselect");
    if( rs && rs != "" ) {
      var re = document.getElementById(rs);
      if(!re) { return; }
      if(re.type != 'radio') return;

      re.checked=true;
    }
  }
}

function placeholderBlur() {
  var ph = this.getAttribute("placeholder")
  if( this.is_focused && ph && this.value == "" ) {
		this.is_focused = 0;
    this.value = ph;
    this.style.color = '#777';
  }
}

// === String Utilities ===

function htmlspecialchars(text) {
  return text ? text.toString().replace(/&/g, '&amp;').replace(/"/g, '&quot;').replace(/'/g, '&#039;').replace(/</g, '&lt;').replace(/>/g, '&gt;') : '';
}

function escape_js_quotes(text) {
  if (!text) {
    return;
  }

  return text.replace(/\\/g, '\\\\').replace(/\n/g, '\\n').replace(/\r/g, '\\r').replace(/"/g, '\\x22').replace(/'/g, '\\\'').replace(/</g, '\\x3c').replace(/>/g, '\\x3e').replace(/&/g, '\\x26');
}

function trim(str) {
  var delim = arguments.length > 1 ? arguments[1] : ' ';
  for (var i=0, c=str.length-delim.length; i<=c; i+=delim.length) {
    if (str.substring(i, i + delim.length) != delim) {
      break;
    }
  }

  for (var j=str.length, c=Math.max(i, delim.length - 1); j>c; j-=delim.length) {
    if (str.substring(j - delim.length, j) != delim) {
      break;
    }
  }

  return str.substring(i, j);
}

// === URI Handling ===

function escapeURI(u)
{
    if(encodeURIComponent) {
        return encodeURIComponent(u);
    }
    if(escape) {
        return escape(u);
    }
}

function goURI(href) {
  window.location.href = href;
}

function is_email(email) {
  return /^[\w!.%+]+@[\w]+(?:\.[\w]+)+$/.test(email);
}

//13th parallel
function getViewportWidth() {
  var width = 0;
  if( document.documentElement && document.documentElement.clientWidth ) {
    width = document.documentElement.clientWidth;
  }
  else if( document.body && document.body.clientWidth ) {
    width = document.body.clientWidth;
  }
  else if( window.innerWidth ) {
    width = window.innerWidth - 18;
  }
  return width;
};

function getViewportHeight() {
  var height = 0;
  if( document.documentElement && document.documentElement.clientHeight ) {
    height = document.documentElement.clientHeight;
  }
  else if( document.body && document.body.clientHeight ) {
    height = document.body.clientHeight;
  }
  else if( window.innerHeight ) {
    height = window.innerHeight - 18;
  }
  return height;
};

// === Deprecated ===
// --- Delete checkAgree when user profile picture editing moves to picture widget

function checkAgree() {
  if (document.frm.pic.value) {
    if (document.frm.agree.checked) {
      document.frm.submit();
    } else {
      show("error");
    }
  }
}

function isIE() {
 return (navigator.userAgent.toLowerCase().indexOf("msie") != -1);
}   
    
function getTableRowShownDisplayProperty() {
  if (isIE()) {
    return  'inline';
  } else {
    return 'table-row';
  }
}
  
function showTableRow()
{ 
  for( var i = 0; i < arguments.length; i++ ) {
    var element = ge(arguments[i]);
    if (element && element.style) element.style.display =
        getTableRowShownDisplayProperty();
  }
  return false;
} 
  
function getParentRow(el) {
    el = ge(el);
    while (el.tagName && el.tagName != "TR") {
        el = el.parentNode;
    }
    return el;
} 

function stopPropagation(e) {
    if (!e) var e = window.event;
    e.cancelBubble = true;
    if (e.stopPropagation) {
        e.stopPropagation();
    }
}

function show_standard_status(status) {
  s = ge('standard_status');
  if (s) {
    var header = s.firstChild;
    header.innerHTML = status;
    show('standard_status');
  }
}

function hide_standard_status() {
  s = ge('standard_status');
  if (s) {
    hide('standard_status');
  }
}

function remove_node(node) {
  if (node.removeNode)
    node.removeNode(true);
  else {
    for (var i=node.childNodes.length-1; i>=0; i--)
      remove_node(node.childNodes[i]);
    node.parentNode.removeChild(node);
  }
  return null;
}

function adjustImage(obj, stop_word, max) {
  
  var pn=obj.parentNode;

  if (stop_word==null)
    stop_word='note_content';
  if (max==null) {
    while (pn.className.indexOf(stop_word)==-1)
      pn=pn.parentNode;
    if (pn.offsetWidth)
      max=pn.offsetWidth;
    else
      max=400;
  }

  obj.className=obj.className.replace('img_loading', 'img_ready');

  if (obj.width>max) {
    if (window.ActiveXObject) {
      try {
        var img_div=document.createElement('div');
        img_div.style.filter='progid:DXImageTransform.Microsoft.AlphaImageLoader(src="' + obj.src.replace('"', '%22') + '", sizingMethod="scale")';
        img_div.style.width=max+'px';
        img_div.style.height=((max/obj.width)*obj.height)+'px';
        if (obj.parentNode.tagName=='A')
          img_div.style.cursor='pointer';
        obj.parentNode.insertBefore(img_div, obj);
        obj.removeNode(true);
      }
      catch (e) {
        obj.style.width=max+'px';
      }
    }
    else
      obj.style.width=max+'px';
  }
}

function set_opacity(obj, opacity) {
  try {
    obj.style.opacity=(opacity==1?'':opacity);
    obj.style.filter=(opacity==1?'':'alpha(opacity='+opacity*100+')');
  }
  catch (e) {}
  //obj.setAttribute('opacity', opacity); // for future reference
}

function get_opacity(obj) {
  return obj.opacity ? obj.opacity : 1;
}

function focus_login() {
  var email = ge("email");
  var pass = ge("pass");
  var dologin = ge("doquicklogin");
  if (email && pass) {
    if (email.value != "" && pass.value == "") {
      pass.focus();
    } else if (email.value == "") {
      email.focus();
    } else if (email.value != "" && pass.value != "") {
      dologin.focus();
    }
  }
}

function array_indexOf(arr, val, index) {
  if (!index) {
    index=0;
  }
  for (var i=index; i<arr.length; i++) {
    if (arr[i] == val) {
      return i;
    }
  }
  return -1;
}

//
// OOP implementation
function __super_class(obj) {
  this.__super=obj;
  this.__parent=obj.prototype.parent;
}
__super_class.prototype.__super_method=function(method, pointer) {
  var __pointer=pointer;
  this[method]=function() {
    var __parent=this.__context.parent;
    this.__context.__parents.push(__parent);
    this.__context.parent=__parent ? __parent.parent : null;
    var __ret=__pointer.apply(this.__context, arguments);
    this.__context.parent=__parent;
    this.__context.__parents.pop();
    __parent=null;
    return __ret;
  };
}
__super_class.prototype.__overridden_method=function(method, pointer) {
  var __pointer=pointer;
  return function() {
    if ((typeof this.__parents=='undefined') || !this.__parents.length) {
      return __pointer.apply(this, arguments);
    }
    else {
      var __parent=this.parent;
      this.parent=this.__parents[0];
      var __ret=__pointer.apply(this, arguments);
      this.parent=__parent;
      __parent=null;
      return __ret;
    }
  }
}
__super_class.prototype.construct=function(context) {
  this.__context=context;
  this.__context.__parents=[];
  if (typeof this.__context.__prototype.__overridden=='undefined') {
    this.__context.__prototype.__overridden=true;
    for (var i in this.__context.__prototype) {
      if ((typeof this.__context.__prototype[i]=='function') && this.__context.__prototype[i]!=this.__super.prototype[i]) {
        this.__context.__prototype[i]=this.__overridden_method(i, this.__context.__prototype[i]);
      }
    }
  }
  var a=new Array();
  for (var i=1; i<arguments.length; i++) {
    a.push(arguments[i]);
  }
  this.__context.parent=this.__parent;
  var __ret=this.__super.apply(context, a);
  this.__context.parent=this;
  return __ret;
}
Function.prototype.bind=function(context) {
  var __method=this;
  var __context=context;
  return function() {
    return __method.apply(context, arguments);
  }
}
Function.prototype.extend=function(obj) {
  this.prototype.parent=new __super_class(obj);
  this.prototype.__prototype=this.prototype;
  for (var i in obj.prototype) {
    if (typeof obj.prototype[i]=='function') {
      this.prototype[i]=obj.prototype[i];
      this.prototype.parent.__super_method(i, obj.prototype[i]);
    }
    else if (i!='parent') {
      this.prototype[i]=obj.prototype[i];
    }
  }
}

function dp(object)
{
  var descString = "";
  for(var value in object)
    descString += (value + " => " + object[value] + "\n");
  if( descString != "" )
    alert(descString);
  else
    alert(object);
}

//
// generic dialog class, does very little on its own
function generic_dialog(className) {
  this.className=className;
  this.content=null;
  this.obj=null;
  this.popup=null;
  this.iframe=null;
  this.hidden_objects=new Array();
}
generic_dialog.prototype.should_hide_objects=navigator.userAgent.indexOf('Mac OS X')!=-1;

// sets the content with raw html
generic_dialog.prototype.set_content=function(html) {
  this.content.innerHTML=html;

  // if we need to hide objects behind this, we need to check back after images are loaded
  if (generic_dialog.prototype.should_hide_objects) {
    var imgs=this.content.getElementsByTagName('img');
    for (var i=0; i<imgs.length; i++) {
      imgs[i].onload=imgs[i].onload ? function() {
                                        this.img.onload();
                                        this.dialog.hide_objects()
                                      }.bind({img:imgs[i],dialog:this})
                                    : this.hide_objects.bind(this);
    }
  }
}

// shows a dialog with raw html
generic_dialog.prototype.show_dialog=function(html) {
  if (!this.obj) {
    this.build_dialog();
  }
  this.set_content(html);
  this.show();
}

// shows a pop dialog with an ajax request and uses that innerHTML
generic_dialog.prototype.show_ajax_dialog=function(src) {
  this.show_dialog('<div class="dialog_loading">Loading...</div>');
  var myself=this;
  var ajax=new Ajax(
    function(obj, text) {
      myself.show_dialog(text);
    });
  ajax.get(src);
}

// shows a dialog with the given title and body content
generic_dialog.prototype.show_prompt=function(title, content) {
  this.show_dialog('<h2 id="dialogtitle"><span>' + title + '</span></h2><div class="dialog_content">' + content + '</div>');
}

// shows a message with a title, text, and button to continue
generic_dialog.prototype.show_message=function(title, content, button/* = 'Ok' */) {
  if (button==null) {
    button='OK';
  }
  this.show_choice(title, content, button, function(){generic_dialog.get_dialog(this).fade_out(100)});
}

// shows a message with one or two buttons that do some javascript
generic_dialog.prototype.show_choice=function(title, content, button1, button1js, button2, button2js) {
 
  var buttons='<div class="dialog_buttons"><input class="inputsubmit" type="button" value="' + button1 + '" />';
  if (button2) {
    buttons+='<input class="inputsubmit" type="button" value="' + button2 + '" />';
  }
  this.show_prompt(title, this.content_to_markup(content) + buttons);
  
  // Register objects
  var inputs=this.obj.getElementsByTagName('input'); 
  if (button2) {
    button1obj=inputs[inputs.length-2];
    button2obj=inputs[inputs.length-1];
  } else {
    button1obj=inputs[inputs.length-1];
  }
 
  // Assign JS to buttons if necessary
  if (button1js) {
    if (typeof button1js == 'string') {
      eval('button1js = function(){' + button1js + '}');
    }
    button1obj.onclick=button1js;
  }
  if (button2js) {
    if (typeof button2js == 'string') {
      eval('button2js = function(){' + button2js + '}');
    }
    button2obj.onclick=button2js;
  }

  /**
   * Enter clicks the first button. Escape clicks the second one if it exists 
   * (usually cancel), or else clicks the first button.
   */
   document.onkeyup = function(e) {
     var keycode = (e && e.which) ? e.which : event.keyCode;
     var btn2_exists = (typeof button2obj != 'undefined');
     var is_webkit = (navigator.userAgent.indexOf('WebKit') > 0);
     
     if (is_webkit && keycode == 13) {
       // WebKit/Safari doesn't support enter-clicking on the focused item.
       button1obj.click();
     }
     
     // Escape clicks the first button if it's the only button.
     if (keycode == 27) {
       if (btn2_exists) {
         button2obj.click();
       } else {
         button1obj.click();
       } 
     } 
     // Clear the onkeyup from these shackles.
     document.onkeyup = function(){}
   }
   // This should make enter work (except in Safari). If we always captured the 
   // keycode too, it'd post twice in Firefox.
   button1obj.focus();
}

generic_dialog.prototype.setBackground=function(show) {
	switch(show)
	{
		case 'help'   : document.getElementById('dialogtitle').style.background = "url('/images/schedule_help_head.gif')"; break;
		case 'profile': document.getElementById('dialogtitle').style.background = "url('/images/profile_head.gif')"; break;
	}
}

// shows a form that will cause a post
generic_dialog.prototype.show_form=function(title, content, button, target) {
  content='<form action="' + target + '" method="post">' + this.content_to_markup(content);
  var post_form_id=ge('post_form_id');
  if (post_form_id) {
    content+='<input type="hidden" name="post_form_id" value="' + post_form_id.value + '" />';
  }
  content+='<div class="dialog_buttons"><input class="inputsubmit" name="confirm" type="submit" value="' + button + '" />';
  content+='<input type="hidden" name="next" value="'+htmlspecialchars(document.location)+'"/>';
  content+='<input class="inputsubmit" type="button" value="Cancel" onclick="generic_dialog.get_dialog(this).fade_out(100)" /></form>';
  this.show_prompt(title, content);
  return false;
}

generic_dialog.prototype.content_to_markup=function(content) {
  return (typeof content == 'string') ? 
         '<div class="dialog_body">' + content + '</div>' : 
         '<div class="dialog_summary">'+ content.summary +'</div><div class="dialog_body">'+ content.body +'</div>';
}

// hides the dialog
generic_dialog.prototype.hide=function() {
  if (this.obj) {
    this.obj.style.display='none';
  }

  // unhide hidden objects
  if (this.hidden_objects.length) {
    for (var i in this.hidden_objects) {
      this.hidden_objects[i].style.visibility='';
    }
    this.hidden_objects=new Array();
  }
}

// fades the dialog out over X seconds
generic_dialog.prototype.anim_res=5;
generic_dialog.prototype.fade_out=function(interval, first_call) {
  if (!interval)
    interval=350;
  if (!first_call)
    first_call=(new Date).getTime()-this.anim_res;
  var fade=1.0-(((new Date).getTime()-first_call)/interval)*1.0;
  if (fade>0) {
    set_opacity(this.obj, fade);
    var myself=this;
    setTimeout(function(){myself.fade_out(interval, first_call)}, this.anim_res);
  }
  else {
    this.hide();
    set_opacity(this.obj, 1);
  }
}

// shows the dialog (if it's built already)
generic_dialog.prototype.show=function() {
  if (this.obj && this.obj.style.display) {
    this.obj.style.visibility='hidden';
    this.obj.style.display='';
    this.reset_dialog();
    this.obj.style.visibility='';
    this.obj.dialog=this; // for onclick events, etc
  }
  else {
    this.reset_dialog();
  }
  this.hide_objects();
}

generic_dialog.prototype.hide_objects=function() {
  if (!this.should_hide_objects) { return; }

  var rect={x:elementX(this.content), y:elementY(this.content), w:this.content.offsetWidth, h:this.content.offsetHeight};
  var objects=new Array();
  var iframes=document.getElementsByTagName('iframe');
  for (var i=0; i<iframes.length; i++) {
    if (iframes[i].className.indexOf('share_hide_on_dialog')!=-1) {
      objects.push(iframes[i]);
    }
  }
  var swfs=document.getElementsByTagName('embed');
  for (var i=0; i<swfs.length; i++) {
    objects.push(swfs[i]);
  }
  for (var i=0; i<objects.length; i++) {
    var pn=false;
    var node = objects[i].offsetHeight ? objects[i] : objects[i].parentNode;
    swf_rect={x:elementX(node), y:elementY(node), w:node.offsetWidth, h:node.offsetHeight};
    if (rect.y + rect.h > swf_rect.y &&
        swf_rect.y + swf_rect.h > rect.y &&
        rect.x + rect.w > swf_rect.x &&
        swf_rect.x + swf_rect.w > rect.w &&
        array_indexOf(this.hidden_objects, node) == -1) {
          this.hidden_objects.push(node);
          node.style.visibility='hidden';
          node.style.visibility='hidden';
    }
  }
}

// builds a dialog base
generic_dialog.prototype.build_dialog=function() {
  // build a holder
  if (!this.obj && !(this.obj=ge('generic_dialog'))) {
    this.obj=document.createElement('div');
    this.obj.id='generic_dialog';
  }
  this.obj.className='generic_dialog' + (this.className ? ' ' + this.className : '');
  this.obj.style.display='none';
  document.body.appendChild(this.obj);

  // build an iframe to block out select boxes
  if (!this.iframe && !(this.iframe=ge('generic_dialog_iframe'))) {
    this.iframe=document.createElement('iframe');
    this.iframe.id='generic_dialog_iframe';
  }
  this.iframe.frameBorder='0';
  this.obj.appendChild(this.iframe);
 
  // build a div to hold the content
  if (!this.popup && !(this.popup=ge('generic_dialog_popup'))) {
    this.popup=document.createElement('div');
    this.popup.id='generic_dialog_popup';
  }
  this.obj.appendChild(this.popup);
}

// repositions the elements to be where they should be
generic_dialog.prototype.reset_dialog=function() {
  if (!this.popup || !this.iframe)
    return;
  this.reset_dialog_obj();
  this.iframe.style.width=this.popup.offsetWidth+'px';
  this.iframe.style.height=this.popup.offsetHeight+'px';
}

// does nothing
generic_dialog.prototype.reset_dialog_obj=function() {}

// sets the width of the dialog. if w is false it will use the default
generic_dialog.prototype.set_width=function(w) {
  this.obj.style.width=w ? w+'px' : '';
}

// returns the dialog object in which obj is contained
/*static*/ generic_dialog.get_dialog=function(obj) {
  while (!obj.dialog && obj.parentNode) {
    obj=obj.parentNode;
  }
  return obj.dialog?obj.dialog:false;
}


//
// class for centered dialog with flat transparent borders
function pop_dialog(className) {
  this.parent.construct(this, className);
}
pop_dialog.extend(generic_dialog);

// builds a pop dialog -- uses tables, but compatible in all browsers
pop_dialog.prototype.build_dialog=function() {
  this.parent.build_dialog();

  this.obj.className+=' pop_dialog';
  this.popup.innerHTML='<table class="pop_dialog_table">'+
                       '<tr><td class="pop_topleft"></td><td class="pop_border"></td><td class="pop_topright"></td></tr>'+
                       '<tr><td class="pop_border"></td><td class="pop_content" id="pop_content"></td><td class="pop_border"></td></tr>'+
                       '<tr><td class="pop_bottomleft"></td><td class="pop_border"></td><td class="pop_bottomright"></td></tr>'+
                       '</table>';
  this.content=document.getElementById('pop_content');
}

// centers the dialog where it should be
pop_dialog.prototype.reset_dialog_obj=function() {
  this.obj.style.top=(document.documentElement.scrollTop?document.documentElement.scrollTop:document.body.scrollTop)+'px';
  this.obj.style.left=(document.body.offsetWidth-this.popup.offsetWidth)/2+'px';
}

//
// class for contextual dialogs pointing to what they reference. think: mini-feed
function contextual_dialog(className) {
  this.parent.construct(this, className);
}
contextual_dialog.extend(generic_dialog);

// sets the context for which this element will be used... i.e. what it's going to point to
contextual_dialog.prototype.set_context=function(obj) {
  this.context=obj;
}

// builds a contextual dialog
contextual_dialog.prototype.build_dialog=function() {
  this.parent.build_dialog();

  this.obj.className+=' contextual_dialog';
  this.popup.innerHTML='<div class="contextual_arrow"><span>^_^keke1</span></div><div class="contextual_dialog_content"></div>';
  this.content=this.popup.getElementsByTagName('div')[1];
}

// sets this dioalog near its context
contextual_dialog.prototype.reset_dialog_obj=function() {
  this.obj.style.top=(elementY(this.context)+7)+'px';
  this.obj.style.left=elementX(this.context)-this.obj.offsetWidth+12+'px';
}
