jQuery.fn.fixate = function(parameters){
	var $this = $(this);
	var defaults = {
		maxLeft	: null,
		minLeft	: (isNaN(parseInt($this.css('left'))) ? 0 : parseInt($this.css('left'))),
		maxTop	: null,
		minTop	: (isNaN(parseInt($this.css('top'))) ? 0 : parseInt($this.css('top')))
	};
	jQuery.extend(defaults, parameters);
	var priv = {
		oriTop	: 0,
		oriLeft	: 0,
		parentOffsetTop : 0,
		parentOffsetleft: 0,
		
		fixate	: function(){
			//bind the window events
			$(window).bind("scroll", function(evt){priv.windowScroll(evt);});
			$(window).bind("resize", function(evt){priv.windowResize(evt);});
			
			//make sure the parent has a relative or absolute position
			if($($this.parent()).css('position') != 'absolute'){
			   $($this.parent()).css('position', 'relative');
			}
						
			priv.oriTop += $this.get(0).offsetTop;
			priv.oriLeft += $this.get(0).offsetLeft;
			var currParent = $this.get(0).offsetParent;
			
			while(currParent){
			    priv.parentOffsetTop += currParent.offsetTop;
			    priv.parentOffsetLeft += currParent.offsetLeft;
			    
			    currParent = currParent.offsetParent;
			}
			
			priv.windowScroll();
			
		},
		
		windowScroll	: function(evt){
		    if($this.css('display') == 'block' && $this.height() > 15){
			    //add the scrollheight to the element top style
			    var thisHeight = ($this.height() ? $this.height() : 0);
			    var newTop = $('html').get(0).scrollTop - thisHeight;
    			
			    //test if we do not exeed the maxTop:
			    if(defaults.maxTop != null){
				    newTop = Math.min(newTop, defaults.maxTop - thisHeight);
			    }
			    
			    //overrule all above if the bottom of the element exeeds below the window
			    if(priv.parentOffsetTop + newTop + thisHeight > $(window).height() + $('html').get(0).scrollTop){
			        newTop =  newTop - Math.abs($(window).height() + $('html').get(0).scrollTop - (priv.parentOffsetTop + newTop + thisHeight));
			    }
			    //we may not have a smaller top value than we started with
			    newTop = Math.max(priv.oriTop, newTop);
    			
			    //test if we do not exeed the minTop:
			    if(defaults.minTop != null){
				    newTop = Math.max(newTop, defaults.minTop);
			    }
    			
    			/**
    			* not supported yet leftoffset
    			
			    var newLeft = priv.oriLeft + $('html').get(0).scrollLeft;
			    //test if we do not exeed the minLeft:
			    if(defaults.minLeft != null){
				    newLeft = Math.max(newLeft, defaults.minLeft);
			    }
			    //test if we do not exeed the maxleft:
			    if(defaults.maxLeft != null){
				    newLeft = Math.min(newLeft, defaults.maxLeft);
			    }
    			**/
			    $this.css({'position':'absolute', 'z-index': '99', 'top':newTop + 'px', 'left':0 + 'px'});
			}
		},
		
		windowResize	: function(evt){
			priv.windowScroll();
		}
	}
	
	return priv.fixate();
};