Element.extend({
       setPosition: function(options){
               options = $merge({
                       relativeTo: document.body,
                       position: {
                               x: 'center', //left, center, right
                               y: 'center' //top, center, bottom
                       },
                       edge: false,
                       offset: {x:0,y:0},
                       returnPos: false,
                       relFixedPosition: false,
                       ignoreMargins: false,
                       overflown: []
               }, options);
               var parentOffset = {x: 0, y: 0};
               var parentPositioned = false;
               if(this.getParent() != document.body) {
                       var parent = this.getParent();
                       while(parent != document.body && parent.getStyle('position') == "static") {
                               parent = parent.getParent();
                       }
                       if(parent != document.body) {
                               parentOffset = parent.getPosition();
                               parentPositioned = true;
                       }
                       options.offset.x = options.offset.x - parentOffset.x;
                       options.offset.y = options.offset.y - parentOffset.y;
               }
               function fixValue(option) {
                       if($type(option) != "string") return option;
                       option = option.toLowerCase();
                       var val = {};
                       if(option.test('left')) val.x = 'left';
                       else if(option.test('right')) val.x = 'right';
                       else val.x = 'center';

                       if(option.test('upper')||option.test('top')) val.y = 'top';
                       else if (option.test('bottom')) val.y = 'bottom';
                       else val.y = 'center';
                       return val;
               };
               options.edge = fixValue(options.edge);
               options.position = fixValue(options.position);
               if(!options.edge) {
                       if(options.position.x == 'center' && options.position.y == 'center') options.edge = {x:'center',y:'center'};
                       else options.edge = {x:'left',y:'top'};
               }
               
               this.setStyle('position', 'absolute');
               var rel = $(options.relativeTo) || document.body;
               if (window.opera) {
     var top = (rel == document.body)?window.getScrollTop():rel.getTop();
     var left = (rel == document.body)?window.getScrollLeft():rel.getLeft();
   } else {
     var top = (rel == document.body)?window.getScrollTop():rel.getTop(options.overflown);
     var left = (rel == document.body)?window.getScrollLeft():rel.getLeft(options.overflown);
   }
               
               if (top < 0) top = 0;
   if (left < 0) left = 0;
               var dim = this.getDimensions({computeSize: true, styles:['padding', 'border','margin']});
               if (options.ignoreMargins) {
                       options.offset.x += ((options.edge && options.edge.x == "right")?dim['margin-right']:-dim['margin-left']);
                       options.offset.y += ((options.edge && options.edge.y == "bottom")?dim['margin-bottom']:-dim['margin-top']);
               }
               var pos = {};
               var prefY = options.offset.y.toInt();
               var prefX = options.offset.x.toInt();
               switch(options.position.x) {
                       case 'left':
                               pos.x = left + prefX;
                               break;
                       case 'right':
                               pos.x = left + prefX + rel.offsetWidth;
                               break;
                       default: //center
                               pos.x = left + (((rel == document.body)?window.getWidth():rel.offsetWidth)/2) + prefX;
                               break;
               };              
               switch(options.position.y) {
                       case 'top':
                               pos.y = top + prefY;
                               break;
                       case 'bottom':
                               pos.y = top + prefY + rel.offsetHeight;
                               break;
                       default: //center
                               pos.y = top + (((rel == document.body)?window.getHeight():rel.offsetHeight)/2) + prefY;
                               break;
               };
               
               if(options.edge){
                       var edgeOffset = {};
                       
                       switch(options.edge.x) {
                               case 'left':
                                       edgeOffset.x = 0;
                                       break;
                               case 'right':
                                       edgeOffset.x = -dim.x-dim.computedRight-dim.computedLeft;
                                       break;
                               default: //center
                                       edgeOffset.x = -(dim.x/2);
                                       break;
                       };
                       switch(options.edge.y) {
                               case 'top':
                                       edgeOffset.y = 0;
                                       break;
                               case 'bottom':
                                       edgeOffset.y = -dim.y-dim.computedTop-dim.computedBottom;
                                       break;
                               default: //center
                                       edgeOffset.y = -(dim.y/2);
                                       break;
                       };
                       pos.x = pos.x+edgeOffset.x;
                       pos.y = pos.y+edgeOffset.y;
               }
               pos = {
                       left: ((pos.x >= 0 || parentPositioned)?pos.x:0).toInt()+'px',
                       top: ((pos.y >= 0 || parentPositioned)?pos.y:0).toInt()+'px'
               };
               if(rel.getStyle('position') == "fixed"||options.relFixedPosition) {
                       pos.top = pos.top.toInt() + window.getScrollTop()+'px';
                       pos.left = pos.left.toInt() + window.getScrollLeft()+'px';
               }

               if(options.returnPos) return pos;
               if(options.smoothMove) new Fx.SmoothMove(this, options).start();
               else this.setStyles(pos);
               return this;
       }
});
