/*	Script: element.position.js
Extends the <Element> object.

Dependancies:
	 mootools - <Moo.js>, <String.js>, <Array.js>, <Function.js>, <Element.js>, <Dom.js>
	 cnet - <element.dimensions.js>

Author:
	Aaron Newton, <aaron [dot] newton [at] cnet [dot] com>
	
Class: Element
		This extends the <Element> prototype.
	*/
Element.extend({
/*	Property: setPosition
		Sets the location of an element relative to another (defaults to the document body).
		
		Note:
		The element must be absolutely positioned (if it isn't, this method will set it to be);
		
		Arguments:
		options - a key/value object with options
		
		Options:
		relativeTo - (element) the element relative to which to position this one; defaults to document.body.
		position - (string) the aspect of the relativeTo element that this element should be positioned. Options are 'upperRight', 'upperLeft', 'bottomLeft', 'bottomRight', and 'center' (the default). With the exception of center, all other options will make the upper right corner of the positioned element = the specified corner of the relativeTo element. 'center' will make the center point of the positioned element = the center point of the relativeTo element.
		edge - (string; optional) the edge of the element to set relative to the relative elements corner; this way you can specify to position this element's upper right corner to the bottom left corner of the relative element. this is optional; the default behavior positions the element's upper left corner to the relative element unless position == center, in which case it positions the center of the element to the center of the relative element.
		offset - (object) x/y coordinates for the offset (i.e. {x: 10, y:100} will move it down 100 and to the right 10). Negative values are allowed.
		smoothMove - (boolean) move the element to the new position using <Fx.Styles>; defaults to false.
		effectOptions - (object) options object for <Fx.Styles>, optional
		returnPos - (boolean) don't move the element, but instead just return the position object ({top: '#', left: '#'}); defaults to false

	*/
	setPosition: function(options){
		options = $merge({
			relativeTo: document.body,
			position: 'center',
			edge: false,
			offset: {x:0,y:0},
			smoothMove: false,
			effectOptions: {},
			returnPos: false
		}, options);
		this.setStyle('position', 'absolute');
		var rel = $(options.relativeTo) || document.body;
		var top = (rel == document.body)?window.getScrollTop():rel.getTop();
		if (top < 0) top = 0;
		var left = (rel == document.body)?window.getScrollLeft():rel.getLeft();
		if (left < 0) left = 0;
		var dim = this.getDimensions({computeSize: true});
		var pos;
		var prefY = options.offset.y.toInt();
		var prefX = options.offset.x.toInt();
		switch(options.position) {
			case 'upperLeft':
				pos = {
					x:(left + prefX),
					y:(top + prefY)
				};
				break;
			case 'upperRight':
				pos = {
					x:(left + prefX + rel.offsetWidth),
					y:(top + prefY)
				};
				break;
			case 'bottomLeft':
				pos = {
					x:(left + prefX),
					y:(top + prefY + rel.offsetHeight)
				};
				break;
			case 'bottomRight':
				pos = {
					y:(left + prefX + rel.offsetWidth),
					x:(top + prefY + rel.offsetHeight)
				};
				break;
			default: //center
				pos = {
					x: left + (((rel == document.body)?window.getWidth():rel.offsetWidth)/2) + prefX,
					y: top + (((rel == document.body)?window.getHeight():rel.offsetHeight)/2) + prefY
				};
				options.edge = "center";
				break;
		}
		if(options.edge){
			var edgeOffset;
			switch(options.edge){
				case 'upperLeft':
					edgeOffset = {
						x: 0,
						y: 0
					};
					break;
				case 'upperRight':
					edgeOffset = {
						x: -dim.x-dim.computedRight-dim.computedLeft,
						y: 0
					};
					break;
				case 'bottomLeft':
					edgeOffset = {
						x: 0,
						y: -dim.y-dim.computedTop-dim.computedBottom
					};
					break;
				case 'bottomRight':
					edgeOffset = {
						x: -dim.x-dim.computedRight-dim.computedLeft,
						y: -dim.y-dim.computedTop-dim.computedBottom
					};
					break;
				default: //center
					edgeOffset = {
						x: -(dim.x/2),
						y: -(dim.y/2)
					};
					break;
			}
			pos.x = pos.x+edgeOffset.x;
			pos.y = pos.y+edgeOffset.y;
		}
		pos = {
			left: ((pos.x >= 0)?pos.x:0).toInt()+'px',
			top: ((pos.y >= 0)?pos.y:0).toInt()+'px'
		};
		if(options.returnPos) return pos;
		if(options.smoothMove && this.effects) this.effects(options.effectOptions).start(pos);
		else this.setStyles(pos);
		return this;
	}
});
/* do not edit below this line */   
/* Section: Change Log 

$Source: /cvs/main/flatfile/html/rb/js/global/cnet.global.framework/mootools.extended/Native/element.position.js,v $
$Log: element.position.js,v $
Revision 1.3  2007/05/30 20:32:33  newtona
doc updates

Revision 1.2  2007/05/29 22:01:53  newtona
Split element.cnet.js into seperate files; updated docs in files to note this
Changed element.visible to element.isVisible (left old namespace for legacy support)
Fixed Element.empty in prototype.compatibility.js
Removed as many dependencies in common code to element.*.js as possible (espeically element.shortcuts.js)

Revision 1.1  2007/05/29 21:25:31  newtona
splitting up element.cnet.js (which had grown to be too unweildy); moving things into sub-directories


*/
