/* Eventful.com global JS
 * Copyright EVDB, Inc. All rights reserved except where otherwise noted.
 */
if (typeof window.JS == "undefined") var JS = {};
JS.defineGlobal = function(sVar, xVal)
{
    if (xVal === undefined)
    {
        xVal = {};
    }
    if (typeof window[sVar] == "undefined")
    {
        window[sVar] = xVal;
        return xVal;
    }
    return window[sVar];
}

JS.defineGlobal("Eventful");
JS.defineGlobal("DOM");
JS.defineGlobal("CSS");
Eventful.Autoclose = {};

function toggle_all_enabled_checkboxes() {
  var main = document.getElementById('check_all');
  var new_val = main.checked;
  var inputs = document.getElementsByTagName('input');
  for (i=0; i<inputs.length; i++) {
    if (inputs[i].type == 'checkbox' && !inputs[i].disabled && inputs[i] != main) {
      inputs[i].checked = new_val;
    }
  }

  var text = document.getElementById('check_all_text');
  if (new_val) {
    text.innerHTML = "Uncheck all";
  } else {
    text.innerHTML = "Check all";
  }
}

/* height_adjust
 *
 * Used with the "grow" arrows in new_event and elsewhere.
 */
function height_adjust(item, size) {
  var elem = document.getElementById(item);
  if(!elem.style.height) {
    elem.style.height = elem.offsetHeight+'px';
  }
  var height = parseInt(elem.style.height.substr(0,
    elem.style.height.length-2));
  height += size;
  elem.style.height = height+'px';
}

/* set_focus
 *
 * Given a form name and an element name, sets the focus on the
 * element.
 */
function set_focus(fname,ename) {
  if(fname && ename && document.forms[fname] && document.forms[fname].elements[ename]) {
    var element = document.forms[fname].elements[ename];
    if(element != null) {
      element.focus();
      element.select();
    }
  }
}

/* toggle_visibility
 *
 * Given an item ID, toggles the visibility of the item.  If an
 * optional select_item ID is given, after making item visible,
 * the input focus is sent to select_item.
 * Returns the new display state of the element.
 */
function toggle_visibility(item,select_item)
{
  var theItem = document.getElementById(item);
  if(theItem.style.display == "block")
  {
    theItem.style.display = "none";
  }
  else
  {
    theItem.style.display = "block";
  }
  if(select_item)
  {
    var selectItem = document.getElementById(select_item);
    selectItem.focus();
    selectItem.select();
  }
}

/* toggle_exclusive_visibility
 *
 * Works like toggle_visibilty, except it can be used where only one
 * of two possibilities should be visible at any one time.  You can use
 * this to switch between one of the following three states:
 *   Item A is visible
 *   Item B is visible
 *   Item A and B are invisible
 * If you wish to have only the first two states, see swap_visibility().
 */
function toggle_exclusive_visibility(item,noitem,select_item) {
  var theItem = document.getElementById(item);
  var theNoItem = document.getElementById(noitem);
  if(theItem.style.display == "block") {
    theItem.style.display = "none";
  } else {
    theItem.style.display = "block";
    theNoItem.style.display = "none";
  }
  if(select_item) {
    var selectItem = document.getElementById(select_item);
    selectItem.focus();
    selectItem.select();
  }
}

/* swap_visibility
 *
 * Swaps the visibility property between two items.  This means that one
 * of the two items (the first one) is always visible.  See
 * toggle_exclusive_visibility if you wish to be able to hide both items.
 *
 * This works by making item1 visible and hiding item2.  It does NOT blindly
 * swap the visibility of the two items.
 */
function swap_visibility(item1,item2,toFocus) {
  var i1 = document.getElementById(item1);
  var i2 = document.getElementById(item2);
  i1.style.display = "block";
  i2.style.display = "none";
  if(toFocus) {
    i3 = document.getElementById(toFocus);
    if (i3) {
      i3.focus();
      i3.select();
    }
  }
}

