// === 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;
}

/* determines whether or not a base_obj is a descendent of the target_id obj */
function is_descendent(base_obj, target_id) {
  var target_obj = ge(target_id);
  if (base_obj == null) return;
  while (base_obj != target_obj) {
    if (base_obj.parentNode) {
      base_obj = base_obj.parentNode;
    } else {
      return false;
    }
  } 
  return true;
}



// === Event Info Access ===

var KEYS = { BACKSPACE: 8,
             TAB:       9,
             RETURN:   13,
             ESC:      27,             
             LEFT:     37,
             UP:       38,             
             RIGHT:    39,             
             DOWN:     40,
             DELETE:   46 };

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;
  }
}

// === Event Attaching ===
// (see: http://www.quirksmode.org/blog/archives/2005/10/_and_the_winner_1.html)

function addEventBase(obj, type, fn, name_hash)
{
	if (obj.addEventListener)
		obj.addEventListener( type, fn, false );
	else if (obj.attachEvent)
	{
                obj["e"+type+fn+name_hash] = fn;
		obj[type+fn+name_hash] = function() { obj["e"+type+fn+name_hash]( window.event ); }
		obj.attachEvent( "on"+type, obj[type+fn+name_hash] );
          
	}
}


// why name_hash? So you can use the same function and pass different name_hashes and ie won't get confused
function removeEventBase(obj, type, fn, name_hash)
{
	if (obj.removeEventListener)
		obj.removeEventListener( type, fn, false );
	else if (obj.detachEvent)
	{
		obj.detachEvent( "on"+type, obj[type+fn+name_hash] );
		obj[type+fn+name_hash] = null;
		obj["e"+type+fn+name_hash] = null;
	}
}


// === Placeholder Text ===





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';
  }
}

// === Dropdown Menus ===

/* functionality for an optional drop down menu (example: drop downs in the 
nav.) It consists of a link, an arrow, and a menu which appears when the
arrow is clicked. Pass this function an arrow, link, and menu element 
 
arrow_class and arrow_old_class is optional
*/
function isIE() {
 return (navigator.userAgent.toLowerCase().indexOf("msie") != -1);
}

function isSafari() {
 return (navigator.userAgent.indexOf("Safari") != -1);
}
    
function getTableRowShownDisplayProperty() {
  if (isIE()) {
    return  'inline';
  } else {
    return 'table-row';
  }
}
  
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;
}

//
// Useragent sniffer
var ua = {
  populate: function() {
    var agent = /(?:MSIE.(\d+\.\d+))|(?:Firefox.(\d+\.\d+))|(?:Opera.(\d+\.\d+))|(?:AppleWebKit.(\d+.\d+))/.exec(navigator.userAgent);
    if (!agent) {
      this._ie =
      this._firefox =
      this._opera =
      this._safari = 0;
    }
    this._ie = parseFloat(agent[1] ? agent[1] : 0);
    this._firefox = parseFloat(agent[2] ? agent[2] : 0);
    this._opera = parseFloat(agent[3] ? agent[3] : 0);
    this._safari = parseFloat(agent[4] ? agent[4] : 0);
    this.populated = true;
  },
  populated: false,

  ie: function() {
    if (!this.populated) this.populate();
    return this._ie;
  },

  firefox: function() {
    if (!this.populated) this.populate();
    return this._firefox;
  },

  opera: function() {
    if (!this.populated) this.populate();
    return this._opera;
  },

  safari: function() {
    if (!this.populated) this.populate();
    return this._safari;
  }
}

