Position.center = function(element)
{
	var options = Object.extend({
					zIndex: 999,
					update: false
					}, arguments[1] || {});
	element = $(element)
	if(!element._centered){
		Element.setStyle(element, {position: 'absolute', zIndex:options.zIndex });
		element._centered = true;
	}
	var dims = Element.getDimensions(element);
	Position.prepare();	
	var winWidth = self.innerWidth || document.documentElement.clientWidth || document.body.clientWidth || 0;
	var winHeight = self.innerHeight ||	document.documentElement.clientHeight || document.body.clientHeight || 0;
	
	var offLeft = (Position.deltaX + Math.floor((winWidth-dims.width)/2));
	var offTop = (Position.deltaY + Math.floor((winHeight-dims.height)/2));
	
	element.style.top = ((offTop != null && offTop > 0) ? offTop : '0')+ 'px';
	element.style.left = ((offLeft != null && offLeft > 0) ? offLeft : '0') + 'px';
	if(options.update){
		Event.observe(window, 'resize', function(evt){
											Position.center(element);
										}, false);
		Event.observe(window, 'scroll', function(evt){
											Position.center(element);
										}, false);
	}
}

PeriodicalExecuter.prototype.registerCallback = function() {
	this.intervalID = setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);
}

PeriodicalExecuter.prototype.stop = function() {
	clearInterval(this.intervalID);
}

// Fix the Element.ClassNames for OPTION tags (IE ignores the className but not the class property)
Element.ClassNames.prototype._each = function(iterator){
	var elClassName = this.element.className;
	if(this.element.tagName == 'OPTION') {
		elClassName = this.element.getAttribute('class'); 
	}

	elClassName.split(/\s+/).select(function(name) {
      return name.length > 0;
    })._each(iterator);
}

Element.ClassNames.prototype.set = function(className){
	this.element.className = className;
	if(this.element.tagName == 'OPTION') {
		this.element.setAttribute('class', className);
	}
}

Object.extend(Array.prototype, {
	strip: function(inArray)
	{
		var l = this.length;
		var ll = inArray.length;
		for (var i = 0; i < l; i++){
			for(j=0; j<ll; j++){
				if(this[i] == inArray[j]){
					this.splice(i, 1);
				}
			}			
		}		
	}
})

//rewrite $ to use the gloval $contextDocument variable
$contextDocument = document;
function $() {
  var elements = new Array();

  for (var i = 0; i < arguments.length; i++) {
    var element = arguments[i];
    
    if (typeof element == 'string')      
      element = $contextDocument.getElementById(element);

    if (arguments.length == 1)
      return element;

    elements.push(element);
  }

  return elements;
}

function $_doc(inDoc, inFunction) {
	var old$contextDocument = $contextDocument;
	$contextDocument = inDoc;
	var args = $A(arguments).slice(2);
	var res = inFunction.apply(null, args);
	$contextDocument = old$contextDocument;
	return res;
}

Object.extend(Event, {
  _domReady : function() {
    if (arguments.callee.done) return;
    arguments.callee.done = true;

    if (this._timer)  clearInterval(this._timer);
    
    this._readyCallbacks.each(function(f) { f() });
    this._readyCallbacks = null;
},
  onDOMReady : function(f) {
    if (!this._readyCallbacks) {
      var domReady = this._domReady.bind(this);
      
      if (document.addEventListener)
        document.addEventListener("DOMContentLoaded", domReady, false);
        
        /*@cc_on @*/
        /*@if (@_win32)
            document.write("<script id=__ie_onload defer src=javascript:void(0)><\/script>");
            document.getElementById("__ie_onload").onreadystatechange = function() {
                if (this.readyState == "complete") domReady(); 
            };
        /*@end @*/
        
        if (/WebKit/i.test(navigator.userAgent)) { 
          this._timer = setInterval(function() {
            if (/loaded|complete/.test(document.readyState)) domReady(); 
          }, 10);
        }
        
        Event.observe(window, 'load', domReady);
        Event._readyCallbacks =  [];
    }
    Event._readyCallbacks.push(f);
  }
});

document.getElementsByAttributeValue = function(inAttribute, inValue, parentElement)
{
	var i = 0;
	var children = ($(parentElement) || document.body).getElementsByTagName('*');
	return $A(children).inject([], function(elements, child) {
    	if (child.getAttribute(inAttribute) == inValue)
	    	elements.push(child);
		return elements;
	});
}

document.getAnchorsByHrefValue = function(inValue, parentElement)
{
	var i = 0;
	var children = ($(parentElement) || document.body).getElementsByTagName('A');
	return $A(children).inject([], function(elements, child) {
    	if (child.getAttribute('href').indexOf(inValue) > -1)
	    	elements.push(child);
		return elements;
	});
}

document.getElementsByTagValue = function(inValue, parentElement)
{
	var i = 0;
	var children = ($(parentElement) || document.body).getElementsByTagName('*');
	return $A(children).inject([], function(elements, child) {
    	if (child.childNodes[0].nodeValue == inValue)
	    	elements.push(child);
		return elements;
	});
}

document.getElementsByClassPrefix = function(classPrefix, parentElement) {
  var children = ($(parentElement) || document.body).getElementsByTagName('*');
  return $A(children).inject([], function(elements, child) {
    if (child.className.match(new RegExp("(^|\\s)" + classPrefix + "\\w*(\\s|$)")))
      elements.push(child);
    return elements;
  });
}

document.getElementsByIdPrefix = function(idPrefix, parentElement) {
  var children = ($(parentElement) || document.body).getElementsByTagName('*');
  return $A(children).inject([], function(elements, child) {								  
    if (child.id.match(new RegExp("(^|\\s)" + idPrefix + "\\w*(\\s|$)")))
      elements.push(child);
    return elements;
  });
}