/* Show
 *
 * Given an item ID, makes the item visible.  If an
 * optional select_item ID is given, after making item visible,
 * the input focus is sent to select_item.
 */
function Show(item,select_item)
{
  var theItem = document.getElementById(item);
  theItem.style.display = "block";
  if(select_item)
  {
    var selectItem = document.getElementById(select_item);
    selectItem.focus();
    selectItem.select();
  }
}

/* Hide
 *
 * Given an item ID, makes the item invisible.  If an
 * optional select_item ID is given, after making item invisible,
 * the input focus is sent to select_item. (hint: don't make the select_item
 * something within the now-hidden item, as it'll be invisible now)
 */
function Hide(item,select_item)
{
  var theItem = document.getElementById(item);
  theItem.style.display = "none";
  if(select_item)
  {
    var selectItem = document.getElementById(select_item);
    selectItem.focus();
    selectItem.select();
  }
}


/* addLoadEvent
 *
 * Registers an onload handler for the page. See the following:
 * http://simon.incutio.com/archive/2004/05/26/addLoadEvent
 */
function addLoadEvent(func) {
    Events.addHandler(window, "load", func);
}

/* help
 *
 * Encapsulates the popup window behavior necessary to get contextual help
 * that does not interfere with process flow.
 */
function help(topic) {
  var url = "/help/" + topic;
  window.open(url,"EVDB_Help",'width=300,height=350,resizable,scrollbars');
}

Eventful.helpWindow = function(elLink)
{
    return window.open(elLink.href, elLink.target,
        'width=300,height=350,resizable=1,scrollbars=1');
}

/* Function to show the large version of an image on a detail page.
 */
function show_image(url,width,height) {
  window.open(url,"image_viewer", 'width='+(width+20)+',height='+(height+20)+',resizeable=1,scrollbars=0');
}
Eventful.showLargeImage = function(elLink, nWidth, nHeight)
{
    // make sure we have numbers
    nWidth = (nWidth * 1) || 300;
    nHeight = (nHeight * 1) || 300;

    // open the window and inject HTML
    var elWin = window.open('', elLink.target,
        'width='+ nWidth +',height='+ nHeight +
        ',resizable=1,scrollbars=1');
    if (elWin)
    {
        elWin.document.open("text/html");
        elWin.document.write('<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML'+
        ' 4.01//EN"\n   "http://www.w3.org/TR/html4/strict.dtd">\n' +
        '<html><head>\n<title>Eventful Image Viewer</title>'+
        '<style type="text/css">\n' +
        'html,body{margin:0; padding:0; overflow:hidden; width:100%;' +
        'height:100%;}\n' +
        'img,div{margin:0;padding:0;}\n' +
        'p{margin:0;padding:0.5em;text-align:center;}\n' +
        '</style><body><div><img src="'+ elLink.href +'" alt="Full image" ' +
        'title="Click to close" onclick="self.close()" />' +
        '</div></body></html>');
        elWin.document.close();

        return true;
    }
    return false;
}

/* addEventToCalendar
 *
 * Add an event to a user's calendar.
 */
function addEventToCalendar(user,calendar,seid,icon_state) {

  /* Change the add image to the "added" version.
   */
  var obj = document.getElementById("b_" + seid);
  obj.src = "/images/" + icon_state + ".gif";

  /* Change the add event popup contents to "Updating..."
   */
  popup = document.getElementById("ap_" + seid);
  popup.innerHTML = "Updating<p />Please wait...";
  Show("ap_" + seid);

  /* Add the event to the calendar.
   */
  var url = "/users/" + user + "/calendars/events/add?calendar_id="
    + calendar + "&event_id=" + seid;
  callbackGET(url, refresh_popup_callback(seid, false));

  /* Get new contents for the add event popup that reflects the new
   * state.
   */
/*
  var url = "/parts/add_groupcal_box_contents.php?id=" + event;
  replaceContentsWithURL("ap_"+event,url);
*/
}