//
// OOP implementation
Function.prototype.extend = function(obj) {
  this.prototype.parent = new __super_class_factory(obj, this);
}
function __super_class_factory(superclass, subclass) {
  this.superclass = superclass;
  this.subclass = subclass;
  this.prototyped = false;
  subclass.__parent = this;
  this.parent = superclass.__parent ? superclass.__parent : false;
}
__super_class_factory.prototype.construct = function(instance) {

  // create pointers to the subclass parent-inherited functions
  var superclass_prototype = this.superclass.prototype;
  this.extend_prototype();

  // link this instance to the parent and to itself. note: this is a circular reference.
  var parent = new __super_class();
  parent.__instance = instance.__instance = instance;

  // create references to the parent functions on this instance of the parent
  for (i in superclass_prototype) {
    parent[i] = this.method(superclass_prototype[i], parent);
  }

  // call the parent's constructor
  var args = [];
  for (var i=1; i<arguments.length; i++) {
    args.push(arguments[i]);
  }
  instance.parent = this.parent;
  var ret = this.superclass.apply(instance, args);
  parent.parent = instance.parent;
  instance.parent = parent;
  return ret;
}
__super_class_factory.prototype.extend_prototype = function() {
  if (!this.prototyped) {
    if (this.parent && !this.parent.prototyped) {
      this.parent.extend_prototype();
    }
    var superclass_prototype = this.superclass.prototype;
    var subclass_prototype = this.subclass.prototype;
    for (var i in superclass_prototype) {
      if (typeof superclass_prototype[i] == 'function') {
        if (typeof subclass_prototype[i] == 'undefined') {
          subclass_prototype[i] = this.method(superclass_prototype[i], null);
        }
      } else if (i != 'parent') {
        subclass_prototype[i] = superclass_prototype[i];
      }
    }
  }
}
__super_class_factory.prototype.method = function(method, parent) {
  return function() {
    var instance = this.__instance;
    var old_parent = instance.parent;
    instance.parent = parent ? parent : this.parent;
    try {
      var ret = method.apply(instance, arguments);
    } catch (e) {
      console ? console.error(e) : false;
    }
    instance.parent = old_parent;
    return ret;
  }
}
function __super_class(obj) {
}
Function.prototype.bind = function(context) {
  var method = this;
  return function() {
    return method.apply(context, arguments);
  }
}

function dp(object)
{
  var descString = "";
  for(var value in object)
    descString += (value + " => " + object[value] + "\n");
  if( descString != "" )
    alert(descString);
  else
    alert(object);
}

function toggleInlineFlyer(toggler) {
    if (toggler.innerHTML == 'hide flyer') {
        toggler.innerHTML = 'show flyer';
    } else {
        toggler.innerHTML = 'hide flyer';
    }
    toggle('inline_flyer_content');
}






function Ajax(doneHandler, failHandler)
{
  newAjax = this;
  this.onDone = doneHandler;
  this.onFail = failHandler;
  this.transport = this.getTransport();
  this.transport.onreadystatechange = ajaxTrampoline(this);
}

Ajax.prototype.get = function (uri, query, force_sync)
{
  // Firefox doesn't call onDone and onFail handlers if you force_sync
  force_sync = force_sync || false;
  if( typeof query != 'string' )
    query = ajaxArrayToQueryString(query);
  fullURI = uri+(query ? ('?'+query) : '');
  this.transport.open('GET', fullURI, !force_sync );
  this.transport.send('');
}

Ajax.prototype.post = function (uri, data, force_sync, no_post_form_id)
{
  force_sync = force_sync || false;
  no_post_form_id = no_post_form_id || false;

  if( typeof data != 'string' ) {
    data = ajaxArrayToQueryString(data);
  }
  if (!no_post_form_id) {
    var post_form_id=ge('post_form_id');
    if (post_form_id) {
      data+='&post_form_id='+post_form_id.value;
    }
  }
  this.transport.open('POST', uri, !force_sync);
  this.transport.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
  this.transport.send(data);
}

Ajax.prototype.stateDispatch = function ()
{
  try {
    if( this.transport.readyState == 1 && this.showLoad )
      ajaxShowLoadIndicator();
  
    if( this.transport.readyState == 4 ) {
      if( this.showLoad )
        ajaxHideLoadIndicator();
      if( this.transport.status >= 200 &&
          this.transport.status < 300 &&
          this.transport.responseText.length > 0 ) {
        try {
          if( this.onDone ) this.onDone(this, this.transport.responseText);
        } catch(tempError) {
          console ? console.error(tempError) : false;
        }
      } else {
        try {
          if( this.onFail ) this.onFail(this);
        } catch(tempError) {
          console ? console.error(tempError) : false;
        }
      }
    }
  } catch (error) {
    if( this.onFail ) this.onFail(this);
  }
}

Ajax.prototype.getTransport = function ()
{
  var ajax = null;
  
  try { ajax = new XMLHttpRequest(); }
  catch(e) { ajax = null; }
  
  try { if(!ajax) ajax = new ActiveXObject("Msxml2.XMLHTTP"); }
  catch(e) { ajax = null; }
  
  try { if(!ajax) ajax = new ActiveXObject("Microsoft.XMLHTTP"); }
  catch(e) { ajax = null; }
  
  return ajax;
}

function ajaxTrampoline(ajaxObject)
{
  return function () { ajaxObject.stateDispatch(); };
}

