//=====================================================================
// Event Listener
// by Scott Andrew - http://scottandrew.com
// edited by Mark Wubben, <useCapture> is now set to false
//=====================================================================
function addEvent(obj, evType, fn)
{
  if(obj.addEventListener){
    obj.addEventListener(evType, fn, false); 
    return true;
  } else if (obj.attachEvent){
    var r = obj.attachEvent('on'+evType, fn);
    return r;
  } else {
    return false;
  }
}

/** Constants to aid readability of onclick handlers. */
var ONCLICK_OK     =false; // Do NOT execute href.
var ONCLICK_FAILED =true;  // DO execute href.

/** Shorthand for document.getElementById. Borrowed from Prototype.js */
function $(id){ return document.getElementById(id); }

/** Returns parameter p if it's set, else the delfault value d. */
function dflt(p,d)
{
  return p==null? d: p;
}

/** Move 'e' to precede 'before'. */
function move_before(e,before)
{
  if(e && before)
  {
    e.parentNode.removeChild(e);
    before.parentNode.insertBefore(e,before);
  }
}

/** Helper class for generating POST parameters.
 *  If the optional parameter 'form' is set, then the object is initialised from
 *  the form's fields.
 */
function Params(form)
{
  this.value='';
  if(form!=null)
    for(var i=0; i<form.elements.length; i++)
      this.add(form.elements[i].name,form.elements[i].value);
}
Params.prototype.add=function(k,v)
{
  if(this.value.length>0)
    this.value+='&';
  this.value+=k+'='+encodeURI(v);
}

function getFirstChildByTagName(e,tagName)
{
  if(e)
  {
    var arr=e.getElementsByTagName(tagName);
    if(arr.length)
      return arr[0];
  }
  return false;
}

/** Gets all of the TEXT and CDATA from an element, concatenated into a
 *  single string. */
function getInnerText(e,result)
{
  result=dflt(result,'');
  for(var i=0; i<e.childNodes.length; i++)
  {
    var nt=e.childNodes[i].nodeType;
    if(nt==3 /* TEXT_NODE */ || nt==4 /* CDATA_SECTION_NODE */)
    {
      if(result.length==0)
        result+=' ';
      result+=e.childNodes[i].nodeValue;
    }
    else if(nt==1 /* ELEMENT_NODE */)
    {
      result=getInnerText(e.childNodes[i],result);
    }
  }
  return result;
}

/** Submit an Ajax request. Options are:
 *   oncomplete: callback function. Passed the xml document.
 *   method: 'GET', 'POST' (default)
 *   data: data for POST request
 *   form: form from which to calculate data (ignored if data is set).
 */
function ajax(url,options)
{
  if(options==null)
    options=new Object();
  var req=new XMLHttpRequest();
  if(!req)
    return false;
  // method
  if(options.method)
    req.open(options.method,url,true);
  else
    req.open('POST',url,true);
  // data, form
  var data=null;
  if(options.data)
  {
    data=options.data;
  }
  else if(options.form)
  {
    var params=new Params(options.form);
    data=params.value;
  }
  if(data)
  {
    req.setRequestHeader("Content-type","application/x-www-form-urlencoded");
    req.setRequestHeader("Content-length",data.length);
  }
  // oncomplete
  if(options.oncomplete)
  {
    var oncomplete=options.oncomplete;
    req.onreadystatechange=
      function()
      {
        if(!(req.readyState==4 && req.status==200))
          return;
        oncomplete(req.responseXML.documentElement);
      }
  }
  req.setRequestHeader('If-Modified-Since','Sat, 1 Jan 2000 00:00:00 GMT');
  req.send(data);
  return true;
}

/** Helper function that submits a form through Ajax. */
function ajax_form(form,options)
{
  if(options==null)
    options=new Object();
  options.form=form;
  return ajax(form.action,options);
}

/** Fade out then remove an element. */
function fade_out(e,hide)
{
  var className=dflt(e.className,'');
  var trans=10;
  function evt_fade_out()
  {
    trans-=2;
    if(trans<=0)
    {
      if(hide)
      {
        e.className=className;
        e.style.display='none';
      }
      else
      {
        e.parentNode.removeChild(e);
      }
    }
    else
    {
      e.className='fade'+trans+' '+className;
      setTimeout(evt_fade_out,100);
    }
  }
  evt_fade_out();
}

/** Fade in an element. Optionally set its style.display */
function fade_in(e,display)
{
  if(display)
    e.style.display=display;
  var className=dflt(e.className,'');
  var trans=0;
  function evt_fade_in()
  {
    if(trans>=10)
    {
      e.className=className;
    }
    else
    {
      e.className='fade'+trans+' '+className;
      trans+=2;
      setTimeout(evt_fade_in,100);
    }
  }
  evt_fade_in();
}

/** Finds Absolute Y position of an element. */
function findPosY(obj)
{
  var curtop = 0;
  if(obj.offsetParent)
      while(1)
      {
        curtop += obj.offsetTop;
        if(!obj.offsetParent)
          break;
        obj = obj.offsetParent;
      }
  else if(obj.y)
      curtop += obj.y;
  return curtop;
}

/** Cross-browser compatible implementation of scrollIntoView. */
function scrollIntoView(e)
{
  window.scrollTo(0,e.offsetHeight + findPosY(e));
}
