var Position = {
	includeScrollOffsets: false,
	prepare: function() {
	this.deltaX =  window.pageXOffset
	|| document.documentElement.scrollLeft
	|| document.body.scrollLeft
	|| 0;
	this.deltaY =  window.pageYOffset
	|| document.documentElement.scrollTop
	|| document.body.scrollTop
	|| 0;
	},
	
	realOffset: function(element) {
	var valueT = 0, valueL = 0;
	do {
	valueT += element.scrollTop  || 0;
	valueL += element.scrollLeft || 0;
	element = element.parentNode;
	} while (element);
	return [valueL, valueT];
	},
	
	cumulativeOffset: function(element) {
	var valueT = 0, valueL = 0;
	do {
	valueT += element.offsetTop  || 0;
	valueL += element.offsetLeft || 0;
	element = element.offsetParent;
	} while (element);
	return [valueL, valueT];
	},
	
	positionedOffset: function(element) {
		var valueT = 0, valueL = 0;
		do {
		valueT += element.offsetTop  || 0;
		valueL += element.offsetLeft || 0;
		element = element.offsetParent;
		if (element) {
		if(element.tagName=='BODY') break;
		var p = Element.getStyle(element, 'position');
		if (p == 'relative' || p == 'absolute') break;
		}
		} while (element);
		return [valueL, valueT];
	},
	
	offsetParent: function(element) {
	if (element.offsetParent) return element.offsetParent;
	if (element == document.body) return element;
	
	while ((element = element.parentNode) && element != document.body)
	if (Element.getStyle(element, 'position') != 'static')
	return element;
	
	return document.body;
	},
	
	// caches x/y coordinate pair to use with overlap
	within: function(element, x, y) {
	if (this.includeScrollOffsets)
	return this.withinIncludingScrolloffsets(element, x, y);
	this.xcomp = x;
	this.ycomp = y;
	this.offset = this.cumulativeOffset(element);
	
	return (y >= this.offset[1] &&
	y <  this.offset[1] + element.offsetHeight &&
	x >= this.offset[0] &&
	x <  this.offset[0] + element.offsetWidth);
	},
	
	withinIncludingScrolloffsets: function(element, x, y) {
	var offsetcache = this.realOffset(element);
	
	this.xcomp = x + offsetcache[0] - this.deltaX;
	this.ycomp = y + offsetcache[1] - this.deltaY;
	this.offset = this.cumulativeOffset(element);
	
	return (this.ycomp >= this.offset[1] &&
	this.ycomp <  this.offset[1] + element.offsetHeight &&
	this.xcomp >= this.offset[0] &&
	this.xcomp <  this.offset[0] + element.offsetWidth);
	},
	
	// within must be called directly before
	overlap: function(mode, element) {
	if (!mode) return 0;
	if (mode == 'vertical')
	return ((this.offset[1] + element.offsetHeight) - this.ycomp) /
	element.offsetHeight;
	if (mode == 'horizontal')
	return ((this.offset[0] + element.offsetWidth) - this.xcomp) /
	element.offsetWidth;
	},
	
	page: function(forElement) {
	var valueT = 0, valueL = 0;
	
	var element = forElement;
	do {
	valueT += element.offsetTop  || 0;
	valueL += element.offsetLeft || 0;
	
	// Safari fix
	if (element.offsetParent == document.body)
	if (Element.getStyle(element,'position')=='absolute') break;
	
	} while (element = element.offsetParent);
	
	element = forElement;
	do {
	if (!window.opera || element.tagName=='BODY') {
	valueT -= element.scrollTop  || 0;
	valueL -= element.scrollLeft || 0;
	}
	} while (element = element.parentNode);
	
	return [valueL, valueT];
	},
	
	clone: function(source, target) {
		var options = Object.extend({
		setLeft:	true,
		setTop:	 true,
		setWidth:   true,
		setHeight:  true,
		offsetTop:  0,
		offsetLeft: 0
		}, arguments[2] || {})
	
		// find page position of source
		source = $(source);
		var p = Position.page(source);
		
		// find coordinate system to use
		target = $(target);
		var delta = [0, 0];
		var parent = null;
		// delta [0,0] will do fine with position: fixed elements,
		// position:absolute needs offsetParent deltas
		if (Element.getStyle(target,'position') == 'absolute') {
		parent = Position.offsetParent(target);
		delta = Position.page(parent);
		}
		
		// correct by body offsets (fixes Safari)
		if (parent == document.body) {
		delta[0] -= document.body.offsetLeft;
		delta[1] -= document.body.offsetTop;
		}
		
		// set position
		if(options.setLeft)   target.style.left  = (p[0] - delta[0] + options.offsetLeft) + 'px';
		if(options.setTop)	target.style.top   = (p[1] - delta[1] + options.offsetTop) + 'px';
		if(options.setWidth)  target.style.width = source.offsetWidth + 'px';
		if(options.setHeight) target.style.height = source.offsetHeight + 'px';
	},
	
	absolutize: function(element) {
		element = $(element);
		if (element.style.position == 'absolute') return;
		Position.prepare();
		
		var offsets = Position.positionedOffset(element);
		var top	 = offsets[1];
		var left	= offsets[0];
		var width   = element.clientWidth;
		var height  = element.clientHeight;
		
		element._originalLeft   = left - parseFloat(element.style.left  || 0);
		element._originalTop	= top  - parseFloat(element.style.top || 0);
		element._originalWidth  = element.style.width;
		element._originalHeight = element.style.height;
		
		element.style.position = 'absolute';
		element.style.top	= top + 'px';
		element.style.left   = left + 'px';
		element.style.width  = width + 'px';
		element.style.height = height + 'px';
		},
		
		relativize: function(element) {
		element = $(element);
		if (element.style.position == 'relative') return;
		Position.prepare();
		
		element.style.position = 'relative';
		var top  = parseFloat(element.style.top  || 0) - (element._originalTop || 0);
		var left = parseFloat(element.style.left || 0) - (element._originalLeft || 0);
		
		element.style.top	= top + 'px';
		element.style.left   = left + 'px';
		element.style.height = element._originalHeight;
		element.style.width  = element._originalWidth;
	}
} ;