function ajaxArrayToQueryString(query) {
  var params = [];
  
  for (var key in query) {
    if (typeof query[key] == 'object') {
      for (var i=0; i<query[key].length; i++) {
        params.push(encodeURIComponent(key)+'[]='+encodeURIComponent(query[key][i]));
      }
    } else {
      params.push(encodeURIComponent(key)+'='+encodeURIComponent(query[key]));
    }
  }
  return params.join('&');
}

var ajaxLoadIndicatorRefCount = 0;

function ajaxShowLoadIndicator()
{
  indicatorDiv = ge('ajaxLoadIndicator');
  if( !indicatorDiv ) {
    indicatorDiv = document.createElement("div");
    indicatorDiv.id = 'ajaxLoadIndicator';
    indicatorDiv.innerHTML = 'Loading';
    indicatorDiv.className = 'ajaxLoadIndicator';
    document.body.appendChild(indicatorDiv);
  }
  
  indicatorDiv.style.top = (5 + pageScrollY()) + 'px';
  indicatorDiv.style.left = (5 + pageScrollX()) + 'px';
  indicatorDiv.style.display = 'block';
  ajaxLoadIndicatorRefCount++;
}

function ajaxHideLoadIndicator()
{
  ajaxLoadIndicatorRefCount--;
  if( ajaxLoadIndicatorRefCount == 0 )
    ge('ajaxLoadIndicator').style.display = '';
}

function setCookie(cookieName, cookieValue, nDays) {
  var today = new Date();
  var expire = new Date();
  if (nDays == null || nDays == 0) nDays = 1;
  expire.setTime(today.getTime() + 3600000 * 24 * nDays);
  document.cookie = cookieName + "=" + escape(cookieValue) + "; expires=" + expire.toGMTString() + "; path=/; domain=.facebook.com";
}

function clearCookie(cookieName) {
  document.cookie = cookieName + "=; expires=Mon, 26 Jul 1997 05:00:00 GMT; path=/; domain=.facebook.com";
}

function getCookie(name) {
  var nameEQ = name + "=";
  var ca = document.cookie.split(';');
  for (i = 0; i < ca.length; i++) {
    var c = ca[i];
    while (c.charAt(0) == ' ') c = c.substring(1, c.length);
    if (c.indexOf(nameEQ) == 0) {
        return unescape(c.substring(nameEQ.length, c.length));
    }
  }
  return null;
}

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;
generic_dialog.prototype.should_use_iframe = navigator.userAgent.indexOf('MSIE 6.0')!=-1;

// shows a dialog with raw html
generic_dialog.prototype.show_dialog=function(html) {
  if (!this.obj) {
    this.build_dialog();
  }
  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.onload.apply(this.img, arguments);
                                        this.dialog.hide_objects()
                                      }.bind({img:imgs[i],dialog:this,onload:imgs[i].onload})
                                    : this.hide_objects.bind(this);
    }
  }
  this.show();

  // eval inline js
  var scripts = this.content.getElementsByTagName('script');
  for (var i=0; i<scripts.length; i++) {
    eval(scripts[i].innerHTML);
  }
  return this;
}

generic_dialog.prototype.set_top=function(top) {
  return this;
}

generic_dialog.prototype.show_ajax_dialog_custom_loader=function(html,src) {
    this.show_dialog('<div class="dialog_loading">'+html+'</div>');
    var myself=this;
    var ajax=new Ajax(
            function(obj, text) {
            myself.show_dialog(text);
            });
    ajax.get(src);
    return this;
}

// shows a pop dialog with an ajax request and uses that innerHTML
generic_dialog.prototype.show_ajax_dialog=function(src) {
  var load = 'Loading...';
  return this.show_ajax_dialog_custom_loader(load,src);
}


// shows a dialog with the given title and body content
generic_dialog.prototype.show_prompt=function(title, content) {
  return this.show_dialog('<h2><span>' + title + '</span></h2><div class="dialog_content">' + content + '</div>');
}

