//2009-04-21
(function($){

$.fn.extend({
	/**
	 * Turns (el) into a popup.
	 * @param {Object} options
	 */
	popup : function(opts){
		var options = (typeof opts=='string') ? opts.toLowerCase() : $.extend({
			autoScroll: false,
			center: true,
			overlay: true,
			shadow: true,
			draggable:false,
			closeButton:true
		}, opts);
		return this.each(function(){
			var box = this;
			
			if(typeof options == 'string' && box.containerPopup) switch (options){
				case 'focus':
					box.containerPopup.focus();
					return;
				case 'show' :
				case 'open'	:
					box.containerPopup.show();
					return;
				case 'hide'	:
				case 'close':
					box.containerPopup.hide();
					return;
			};
			
			if(box.containerPopup) return;
			
			var el = $('<div>').css('position','absolute').addClass('jquery-popup').insertBefore(box).append(box)[0];
			$(box).addClass('jquery-popup-body').show().get(0).containerPopup = el;
			el.originalBox = box;
			$.popups.push(el);
			$el = $(el);

			el.options = options;
			box.options = options;
			
			if(options.renderIn) $el.prependTo(options.renderIn);
			if(options.width) $el.width(options.width);
			else if($el.css('width')!='auto'){
				$el.css('width',$(box).css('width'));
				$(box).css('width','auto');
			}
			
			if(options.height) $(box).height(options.height);
			
			if(!options.title && $(box).attr('title')) options.title = $(box).attr('title');
			if(options.title || options.closeButton){
				var titleDiv = $("<div>").prependTo(el).addClass('ui-popup-titlebar').addClass('clearFix');
				var titleText = $("<div>").addClass('ui-popup-title').appendTo(titleDiv);
				titleText.html(options.title ? options.title : '&nbsp;');
				titleDiv.css('opacity',.7);
				
				el.titleDiv = titleDiv[0];
				el.titleText = titleText[0];
				
				if (options.closeButton)
					$('<a href="#" />')
					.text('x')
					.addClass('ui-popup-titlebar-close')
					.appendTo(titleDiv)
					.click(function(){
							$(this.popupBox).popup('hide');
							return false;
						})[0].popupBox = box;
				
				$el.bind('mouseover',function(){
					if(this.over)return false;
					this.over = true;
					$(this.titleDiv).stop().fadeTo(200, .8);
				});
				$el.bind('mouseout',function(e){
					if(!$(this).isTrueMouseOut(e))return false;
					this.over = false;
					$(this.titleDiv).stop().fadeTo(200, .7);
				});
			};
			
			for(o in options){
				if(!options[o])continue;
				switch(o){
					case 'draggable':
						if(!$el.draggable)break;
						$el.draggable({
							handle : el.titleDiv ? el.titleDiv : false,
							scroll: true,
							drag : function(){
								if(this.options.shadow) this.shadow.show();
								if($.browser.msie && $.browser.version<7) this.iframe.show();
							},
							stop : function(){
								if(this.options.shadow) this.shadow.show();
								if($.browser.msie && $.browser.version<7) this.iframe.show();
							}
						});
						break;
					case 'onShow':
						$el.bind('show', options[o]);
						break;
					case 'onHide':
						$el.bind('hide', options[o]);
						break;
					case 'resizable':
						$el.resizable({
							handles: 'all',
							autoHide: true,
							resize: function(){
								if($(this).css('overflow')=='visible') $(this).css('overflow','hidden');
								var titleDivHeight = this.titleDiv ? $(this.titleDiv).outerHeight() : 0;
								var newHeight = 
									$(this).height()
									- parseInt($(this.originalBox).css('padding-top'),10)
									- parseInt($(this.originalBox).css('padding-bottom'),10)
									- titleDivHeight;
								$(this.originalBox).height(newHeight);
								if (this.options.shadow) this.shadow.show();
								if ($.browser.msie && this.iframe && $.browser.version<7) this.iframe.show();
							},
							stop: function(){
								var titleDivHeight = this.titleDiv ? $(this.titleDiv).outerHeight() : 0;
								var newHeight = 
									$(this).height()
									- parseInt($(this.originalBox).css('padding-top'),10)
									- parseInt($(this.originalBox).css('padding-bottom'),10)
									- titleDivHeight;
								$(this.originalBox).height(newHeight);
								if (this.options.shadow) this.shadow.show();
								if ($.browser.msie && this.iframe && $.browser.version<7) this.iframe.show();
							}
						});
						$(".ui-resizable-s, .ui-resizable-se, .ui-resizable-sw",el).each(function(){
							this.popup = el;
						}).bind('dblclick',function(){
							var popup = this.popup;
							$([popup,popup.originalBox]).css('height','auto');
							if (popup.options.shadow) popup.shadow.show();
							if ($.browser.msie && $.browser.version<7) popup.iframe.show();
						});
						break;
					case 'shadow':		$el.shadow();		break;
					case 'overlay':		$el.overlay();	break;
				};
			};
			
			if ($.browser.msie && $.browser.version<7) $el.iframe();
			
			$.extend(el,{
				scrollers:$('.scrollArea',el),
				show : function(noEvent){
					if (this.visible){
						this.refresh();
						return false;
					};
					$this = $(this);
					if(!noEvent)
						$this.triggerHandler('beforeShow');
					if (this.options.hidePopups) $.hidePopups();
					this.visible = true;
					$this.show();
					if (this.options.center) $(this).center();
					this.refresh();
					if(!noEvent)
						$this.triggerHandler('show');
					if(this.options.autoFocus)this.focus();
				},
				hide : function(){
					if (this.visible === false) return false;
					$this = $(this);
					$this.triggerHandler('beforeHide');
					this.visible = false;
					if (this.originalBox.triggerEl) {
						this.originalBox.triggerEl.stuck = false;
						this.originalBox.triggerEl.hovering = false;
					};
					if (this.shadow) this.shadow.hide();
					if (this.overlay) this.overlay.hide();
					if ($.browser.msie && $.browser.version<7) this.iframe.hide();
					$this.triggerHandler('hide');
					$this.hide();
				},
				focus : function(){
					var zIndex = 0;
					var el = this;
					$($.popups).each(function(){
						if(!this.visible || this == el)return;
						zIndex = Math.max(zIndex,$(this).css('z-index'));
					});
					$(this).css('zIndex',zIndex +3);
					this.refresh();
					$this.triggerHandler('focus');
				},
				refresh : function(){
					//if (this.options.center) $(this).center();
					if (this.titleText) $(this.titleText).html($(this.originalBox).attr('title'));
					if (this.options.autoScroll) this.scrollers.autoScroll(this.options);
					if (this.options.shadow) this.shadow.show();
					if ($.browser.msie && $.browser.version<7) this.iframe.show();
					if (this.options.overlay) this.overlay.show();
					$this.triggerHandler('refresh');
				}
			});
			if ($el.hasClass('scrollArea')) el.scrollers.push(el);
			
			el.show(true);
			el.hide();
			
			el = null;
		});
	},
	
	/**
	 * Keeps an element from exceeding a certain height and width. Options can be
	 * {
	 * 		maxHeight : maximum allowed height (Int)
	 * 		fromBottom : minumum allowed distance from bottom of screen (Int)
	 * 		maxWidth : maximum allowed width (Int)
	 * 		fromRight : minumum allowed distance from right side of screen (Int)
	 * }
	 * @param {Object} options
	 */
	autoSize : function(options){
		return this.each(function(){
			var position = $(this).offset();
			if(options.fromRight || options.maxWidth){
				$(this).css({'width':'auto','overflowX':'hidden'});
				var size = $(this).outerWidth();
				if (options.fromRight) {
					var viewPortWidth = $(window).width();
					var rightX = position.left + size + options.fromRight;
					if (rightX > viewPortWidth + $(window).scrollLeft()) {
						var newWidth = size - (rightX - viewPortWidth);
						if (newWidth <= 60) newWidth = 60;
						$(this).width(newWidth);
					};
				};
				if(options.maxWidth && size > options.maxWidth) $(this).width(options.maxWidth);
			};
			if(options.fromBottom || options.maxHeight){
				$(this).css({'height':'auto','overflowY':'hidden'});
				var size = $(this).outerHeight();	
				if (options.fromBottom) {
					var viewPortHeight = $(window).height();
					var bottomY = position.top + size + options.fromBottom;
					if (bottomY > viewPortHeight + $(window).scrollTop()) {
						var newHeight = size - (bottomY - viewPortHeight);
						if (newHeight <= 60) newHeight = 60;
						$(this).height(newHeight);
					};
				};
				if(options.maxHeight && size > options.maxHeight) $(this).height(options.maxHeight);
			};
		});
	},
	
	/**
	 * Sets up element to auto scroll while moving mouse across it.  Scrolling will not
	 * occur unless element is tall enough to be be less than (fromBottom) from the
	 * bottom of the window. Options can be
	 * {
	 * 		width : set to true to autoscroll left and right
	 * 		height : set to true to autoscroll up and down
	 * 		fromEdge : distance from edge of element
	 * }
	 * This funtion calls autoSize(), so you can also pass autoSize parameters in the options.
	 * 
	 * @param {Object} options
	 */
	autoScroll : function(options, event){
		return this.each(function(){
			if(typeof options == 'string' && event){
				var orient = options;
				var direction = orient == "Height" ? 'Top' : 'Left';
				var size = $(this)['outer' + orient ]();
				var scrollSize = this['scroll' + orient];
				
				if(scrollSize <= size)return;
				
				var fromEdge = this.scrollOptions.fromEdge || this.scrollOptions.fromEdge===0 ? this.scrollOptions.fromEdge : 30;
				
				var mousePos = findMouse(event)[orient=="Height" ? 1 : 0];
				var elEdge = $(this).offset()[direction.toLowerCase()] + fromEdge;
				
				var adjustedSize = size - (fromEdge*2);
				
				var mousePosOnDiv = mousePos-elEdge;
				var percentScroll = Math.max(Math.min(mousePosOnDiv/adjustedSize,1),0);
				
				$(this)['scroll' + direction](Math.round((scrollSize-size) * percentScroll));
				return;
			};
			
			if(options.fromRight || options.maxWidth) options.width = true;
			if (options.fromBottom || options.maxHeight) options.height = true;
			
			this.scrollOptions = options;
			
			if(!this.scrollSet)
				$(this).bind('mousemove',function(e){
					if(this.scrollOptions.height)
						$(this).autoScroll("Height", e);
					if(this.scrollOptions.width)
						$(this).autoScroll("Width", e);
				});
			
			this.scrollSet = true;
			
			//Ensures that scroll occurs even when browsers are
			//stupid and think mousing over a link in an element
			//is mousing out of the element
			var el = this;
			$('*', this).each(function(){
				if (this.autoScrollParent) return;
				this.autoScrollParent = el;
				$(this).bind('mousemove', function(e){
					if(this.autoScrollParent.onmousemove)
						this.autoScrollParent.onmousemove(e);
				});
			});
			
			$(this).autoSize(options);
		});
	},
	
	/**
	 * Scrolls container by dragging on it with mouse.  Similar
	 * to google maps.
	 */
	dragScroll : function(){
		return this.each(function(){
			el = this;
			$el = $(el);
			$el.css('cursor', 'move');
			$el.css('position', 'relative');
			$el.bind('mousedown', function(e){
				$(this).bind('mousemove', function(e){
					var newPos = findMouse(e);
					var adjLeft = newPos[0] - this.startPos[0];
					var adjTop = newPos[1] - this.startPos[1];
					var newScrollLeft = Math.max(this.startScroll.left - adjLeft, 0);
					var newScrollTop = Math.max(this.startScroll.top - adjTop, 0);
					$(this).scrollLeft(newScrollLeft);
					$(this).scrollTop(newScrollTop);
					
					this.startPos = newPos;
					this.startScroll = {
						left: newScrollLeft,
						top: newScrollTop
					};
					
					this.eventsCleared = false;
					
					stopEventPropagation(e);
					e.preventDefault();
					return false;
				});
				
				this.startPos = findMouse(e);
				this.startScroll = {
					left: $(this).scrollLeft(),
					top: $(this).scrollTop()
				};
				
				if (this.dragEventSet) return false;
				this.dragEventSet = true;
				
				this.clearEvents = function(e){
					if (this.eventsCleared) 
						return false;
					this.eventsCleared = true;
					$(this).unbind('mousemove');
					if (this.endDrag) 
						this.endDrag();
				};
				$(this).bind('click', function(e){
					this.clearEvents(e);
				});
				$(this).bind('mouseup', function(e){
					this.clearEvents(e);
				});
				$(this).bind('mouseout', function(e){
					if (!$(this).isTrueMouseOut(e)) 
						return false;
					this.clearEvents(e);
				});
				
				stopEventPropagation(e);
				e.preventDefault();
				return false;
			});
		});
	},
	
	/**
	 * Turns the matched elements into dropdown menus
	 * @param {Object} opts
	 */
	menu : function(opts){
		var options = $.extend({
			shadow : true,
			hidePopups : false,
			hideMenus : true,
			center : false,
			fromBottom : 10,
			autoScroll : true,
			fromEdge : 30,
			resizable : false,
			clickOff : true,
			overlay : false,
			closeButton : false,
			selectable : true
		}, opts);
		
		return this.popup(options).each(function(){
			var el = this;
			if (el.isMenu) return;
			
			$.menus.push(el);
			
			el.isMenu = true;
			var triggerEl = options.triggerEl ? options.triggerEl : el.containerPopup.parentNode;
			triggerEl.hoverTarget = el;
			el.triggerEl = triggerEl;
			
			if(options.clickOff || options.clickStick){
				$(triggerEl).bind('click',function(e){
					if (this.hoverTarget.containerPopup.options.hideMenus)
						$.hideMenus({hideStuck:true, ignore : this.hoverTarget});
					
					if (this.hoverTarget.containerPopup.options.clickStick) {
						//$(this.triggerEl).css('z-index',9999);
						this.stuck = true;
					};
					if(this.hovering) stopEventPropagation(e);
				});
				$(el).bind('click',function(e){
					if (this.containerPopup.options.clickStick) {
						//$(this.triggerEl).css('z-index',9999;
						this.triggerEl.stuck = true;
					};
					if(this.triggerEl.hovering) stopEventPropagation(e);
				});
				if (options.clickOff) {
					$(document).bind('click', {popup: el.containerPopup}, function(e){
						var popup = e.data.popup;
						if (!popup.originalBox.triggerEl.hovering) {
							popup.hide();
							//$(popup.originalBox.triggerEl).css('z-index',1);
						};
					});
				};
			};
			
			$(triggerEl).bind('mouseover',function(){
				if(this.hovering) return;
				this.hovering = true;
				if(this.hoverTarget.containerPopup.visible 
					&& $(this.hoverTarget.containerPopup).css('display')!='none') return;
				
				if (this.hoverTarget.containerPopup.options.hideMenus)
					$.hideMenus({ignore : this.hoverTarget});
				
				$(this).oneTime(90,function(){
					if(!this.hovering) return false;
					$(this).css({'z-index':999,'position':'relative'});
	
					//if($.browser.safari && $(this.parentNode).css('position')=='static') $(this).css('position','static');
						
					var offset = $(this).offset();
					offset.top += $(this).outerHeight();
					
					$(this.hoverTarget.containerPopup).offset(offset);
					$(this.hoverTarget).popup('show');
				});
			});
			$(triggerEl).bind('mouseout',function(e){
				if(!$(this).isTrueMouseOut(e)) return false;
				if(!this.hovering) return;
				this.hovering = false;
				if(this.stuck) return;
				if(!this.hoverTarget.containerPopup.visible 
					&& $(this.hoverTarget.containerPopup).css('display')=='none') return;
				
				$(this).oneTime(300,function(){
					if(this.hovering) return false;
					$(this).css({'position':'static'});
					$(this.hoverTarget).popup('hide');
				});
			});
			
			if (!options.selectable)
				$(el).add(triggerEl).disableSelection().attr('unselectable','on');
			
			el = null;
		});
	},
	
	/**
	 * Replaced a Select element with a popup menu
	 */
	selectMenu : function(){
		var refreshItems = function(){
			var list = this.list;
			var label = this.label;
			var dropDown = this;
			$(list).html('');
			
			var clickFunction = function(){
				$(this.dropDown.menuDiv).popup('hide');
				
				var selectBox = this.dropDown.select;
				var oldLabel = this.dropDown.label.innerHTML;
				var oldValue = selectBox.value;
				
				selectBox.value = $(this).attr('value');
				
				if ($(selectBox).change() === false) {
					selectBox.value = oldValue;
					return false;
				};

				$(this.dropDown.label).html($(this).html());
				return false;
			};
			
			$('option', this.select).each(function(x){
				var option = this;
				if (x == 0)$(label).html($(option).html());
				var subItem = $('<li>')[0];
				subItem.option = option;
				subItem.dropDown = dropDown;
				option.listItem = subItem;
				var link = $('<a />').addClass('menuLink')[0];
				$(link).attr('value',$(option).attr('value')).attr('href','#');
				$(link).text($(option).html()).appendTo(subItem);
				link.dropDown = dropDown;
				$(subItem).appendTo(list);
				$(link).click(clickFunction);
				$(link).mouseup(clickFunction);
				if (option.selected) $(label).html($(link).html());
			});
		};
		
		return this.each(function(){
			var select = this;
			if (select.tagName.toLowerCase() != 'select') return;
			
			if (select.dropDown) {
				select.dropDown.refresh();
				return;
			};
			$(select).hide();
			
			var mainUL = $('<ul>').css('display','inline').addClass("mainMenu")[0];
			
			var mainItem = $('<li>').addClass("mainItem").appendTo(mainUL)[0];
			var label = $('<span />').addClass('dropDownCurrentSelection').appendTo(mainItem)[0];
			var menuDiv = $('<div>').addClass('menu').appendTo(mainItem)[0];
			var subUL = $('<ul>').addClass('scrollArea').appendTo(menuDiv)[0];
			
			$(mainUL).insertBefore(select);
			
			$.extend(mainUL,{
				label : label,
				list : subUL,
				select : select,
				menuDiv : menuDiv,
				refresh : refreshItems
			});

			subUL.dropDown = mainUL;
			select.dropDown = mainUL;
			
			var settings = {
				shadow : true,
				autoScroll : true,
				fromBottom : 50,
//				maxHeight : 300,
				hidePopups : false,
				hideMenus : true,
				clickOff : true,
				clickStick : true,
				selectable : false
			};
			if ($(select).attr('hideMenus') == 'false') settings.hideMenus = false;
			$(menuDiv).menu(settings);
			
			mainUL.refresh();
			subUL = null;
			select = null;
			mainUL = null;
		});
	},

	/**
	 * Creates a semi-transparent black div the size of (el) behind each matched
	 * element
	 */
	shadow : function(){
		return this.each(function(){
			var el = this;
			if (el.shadow) return;
			
			var shadow = $('<span />').addClass('ui-popup-shadow').insertBefore(el)[0];
			
			$(shadow).css({
			//	'background-color':'#000',
				'position':'absolute'
			//	'opacity': .4
			});
			
			shadow.el = el;
			el.shadow = shadow;
			
			$.extend(shadow,{
				show : function(){
					var el = this.el;
					$(this).show();
					$(this).height($(el).outerHeight()+3);
					$(this).width($(el).outerWidth()+3);
					var offset = $(el).offset();
					offset.left += 1;
					offset.top += 1;
					$(this).offset(offset);
					if(!isNaN($(el).css('z-index')))
						$(this).css('z-index',$(el).css('z-index')-1);
				},
				hide : function(){
					$(this).hide();
				}
			});

			shadow.hide();
			shadow = null;
			el = null;
		});
	},

	/**
	 * Inserts a semi-transparent div the size of the window behind each
	 * matched element
	 */
	overlay : function(){
		return this.each(function(){
			var el = this;
			var overlay = $('<span />').insertBefore(el)[0];
			el.overlay = overlay;
			$(overlay).css({
				'opacity' : .4,
				'position' : 'absolute',
				'background-color' : 'black'
			});
			
			overlay.el = el;
			
			$.extend(overlay,{
				hide : function(){
					$(this).hide();
				},
				show : function(){
					$(this).show();
					$(this).height(Math.max($(window).height(),$(document).height()));
					$(this).width(Math.max($(window).width(),$('body').width()));
					$(this).offset({left:0,top:0});
					$(this).css('z-index',$(this.el).css('z-index')-2);
				}
			});
			
			overlay.hide();
			overlay = null;
			el = null;
		});
	},

	/**
	 * IE Hack.  Inserts an invisible iframe behind each matched
	 * element.
	 */
	iframe : function(){
		return this.each(function(){
			var el = this;
			var iframe = document.createElement('iframe');
			iframe.el = el;
			
			$(iframe).css({
				'display' : 'block',
				'position' : 'absolute',
				'border-width' : '0px',
				'opacity' : 0
			});
			
			iframe.setAttribute('frameborder', 'no');
			iframe.setAttribute('allowtransparency', 'true');
			iframe.setAttribute('border', '0');
			
			$(iframe).hide().insertBefore(el);
			el.iframe = iframe;
			
			$.extend(iframe,{
				hide : function(){
					$(this).hide();
				},
				show : function(){
					var el = this.el;
					
					$(this).show();
					if (el.overlay) {
						$(this).offset({left:0,top:0});
						$(this).height($(document).scrollTop() + $(window).height());
						$(this).width($(window).width())
					}
					else {
						$(this).offset($(el).offset());
						$(this).height($(el).height());
						$(this).width($(el).width());
					};
					$(this).css('z-index',$(el).css('z-index')-3);
				}
			});
			
			iframe.hide();
			iframe = null;
			el = null;
		});
	},

	/**
	 * Adds a label to an input that disappears on focus.  Pass a string selector, or an element.  If label
	 * is empty and there is a 'label' attribute on this, a label will be created with the 'label' attribute's
	 * value.  If none of those options apply and there is a <label> tag on the page with an id that matches 
	 * the id of this, then that label element will be used.
	 * @param {Mixed} label
	 */
	labelOver : function(label){
		if (label) {
			var $labelEl = $(label);
			var labelEl = $labelEl.get(0);
		}
		return this.each(function(){
			$this = $(this);
			
			if(!labelEl && $this.attr('label'))
				$labelEl = $('<label />').css('color','#888').text($this.attr('label'));
			
			else if(!labelEl && $this.attr('id'))
				$labelEl = $('[for='+$this.attr('id')+']');
			
			var marginTop = (1 + parseInt($this.css('border-top-width'),10) + parseInt($this.css('padding-top'),10)) + 'px';
			$labelEl
				.css({
					'display' : 'block',
					'position': 'absolute',
					'cursor' : 'text',
					'padding-top' : marginTop,
					'font' : $this.css('font'),
					'text-align' : $this.css('text-align'),
					'overflow' : 'hidden'
				})
				.insertBefore(this)
				.hide()
				.click(function(){
					this.labelFor.focus();
				});
			
			labelEl = $labelEl.get(0)
			if(!labelEl)return;
			
			var done = false;
			if(this.labelEl) done = true;
			
			$.extend(this,{
				'labelEl' : labelEl
			});
			$.extend(labelEl,{
				'labelFor' : this
			});
			
			if(done) return;
			
			$this
				.addClass('labelTarget')
				.bind('blur', function(){
					if(this.value)return;
					$(this.labelEl).show()
					if(this.offsetWidth)
						$(this.labelEl).width($(this).width());
				})
				.bind('focus', function(){
					$(this.labelEl).hide();
				});
			var $popup = $(this).closest('.jquery-popup');
			if($popup.length){
				$popup.bind('show',function(){
					$('.labelTarget', this).blur();
				});
			}
			$this.blur();
		});
	},

	/**
	 * Centers (el) in the window
	 */
	center : function(){
		return this.each(function(){
			var t = $(window).scrollTop() + ($(window).height() / 2) - ($(this).outerHeight() / 2);
			var l = $(window).scrollLeft() + ($(window).width() / 2) - ($(this).outerWidth() / 2);
			$(this).offset({left:l,top:t});
		});
	},

	/**
	 * Stores the original version of offset(), so that we don't lose it
	 */
	_offset : $.fn.offset,
	
	/**
	 * Set or get the specific left and top position of the matched
	 * elements, relative the the browser window by calling setXY
	 * @param {Object} newOffset
	 */
	offset : function(newOffset){
	    return !newOffset ? this._offset() : this.each(function(){
			var el = this;
			
			var hide = false;
			
			if($(el).css('display')=='none'){
				hide = true;
				$(el).show();
			};
			
			var style_pos = $(el).css('position');
			
			// default to relative
			if (style_pos == 'static') {
				$(el).css('position','relative');
				style_pos = 'relative';
			};
			
			var offset = $(el).offset();
			
			if (offset){
				var delta = {
					left : parseInt($(el).css('left'), 10),
					top: parseInt($(el).css('top'), 10)
				};
				
				// in case of 'auto'
				if (isNaN(delta.left)) 
					delta.left = (style_pos == 'relative') ? 0 : el.offsetLeft;
				if (isNaN(delta.top))
					delta.top = (style_pos == 'relative') ? 0 : el.offsetTop;
				
				if (newOffset.left || newOffset.left===0)
					$(el).css('left',newOffset.left - offset.left + delta.left + 'px');
			
				if (newOffset.top || newOffset.top===0)
					$(el).css('top',newOffset.top - offset.top + delta.top + 'px');
			};
			if(hide) $(el).hide();
		});
	},

	/**
	 * Pass in a mouseout event and this function will return true 
	 * if the mouse actually left the first matched element (checks if
	 * event occurred in an element contained by the first matched element).
	 * @param {Event} event
	 */
	isTrueMouseOut : function(event){
		el = this[0];
		if(!el)return true;
		try{
			if (!event) var event = window.event;
			var relTarg = event.relatedTarget || event.toElement;
			if($(el).contains(relTarg))return false;
		}
		catch(err){};
		return true;
	},
	
	/**
	 * Returns true if the first matched element contains element c
	 * @param {Element} c
	 */
	contains: function(c){
		var p = this[0];
		var c = $(c).get(0);
		if (!p || !c) return false;
		
		if (p.contains && !$.browser.safari) return p.contains(c);
		else {
			if (p.compareDocumentPosition) return !!(p.compareDocumentPosition(c) & 16);
			else {
				var parent = c.parentNode;
				while (parent) {
					if (parent == p) return true;
					else if (!parent.tagName || parent.tagName.toUpperCase() == "HTML") return false;
					parent = parent.parentNode;
				};
				return false;
			}
		};
	},
	
	/**
	 * Attempts to prevent user from selecting text
	 */
	disableSelection : function(){
		return this.each(function(){
			if (typeof this.onselectstart != "undefined") //IE route
				this.onselectstart = function(){return false};
			else if (typeof this.style.MozUserSelect != "undefined") //Firefox route
				this.style.MozUserSelect = "none";
			else //All other route (ie: Opera)
 				this.onmousedown = function(){return false};
			this.style.cursor = "default";
		});
	}
});

$.extend({
	popups : [],
	
	scales : [],
	
	menus : [],
	
	hidePopups : function(){
		$(this.popups).each(function(){
			this.hide();
		});
	},
	
	hideMenus : function(options){
		$($.menus).each(function(){
			if(!options || options.ignore==this )
				return;
			$(this.triggerEl).css({'position':'static'});
			$(this).popup('hide');
		});
	}
});

$(window).bind('unload',function(){
	$($.popups).each(function(){
		this.options = null;
		this.titleDiv = null;
		this.titleText = null;
		this.options = null;
		this.shadow = null;
		this.iframe = null;
		this.overlay = null;
		this.scrollers = null;
		this.originalBox = null;
	});
	$($.scales).each(function(){
		this.container = null;
		this.scale = null;
		this.min = null;
		this.max = null;
		this.track = null;
		this.handle = null;
		this.clearValButton = null;
	});
});

})(jQuery);

function getTime(){
	return new Date().getTime();
}

/**
 * Determines the position of the mouse
 * @param {Event} e
 */
function findMouse(e){
	var posx = 0;
	var posy = 0;
	if (!e) var e = window.event;
	if (e.pageX || e.pageY){
		posx = e.pageX;
		posy = e.pageY;
	}
	else if (e.clientX || e.clientY){
		posx = e.clientX + document.body.scrollLeft;
		posy = e.clientY + document.body.scrollTop;
	};
	return[posx, posy];
};

function stopEventPropagation(e) {
	if (!e) var e = window.event;
	e.cancelBubble = true;
	if (e.stopPropagation) e.stopPropagation();
};