/* removeEventFromCalendar
 *
 * Add an event to a user's calendar.
 */
function removeEventFromCalendar(user,calendar,event,icon_state,refresh_page) {

/*  alert("user: " + user + ", calendar: " + calendar + ", event: " + event);*/

  /* Change the add image to the "not added" version.
   */
  var obj = document.getElementById("b_" + event);
  obj.src = "/images/" + icon_state + ".gif";

  /* Change the add event popup contents to "Updating..."
   */
  popup = document.getElementById("ap_" + event);
  popup.innerHTML = "Updating<p />Please wait...";
  Show("ap_" + event);

  /* Remove the event from the calendar.
   */
  var url = "/users/" + user + "/calendars/events/remove?calendar_id="
    + calendar + "&event_id=" + event;
  callbackGET(url, refresh_popup_callback(event, refresh_page));

  /* Get new contents for the add event popup that reflects the new
   * state.
   */
/*
  var url = "/parts/add_groupcal_box_contents.php?id=" + event;
  replaceContentsWithURL("ap_"+event,url);
*/
}

/* addEventToGroup
 *
 * Add an event to a user's group.
 */
function addEventToGroup(user,group,event,icon_state) {

  /* Change the add image to the "added" version.
   */
  var obj = document.getElementById("b_" + event);
  obj.src = "/images/" + icon_state + ".gif";

  /* Change the add event popup contents to "Updating..."
   */
  popup = document.getElementById("ap_" + event);
  popup.innerHTML = "Updating<p />Please wait...";
  Show("ap_" + event);

  /* Add the event to the group's calendar.
   */
  var url = "/users/" + user + "/groups/events/add?group_id="
    + group + "&event_id=" + event;
  callbackGET(url, refresh_popup_callback(event, false));

  /* Get new contents for the add event popup that reflects the new
   * state.
   */
/*
  var url = "/parts/add_groupcal_box_contents.php?id=" + event;
  replaceContentsWithURL("ap_"+event,url);
*/
}

/* removeEventFromGroup
 *
 * Add an event to a user's group.
 */
function removeEventFromGroup(user,group,event,icon_state,refresh_page) {

  /* Change the add image to the "not added" version.
   */
  var obj = document.getElementById("b_" + event);
  obj.src = "/images/" + icon_state + ".gif";

  /* Change the add event popup contents to "Updating..." */
  popup = document.getElementById("ap_" + event);
  popup.innerHTML = "Updating<p />Please wait...";
  Show("ap_" + event);

  /* Remove the event from the group's calendar.
   */
  var url = "/users/" + user + "/groups/events/remove?group_id="
    + group + "&event_id=" + event;
  callbackGET(url, refresh_popup_callback(event, refresh_page));
}

function refresh_popup_callback(seid,refresh_page) {
  if (refresh_page) {
    return function() {
      window.location.reload();
    }
  } else {
    return function() {
      Hide("ap_" + seid);
      var url = "/parts/add_groupcal_box_contents.php?id=" + seid;
      replaceContentsWithURL("ap_" + seid, url);
      if (document.getElementById('my-eventful-calendar-box')) {
        replaceContentsWithURL('my-eventful-calendar-box', url);
      }
    }
  }
}

/* add_favorite
 *
 * Add an item to a user's list of favorites.
 */
function add_favorite(user, type, item_id, label) {
  var label = label || false;

  if (label) {
    var imFav = document.getElementById("f_"+item_id);
    imFav.src = "/images/star-on.gif";
    replaceContentsWithText('fav_label', "<a href=\"javascript:remove_favorite('" + user + "','" + type + "','" + item_id + "',true)\">Remove from favorites list</a>");
  }
  else {
    var elFav = document.getElementById("f_"+item_id);
    elFav.style.backgroundImage = "url('/images/star-on.gif')";
  }

  // Remove the favorite.
  var url = "/users/" + user + "/favorites/add?item_id=" + item_id +
    "&type=" + type + "&time="+(new Date().valueOf());
  callbackGET(url,refresh_favorite_callback(type, item_id, false, label));
}