generic_dialog.prototype.show_updateprogress=function(title, content) {
  return this.show_dialog('<h2><span style="text-align:center;">' + title + '</span></h2><div class="dialog_content" style="text-align:center;">' + 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';
  }
  return 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, buttons_left_msg, button3, button3js) {
 
  var buttons='<div class="dialog_buttons">';
  if (typeof(buttons_left_msg) != 'undefined') {
    buttons+='<div class="dialog_buttons_left_msg">';
    buttons+=buttons_left_msg;
    buttons+='</div>';
  }
  buttons+='<input class="inputsubmit" type="button" value="' + button1 + '" />';
  if (button2) {
    buttons+='<input class="inputsubmit" type="button" value="' + button2 + '" />';
  }
  if (button3) {
   buttons+='<input class="inputsubmit" type="button" value="' + button3 + '" />';
  }
  this.show_prompt(title, this.content_to_markup(content) + buttons);
  
  // Register objects
  var inputs=this.obj.getElementsByTagName('input'); 
  if (button3) {
	button1obj=inputs[inputs.length-3];
	button2obj=inputs[inputs.length-2];
	button3obj=inputs[inputs.length-1];
  } else 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;
  }
  if (button3js) {
    if (typeof button3js == 'string') {
      eval('button3js = function(){' + button3js + '}');
    }
    button3obj.onclick=button3js;
  }

  /**
   * 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 btn3_exists = (typeof button3obj != '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 (btn3_exists) {
		 button3obj.click();
	   } 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();
   return this;
}



// 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 this;
}

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';
  }
  if (this.iframe) {
    this.iframe.style.display='none';
  }

  // clear any pending timeouts on the dialog
  if (this.timeout) {
    clearTimeout(this.timeout);
    this.timeout = null;
    return;
  }

  // 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();
  }
  return this;
}

// fades the dialog out over X seconds
generic_dialog.prototype.anim_res=5;
generic_dialog.prototype.fade_out=function(interval, timeout, first_call) {
  // if we want to timeout first...
  if (timeout) {
    this.timeout = setTimeout(function(){this.fade_out(interval)}.bind(this), timeout);
    return this;
  } else if (this.timeout) {
    clearTimeout(this.timeout);
    this.timeout = null;
  }

  // otherwise perform the animation
  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);
    setTimeout(function(){this.fade_out(interval, 0, first_call)}.bind(this), this.anim_res);
  }
  else {
    this.hide();
    set_opacity(this.obj, 1);
  }
  return this;
}

// 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();
  return this;
}

// enables \ disables all buttons in the dialog
generic_dialog.prototype.enable_buttons = function(enable) {
  var inputs = this.obj.getElementsByTagName('input');
  for (var i=0; i<inputs.length; i++) {
    if (inputs[i].type == 'button' || inputs[i].type == 'submit') {
      inputs[i].disabled = !enable;
    }
  }
}

// hides <embeds> under this object
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.should_use_iframe) {
    if (!this.iframe && !(this.iframe=ge('generic_dialog_iframe'))) {
      this.iframe=document.createElement('iframe');
      this.iframe.id='generic_dialog_iframe';
    }
    this.iframe.frameBorder='0';
    document.body.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)
    return;
  this.reset_dialog_obj();
  this.reset_iframe();
}

// sizes the iframe to go behind the dialog content
generic_dialog.prototype.reset_iframe = function() {
  if (!this.should_use_iframe) {
    return;
  }
  this.iframe.style.left = elementX(this.frame)+'px';
  this.iframe.style.top = elementY(this.frame)+'px';
  this.iframe.style.width = this.frame.offsetWidth+'px';
  this.iframe.style.height = this.frame.offsetHeight+'px';
  this.iframe.style.display = '';
}

// 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.top = 200;
  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.frame = this.popup.getElementsByTagName('tbody')[0];
  this.content = document.getElementById('pop_content');
}

// centers the dialog where it should be
pop_dialog.prototype.reset_dialog_obj=function() {
  this.popup.style.top=(document.documentElement.scrollTop?document.documentElement.scrollTop:document.body.scrollTop)+this.top+'px';
}

// sets the offset of the dialog from the top of the page
pop_dialog.prototype.set_top = function(top) {
  this.top = top;
}

//
// 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.arrow = this.popup.getElementsByTagName('div')[0];
  this.content = this.frame = this.popup.getElementsByTagName('div')[1];
}

// sets this dioalog near its context
contextual_dialog.prototype.reset_dialog_obj=function() {
  var x = elementX(this.context);
  var width = this.popup.offsetWidth-this.arrow_padding;
  var center = (document.body.offsetWidth-width)/2;
  var left = Math[(center < x) ? 'max' : 'min'](center, x-width);

  this.popup.style.top = (elementY(this.context)+5)+'px';
  this.popup.style.left = left+'px';
  this.arrow.style.backgroundPosition = (x-left-this.arrow_width)+'px';
}
contextual_dialog.prototype.arrow_padding = 12;
contextual_dialog.prototype.arrow_width = 13;