/* remove_favorite
 *
 * Remove an item from a user's list of favorites.
 */
function remove_favorite(user, type, item_id, label) {
  var label = label || false;

  if (label) {
    var imFav = document.getElementById("f_"+item_id);
    imFav.src = "/images/star-off.gif";
    replaceContentsWithText('fav_label', "<a href=\"javascript:add_favorite('" + user + "','" + type + "','" + item_id + "',true)\">Add to favorites list</a>");
  }
  else {
    var elFav = document.getElementById("f_"+item_id);
    elFav.style.backgroundImage = "url('/images/star-off.gif')";
  }

  // Remove the favorite.
  var url = "/users/" + user + "/favorites/remove?item_id=" + item_id +
    "&type=" + type + "&time="+(new Date().valueOf());
  callbackGET(url,refresh_favorite_callback(type, item_id, false, label));
}


function refresh_favorite_callback(type, item_id, refresh_page, label) {
  label = label || false;
  return function() {
    var url = "/parts/favorite_contents.php?item_id=" + item_id + "&type=" + type + "&time="+(new Date().valueOf());
    if (label) {
      url += "&label=true";
    }
    replaceContentsWithURL("af_"+item_id, url);
    if(refresh_page) {
      window.location.reload();
    }
  }
}

/* List style favorites */

/* Show the "calendar add" popup. */
function show_calendar_add(event)
{
    var obj = DOM.get("ap_" + event);
    if (obj)
    {
        obj.style.display = "block";
        Eventful.Autoclose.set_id("ap_" + event);
    }
}

/* image_file_change
 *
 * Handles the change event of input[type="file"] elements to catch bad image
 * URLs.
 */
function image_file_change(evt)
{
  if (evt)
  {
    var elFrom = evt.target || evt.srcElement;
    var elError = document.getElementById("image_error");

    if (elFrom && elFrom.value && /^(ht|f)tp:\/\//i.test(elFrom.value))
    {
      elError.style.display = 'block';
    }
    else
    {
      elError.style.display = 'none';
    }
  }
}

function locale_controller(evt) {
}

// The following code is Copyright (C) Simon Willison 2004.
//
// document.getElementsBySelector(selector)
// - returns an array of element objects from the current document
//   matching the CSS selector. Selectors can contain element names,
//   class names and ids and can be nested. For example:
//     elements = document.getElementsBySelect('div#main p a.external')
// Version 0.4 - Simon Willison, March 25th 2003

function getAllChildren(e) {
  // Returns all children of element. Workaround required for IE5/Windows. Ugh.
  return e.all ? e.all : e.getElementsByTagName('*');
}

document.getElementsBySelector = function(selector) {
  // Attempt to fail gracefully in lesser browsers
  if (!this.getElementsByTagName) {
    return new Array();
  }
  // Split selector in to tokens
  var tokens = selector.split(' ');
  var currentContext = new Array(this);
  for (var i = 0; i < tokens.length; i++) {
    token = tokens[i].replace(/^\s+/,'').replace(/\s+$/,'');;
    if (token.indexOf('#') > -1) {
      // Token is an ID selector
      var bits = token.split('#');
      var tagName = bits[0];
      var id = bits[1];
      var element = this.getElementById(id);
      if (tagName && element.nodeName.toLowerCase() != tagName) {
        // tag with that ID not found, return false
        return new Array();
      }
      // Set currentContext to contain just this element
      currentContext = new Array(element);
      continue; // Skip to next token
    }
    if (token.indexOf('.') > -1) {
      // Token contains a class selector
      var bits = token.split('.');
      var tagName = bits[0];
      var className = bits[1];
      if (!tagName) {
        tagName = '*';
      }
      // Get elements matching tag, filter them for class selector
      var found = new Array;
      var foundCount = 0;
      for (var h = 0; h < currentContext.length; h++) {
        var elements;
        if (tagName == '*') {
            elements = getAllChildren(currentContext[h]);
        } else {
            elements = currentContext[h].getElementsByTagName(tagName);
        }
        for (var j = 0; j < elements.length; j++) {
          found[foundCount++] = elements[j];
        }
      }
      currentContext = new Array;
      var currentContextIndex = 0;
      for (var k = 0; k < found.length; k++) {
        if (found[k].className && found[k].className.match(new RegExp('\\b'+className+'\\b'))) {
          currentContext[currentContextIndex++] = found[k];
        }
      }
      continue; // Skip to next token
    }
    // Code to deal with attribute selectors
    if (token.match(/^(\w*)\[(\w+)([=~\|\^\$\*]?)=?"?([^\]"]*)"?\]$/)) { // "
      var tagName = RegExp.$1;
      var attrName = RegExp.$2;
      var attrOperator = RegExp.$3;
      var attrValue = RegExp.$4;
      if (!tagName) {
        tagName = '*';
      }
      // Grab all of the tagName elements within current context
      var found = new Array;
      var foundCount = 0;
      for (var h = 0; h < currentContext.length; h++) {
        var elements;
        if (tagName == '*') {
            elements = getAllChildren(currentContext[h]);
        } else {
            elements = currentContext[h].getElementsByTagName(tagName);
        }
        for (var j = 0; j < elements.length; j++) {
          found[foundCount++] = elements[j];
        }
      }
      currentContext = new Array;
      var currentContextIndex = 0;
      var checkFunction; // This function will be used to filter the elements
      switch (attrOperator) {
        case '=': // Equality
          checkFunction = function(e) { return (e.getAttribute(attrName) == attrValue); };
          break;
        case '~': // Match one of space seperated words
          checkFunction = function(e) { return (e.getAttribute(attrName).match(new RegExp('\\b'+attrValue+'\\b'))); };
          break;
        case '|': // Match start with value followed by optional hyphen
          checkFunction = function(e) { return (e.getAttribute(attrName).match(new RegExp('^'+attrValue+'-?'))); };
          break;
        case '^': // Match starts with value
          checkFunction = function(e) { return (e.getAttribute(attrName).indexOf(attrValue) == 0); };
          break;
        case '$': // Match ends with value - fails with "Warning" in Opera 7
          checkFunction = function(e) { return (e.getAttribute(attrName).lastIndexOf(attrValue) == e.getAttribute(attrName).length - attrValue.length); };
          break;
        case '*': // Match ends with value
          checkFunction = function(e) { return (e.getAttribute(attrName).indexOf(attrValue) > -1); };
          break;
        default :
          // Just test for existence of attribute
          checkFunction = function(e) { return e.getAttribute(attrName); };
      }
      currentContext = new Array;
      var currentContextIndex = 0;
      for (var k = 0; k < found.length; k++) {
        if (checkFunction(found[k])) {
          currentContext[currentContextIndex++] = found[k];
        }
      }
      // alert('Attribute Selector: '+tagName+' '+attrName+' '+attrOperator+' '+attrValue);
      continue; // Skip to next token
    }

    if (!currentContext[0]){
      return;
    }

    // If we get here, token is JUST an element (not a class or ID selector)
    tagName = token;
    var found = new Array;
    var foundCount = 0;
    for (var h = 0; h < currentContext.length; h++) {
      var elements = currentContext[h].getElementsByTagName(tagName);
      for (var j = 0; j < elements.length; j++) {
        found[foundCount++] = elements[j];
      }
    }
    currentContext = found;
  }
  return currentContext;
}

/* That revolting regular expression explained
/^(\w+)\[(\w+)([=~\|\^\$\*]?)=?"?([^\]"]*)"?\]$/
  \---/  \---/\-------------/    \-------/
    |      |         |               |
    |      |         |           The value
    |      |    ~,|,^,$,* or =
    |   Attribute
   Tag
"*/

// END Simon Willison code

/** Events - bfults@gmail.com - 2006-04-11                                   **
 ** Code licensed under Creative Commons Attribution-ShareAlike License      **
 ** http://creativecommons.org/licenses/by-sa/2.5/                           **/
var Events = {};
Events.pageLoaded = false;
Events.eventStack = [];
Events.unloadStack = [];
Events.loadStack = [];
Events.addHandler = function(xEl, sEvt, fnCB)
{
    bCap = false;
    if (xEl == window)
    {
        if (sEvt == "load")
        {
            Events.loadStack.push(fnCB);
            return true;
        }
        else if (sEvt == "unload")
        {
            Events.unloadStack.push(fnCB);
            return true;
        }
    }

    Events.eventStack.push([!Events.pageLoaded, xEl, sEvt, fnCB, bCap]);

    if (Events.pageLoaded == true)
    {
        return Events._xbEventAddHandler(xEl, sEvt, fnCB, bCap);
    }
    return true;
}
Events.removeHandler = function(xEl, sEvt, fnCB)
{
    var oEl = (typeof (xEl) == "string") ? document.getElementById(xEl) : xEl;
    bCap = false;
    for (var i=0, el=null; i < Events.eventStack.length; i++)
    {
        el = Events.eventStack[i];
        if (el[1] == oEl && el[2] == sEvt && el[3] == fnCB && el[4] == bCap)
        {
            Events.eventStack.splice(i, 1);
            return _xbEventRemoveHandler(oEl, sEvt, fnCB, bCap);
        }
    }
    return false;
}
Events.getTargetElement = function(evt)
{
    if (!evt && window.event) evt = window.event;
    if (!evt) return null;
    return evt.target || evt.srcElement;
}
// Private Functions
Events._setup = function()
{
    var el = null;
    Events.pageLoaded = true;

    for (var i = Events.loadStack.length - 1; i >= 0; i--)
    {
        if (typeof Events.loadStack[i] == "function") Events.loadStack[i]();
        delete Events.loadStack[i];
    }

    for (i=0; i < Events.eventStack.length; i++)
    {
        el = Events.eventStack[i];
        if (el[0] == true)
            Events._xbEventAddHandler(el[1], el[2], el[3], el[4]);
    }
    return true;
}
Events._cleanup = function()
{
    var el = null;
    try
    {
        if (Events.unloadStack && Events.unloadStack.length)
        {
            while (el = Events.unloadStack.pop())
            {
                if (typeof el == "function") el();
            }
        }
        if (Events.eventStack && Events.eventStack.length)
        {
            while (el = Events.eventStack.pop())
            Events._xbEventRemoveHandler(el[1], el[2], el[3], el[4]);
        }
        for (var i in Events) delete Events[i];
        delete window.Events;
    } catch (e) {}
    return true;
}
Events._xbEventRemoveHandler = function(oEl, sEvt, fnCB, bCap)
{
    if (oEl)
    {
        if (!bCap) bCap = false;
        if (oEl.removeEventListener)
        {
            oEl.removeEventListener(sEvt, fnCB, bCap);
            return true;
        }
        else if (oEl.detachEvent)
        {
            return oEl.detachEvent("on"+ sEvt, fnCB);
        }
    }
    return false;
}
Events._xbEventAddHandler = function(xEl, sEvt, fnCB, bCap)
{
    var oEl = (typeof (xEl) == "string") ? document.getElementById(xEl) : xEl;
    if (oEl)
    {
        if (!bCap) bCap = false;
        if (oEl.addEventListener)
        {
            oEl.addEventListener(sEvt, fnCB, bCap);
            return true;
        }
        else if (oEl.attachEvent)
        {
            return oEl.attachEvent("on"+ sEvt, fnCB);
        }
    }
    return false;
}
Events._xbEventAddHandler(window, "load", Events._setup, false);
Events._xbEventAddHandler(window, "unload", Events._cleanup, false);
/* End Events */

/** DOM Class Manipulation - bfults@gmail.com - 2006-04-17                   **
 ** Code licensed under Creative Commons Attribution-ShareAlike License      **
 ** http://creativecommons.org/licenses/by-sa/2.5/                           **/
CSS.hasClass = function (el, sClass)
{
  if (el && el.className !== undefined)
  {
    return new RegExp("(^|\\s+)"+sClass+"(\\s+|$)").test(el.className);
  }

  return false;
}
CSS.addClass = function (el, sClass)
{
  if (el && el.className !== undefined)
  {
    CSS.remClass(el, sClass);
    el.className += ((el.className.length > 0) ? " " : '')+ sClass;
    return true;
  }

  return false;
}
CSS.remClass = function (el, sClass)
{
  if (el && el.className !== undefined)
  {
    el.className = el.className.replace(
      new RegExp("^"+sClass+"$|^"+sClass+"\\s+|\\s+"+sClass+
      "(?=\\s|$)",'g'), '');
    return true;
  }

  return false;
}
/* End DOM Class Manipulation */

/** Autoclose Stuff **/
Eventful.Autoclose.num_elements = 0;
Eventful.Autoclose.element_id = null;

// Called on all clicks (which are inside the body) to close autoclose element
Eventful.Autoclose.body_click = function(evt)
{
  if (evt)
  {
    var elTarget = Events.getTargetElement(evt);
    if (elTarget)
    {
      // if we're clicking on an autoclose or autoclose-click element
      if (CSS.hasClass(elTarget, "autoclose") ||
        CSS.hasClass(elTarget, "autoclose-click") ||
        DOM.findAncestor(elTarget, {className: "autoclose"}))
      {
        // bail out early before closing the block
        return true;
      }
    }
  }
  Eventful.Autoclose.close_block();
  return true;
}

// Called to close the current autoclose block
Eventful.Autoclose.close_block = function()
{
  var id = Eventful.Autoclose.element_id;
  if (id && id.length)
  {
    var elAutoclose = document.getElementById(id);
    if (elAutoclose)
    {
      elAutoclose.style.display = 'none';
      Eventful.Autoclose.element_id = null;
    }
  }
  return true;
}

Events.addHandler(window, "load", function() {
    if (window.Eventful && Eventful.Autoclose && Eventful.Autoclose.body_click)
    {
        Events.addHandler(document.body, "click",
            Eventful.Autoclose.body_click);
    }
});

// Called when the *click* elements are clicked to show the autoclose elements
Eventful.Autoclose.set_id = function(idEl)
{
  // if we're setting a new id, close an old block (if it's open)
  Eventful.Autoclose.close_block();
  Eventful.Autoclose.element_id = idEl;
  return true;
}
/** End Autoclose Stuff **/

/** DOM.findAncestor(elChild, {att: val[, att2: val2]})
 ** If elChild has an ancestor with specified attributes attn with values valn
 ** Return the ancestor element (or null if none found)
 **/
DOM.findAncestor = function(elChild, hAtts)
{
  var el = elChild, att = '', bMatch = true, ct = 0;
  if (elChild && hAtts)
  {
    // traverse upward as long as the parentNode is valid
    while(el = el.parentNode)
    {
      bMatch = true;

      // for each specified attribute
      ct = 0;
      for (att in hAtts)
      {
        if (el[att] !== undefined)
        {
          switch (att)
          {
            case 'className':
            bMatch = (CSS.hasClass(el, hAtts[att]));
            break;

            default:
            bMatch = (el[att] == hAtts[att]);
          }
          ct++;
        }
      }

      // this el has passed all tests, return it!
      if (ct > 0 && bMatch)
      {
        return el;
      }
    }
  }
  return null;
}


/** DOM.get(idOrEl, idOrEl2, idOrEl3, ...) -- getElement(s)ById
 ** Returns DOM elements based on their string IDs.
 ** Will return a single element given a single argument, otherwise an array.
 ** Originally from Sam Stephenson <sam@conio.net>. Much better now.
 **/
DOM.get = function()
{
  var els = [], el = null;
  for (var i = 0; i < arguments.length; i++)
  {
    el = arguments[i];
    if (typeof el == "string")
    {
      el = document.getElementById(el);
    }
    if (arguments.length == 1)
    {
      return el;
    }
    els[els.length] = el;
  }
  return els;
}
$ = DOM.get;

/** DOM.getByClass(sTagName, sClassName[, elRoot]) -- getElementsByClassName
 ** Returns all elements of a given tag name (* for all) with the given class
 ** name, optionally restricted to the subtree of a specific element, elRoot.
 **/
DOM.getByClass = function(sTagName, sClassName, elRoot)
{
  var elsMatch = [];
  var elsAll = $tag(sTagName, elRoot);

  try {
    for (var i=0; i < elsAll.length; i++)
    {
        if (CSS.hasClass(elsAll[i], sClassName))
        {
          elsMatch[elsMatch.length] = elsAll[i];
        }
    }
  }
  catch (e) {}
  return elsMatch;
}
getElementsByClass = getElementsByClassName = $class = DOM.getByClass;

/** DOM.getByTag(sTagName[, elRoot]) -- getElementsByTagName
 ** Returns all elements of a given tag name (* for all) , optionally restricted
 ** to the subtree of a specific element, elRoot.
 **/
DOM.getByTag = function(sTagName, elRoot)
{
  if (!elRoot)
  {
    elRoot = document;
  }

  return elRoot.getElementsByTagName(sTagName);
}
$tag = DOM.getByTag;

/** Array.arrayize(el1[, el2, ...])
 ** Returns a single array containing all elements within arguments or the
 ** argument itself if it is not iterable.
 ** Note: it only "collapses" one level of arrays.
 **/
Array.arrayize = function()
{
    if (arguments.length > 0)
    {
        var aRet = [], cur, j=0;
        for (var i=0; i < arguments.length; i++)
        {
            if (arguments[i] !== undefined)
            {
                cur = arguments[i];
                // custom objects with toArray()
                if (cur.toArray)
                {
                    aRet = aRet.concat(cur.toArray());
                }
                // arrays
                else if (cur instanceof Array)
                {
                    aRet = aRet.concat(cur);
                }
                // other iterables
                else if (typeof cur != "string" && cur.length !== undefined)
                {
                    for (j=0; j < cur.length; j++)
                    {
                        aRet.push(cur[j]);
                    }
                }
                // non-iterables
                else
                {
                    aRet.push(cur);
                }
            }
        }
        return aRet;
    }
    return [];
}
$A = Array.arrayize;

/* focus the primary search box if there is one. */

var focusElement = "fhqwgads";

function setInitialFocus() {
  try {
    var e = document.getElementById(focusElement);
    if (e && e.focus) {
      e.focus();
    }
  }
  catch (e) {
    return false;
  }
}

Events.addHandler(window, 'load', setInitialFocus);


/*
 * Select a text box (or similar) and move its selection caret to the end
 */
function selectAtEnd(object)
{
    if(object.focus) {
        object.focus();
    }
    if(object.setSelectionRange) {
        object.setSelectionRange(object.value.length, object.value.length);
    }
}
/*
 * Select a text box (or similar) and move its selection caret to the beginning
 */
function selectAtBeginning(object)
{
    if(object.focus) {
        object.focus();
    }
    if(object.setSelectionRange) {
        object.setSelectionRange(0, 0);
    }
}
