(function(jQuery) {
	jQuery.dropDownMenuShared = {
		current: undefined,
		current_zindex: 0,
		initCurrent: function() {
			if (this.current == undefined) {
				return;
			}
			this.current_zindex = jQuery(".dropdown-list-container", this.current.control).css("z-index");
			
			
			jQuery(".dropdown-list-container", this.current.control).css("z-index", 99999);
			jQuery(".dropdown-list", this.current.control).css("z-index", 99998);
			if (this.current.iframeFix) {
				jQuery(".dropdown-list-container", this.current.control).find('iframe').css("z-index", 0);
			}
			jQuery(this.current.control).css("z-index", 99996);
		},
		restoreCurrent: function() {
			if (this.current == undefined) {
				return;
			}
			jQuery(".dropdown-list-container", this.current.control).css("z-index", this.current_zindex);
			jQuery(this.current.control).css("z-index", this.current_zindex-1);
			if (this.current.iframeFix) {
				jQuery(".dropdown-list-container", this.current.control).find('iframe').css("z-index", this.current_zindex-1);
			}
		},
		pause: function ( ms ) {
			var date = new Date();
			var curDate = null;
			do { curDate = new Date(); }
			while ( curDate - date < ms);
		},
		getPageSize: function () {
			var xScroll, yScroll;

			if (window.innerHeight && window.scrollMaxY) {	
				xScroll = window.innerWidth + window.scrollMaxX;
				yScroll = window.innerHeight + window.scrollMaxY;
			} else if (document.body.scrollHeight > document.body.offsetHeight){ // all but Explorer Mac
				xScroll = document.body.scrollWidth;
				yScroll = document.body.scrollHeight;
			} else { // Explorer Mac...would also work in Explorer 6 Strict, Mozilla and Safari
				xScroll = document.body.offsetWidth;
				yScroll = document.body.offsetHeight;
			}

			var windowWidth, windowHeight;

			if (self.innerHeight) {	// all except Explorer
				if(document.documentElement.clientWidth){
					windowWidth = document.documentElement.clientWidth; 
				} else {
					windowWidth = self.innerWidth;
				}
				windowHeight = self.innerHeight;
			} else if (document.documentElement && document.documentElement.clientHeight) { // Explorer 6 Strict Mode
				windowWidth = document.documentElement.clientWidth;
				windowHeight = document.documentElement.clientHeight;
			} else if (document.body) { // other Explorers
				windowWidth = document.body.clientWidth;
				windowHeight = document.body.clientHeight;
			}	

			// for small pages with total height less then height of the viewport
			if(yScroll < windowHeight){
				pageHeight = windowHeight;
			} else { 
				pageHeight = yScroll;
			}


			// for small pages with total width less then width of the viewport
			if(xScroll < windowWidth){	
				pageWidth = xScroll;		
			} else {
				pageWidth = windowWidth;
			}
			
			//
			var largestWidth;
			var largestHeight;
			var smallestWidth;
			var smallestHeight;
			//
			if ( pageWidth >= windowWidth )
			{	largestWidth = pageWidth; smallestWidth = windowWidth;	}
			else
			{	largestWidth = windowWidth; smallestWidth = pageWidth;	}
			//
			if ( pageHeight >= windowHeight )
			{	largestHeight = pageHeight; smallestHeight = windowHeight;	}
			else
			{	largestHeight = windowHeight; smallestHeight = pageHeight;	}
			
			// Return
			var arrayPageSize = {'pageWidth':pageWidth,'pageHeight':pageHeight,'windowWidth':windowWidth,'windowHeight':windowHeight,'largestWidth':largestWidth,'largestHeight':largestHeight};
			return arrayPageSize;
		},
			
		getPageScroll: function ( ) {
			var xScroll, yScroll;
			if (self.pageYOffset) {
				yScroll = self.pageYOffset;
				xScroll = self.pageXOffset;
			} else if (document.documentElement && document.documentElement.scrollTop) {	 // Explorer 6 Strict
				yScroll = document.documentElement.scrollTop;
				xScroll = document.documentElement.scrollLeft;
			} else if (document.body) {// all other Explorers
				yScroll = document.body.scrollTop;
				xScroll = document.body.scrollLeft;	
			}
			var arrayPageScroll = {'xScroll':xScroll,'yScroll':yScroll};
			return arrayPageScroll;
		}
	};
	
	jQuery.dropDownMenu = function(ele, o) {
		this.options = jQuery.extend({ 
			width: "auto",
			slideDownSpeed: 1000,
			slideUpSpeed: "fast",
			easeShow:"easeOutQuad",
			easeHide:"easeInQuad",
			checkContainerDim:true,
			scrollPaneOptions: {
				scrollbarWidth : 22,
				scrollbarMargin : 0,
				showArrows : true,
				arrowSize : 10,
				dragMinHeight : 26,
				dragMaxHeight : 26,
				maintainPosition: false
			},
			itemSelected: undefined
		},o);
		this.dim = {};
		this.elem = ele;
		this.init();
	};
	
	jQuery.extend(jQuery.dropDownMenu, {
		prototype: {
			init: function() {
				var self = this;
				
				if (jQuery(this.elem).is("select")) {
					this.select = this.elem;
					
					jQuery(this.select).wrap("<div class='dropdown'></div>");
					this.control = jQuery(this.select).parent();
				} else {
					this.select = jQuery("select:eq(0)", this.elem);
					if (!this.select.length) return;
					this.select = this.select[0];
					
					jQuery(this.elem).addClass('dropdown');
					this.control = jQuery(this.elem);
				}
				
				this.control.show();
				
				var result = jQuery("<div class='dropdown-result-container'><span class='dropdown-result'></span><a class='dropdown-arrow'><span></span></a></div>");
				this.control.append( result );
				this.control.append( jQuery("<div class='dropdown-list-container'><div class='dropdown-list-wrapper'><ul class='dropdown-list'></ul></div></div>") );
				
				jQuery(".dropdown-list", this.control).show();
				jQuery(".dropdown-list-wrapper", this.control).show();
				jQuery(".dropdown-list-container", this.control).show();
				
				this.select_options = jQuery("option", this.select);
				this.itemsValue = [];
				for (var i=0,n=this.select_options.length; i < n; i++) {
					var option = jQuery(this.select_options[i]);
					var h = option.html();
					var c = ((option.attr("disabled") || false)) ? "disabled" : "";
					var c2 = this.select_options[i].selected ? "selected" : "";
					var v = option.attr("value") || "";
					this.itemsValue[i] = v;
					
					jQuery(".dropdown-list", this.control).append("<li>"+h+"</li>");
					if (c != "")
						
						jQuery(".dropdown-list li:last", this.control).addClass(c);
						
					if (c2 != "") {
						jQuery(".dropdown-list li:last", this.control).addClass(c2);
					}
				}
				
				this.items = jQuery(".dropdown-list-container li", this.control);
				this.arrow = jQuery(".dropdown-arrow", this.control);
				this.result = jQuery(".dropdown-result", this.control);
				
				if (!this.items.length) {
					return;
				}
				
				if (!jQuery(this.items).filter(".selected").length) {
					jQuery(this.items[0]).addClass("selected")
				}
				this.initial = jQuery(jQuery(this.items).filter(".selected")[0]);
				
				this.current = this.initial;
				this.value(this.itemsValue[this.items.index(this.current)]);
				
				if (this.options.checkContainerDim) {
					this.dim.controlContainer = {
						padding: {
							top: parseInt(jQuery(this.control).parent().css("padding-top")) || 0,
							bottom: parseInt(jQuery(this.control).parent().css("padding-bottom")) || 0,
							left: parseInt(jQuery(this.control).parent().css("padding-left")) || 0,
							right: parseInt(jQuery(this.control).parent().css("padding-right")) || 0
						},
						border: {
							top: parseInt(jQuery(this.control).parent().css("border-top-width")) || 0,
							bottom: parseInt(jQuery(this.control).parent().css("border-bottom-width")) || 0,
							left: parseInt(jQuery(this.control).parent().css("border-left-width")) || 0,
							right: parseInt(jQuery(this.control).parent().css("border-right-width")) || 0
						}
					};
				}
					
				//the result size
				if (this.options.width != "auto") {
					jQuery(".dropdown-result-container", this.control).css("width", this.options.width);
				} else {
					var w = jQuery(this.select).outerWidth();
					w -= this.arrow.outerWidth(true);
					w -= parseInt(this.result.css("margin-left")) || 0;
					w -= parseInt(this.result.css("margin-right")) || 0;
					w -= parseInt(this.result.css("padding-left")) || 0;
					w -= parseInt(this.result.css("padding-right")) || 0;
					w -= parseInt(jQuery(".dropdown-result-container", this.control).css("padding-left")) || 0;
					w -= parseInt(jQuery(".dropdown-result-container", this.control).css("padding-right")) || 0;
					
					jQuery(".dropdown-result", this.control).css("width", w+"px");
				}
				
				//the control size
				w = jQuery(".dropdown-result", this.control).outerWidth(true) + jQuery(".dropdown-arrow").outerWidth(true);
				
				jQuery(".dropdown-result-container", this.control).css("width", w+"px");
				
				w = jQuery(".dropdown-result-container", this.control).outerWidth(true);
				//alert(w);
				//jQuery(this.control).css("width", w+"px");
				
				//the dropdown size
				w1 = jQuery(".dropdown-result-container", this.control).outerWidth();
				w2 = jQuery(".dropdown-list-container", this.control).outerWidth();
				pl = parseInt(jQuery(".dropdown-list-container", this.control).css("padding-left")) || 0;
				pr = parseInt(jQuery(".dropdown-list-container", this.control).css("padding-right")) || 0;
				bl = parseInt(jQuery(".dropdown-list-container", this.control).css("border-left-width")) || 0;
				br = parseInt(jQuery(".dropdown-list-container", this.control).css("border-right-width")) || 0;
				ppl = parseInt(jQuery(".dropdown-result-container", this.control).css("padding-left")) || 0;
				ppr = parseInt(jQuery(".dropdown-result-container", this.control).css("padding-right")) || 0;
				if ((w2-pr-pl-br-bl+ppl+ppr) < w1) {
					jQuery(".dropdown-list-container", this.control).css("width", (w1-pr-pl-br-bl+ppl+ppr)+"px");
				}
				
				w1 = jQuery(".dropdown-list-container", this.control).innerWidth();
				
				w1 -= parseInt(jQuery(".dropdown-list-container .dropdown-list", this.control).css("padding-left")) || 0;
				w1 -= parseInt(jQuery(".dropdown-list-container .dropdown-list", this.control).css("padding-right")) || 0;
				
				if (w1 > 0) {
					jQuery(".dropdown-list-container .dropdown-list", this.control).css({width:w1+"px"});
				}
				
				if (jQuery.browser.msie && jQuery.browser.version < 8) {
					//fix z-index
					d = jQuery(".dropdown").index(this.control);
					
					//ie iframe fix
					w = jQuery(".dropdown-list-container", this.control).innerWidth();
					w -= parseInt(jQuery(".dropdown-list-container", this.control).css("padding-left")) || 0;
					w -= parseInt(jQuery(".dropdown-list-container", this.control).css("padding-right")) || 0;
					h = jQuery(".dropdown-list-container", this.control).innerHeight();
					h -= parseInt(jQuery(".dropdown-list-container", this.control).css("padding-top")) || 0;
					h -= parseInt(jQuery(".dropdown-list-container", this.control).css("padding-bottom")) || 0;
					
					t = parseInt(jQuery(".dropdown-list-container", this.control).css("top")) || 0;
					
					l = parseInt(jQuery(".dropdown-list-container", this.control).css("left")) || 0;
					l += parseInt(jQuery(".dropdown-list-container", this.control).css("borderLeftWidth")) || 0;
					
					z = parseInt(jQuery(".dropdown-list-container", this.control).css("z-index")) || 0;
					
					if (d > 0 && z > 0) {
						if (z - (d * 10) > 0) {
							z -= (d * 10);
							jQuery(".dropdown-list-container", this.control).css("z-index", z);
							jQuery(this.control).css("z-index", z-1);
						}
					}
					
					this.iframeFix = true;
					this.savedZIndex = z;
					var iframe = jQuery("<iframe frameborder='0' scrolling='no'></iframe>").css({
						width: w+"px",
						height: h+"px",
						position: "absolute",
						left: l+"px",
						top: t+"px",
						zIndex: (z-1),
						display: "block",
						overflow: "hidden"
					});
					
					jQuery(".dropdown-list-container", this.control).append(iframe);
					
				}
				
				//the result position
				t = jQuery(".dropdown-result-container", this.control).outerHeight(true);
				t += parseInt(this.control.css("padding-top")) || 0;
				t += parseInt(this.control.css("padding-bottom")) || 0;
				t += parseInt(this.control.css("border-top-width")) || 0;
				t += parseInt(this.control.css("border-bottom-width")) || 0;
				l = parseInt(jQuery(".dropdown-result-container", this.control).css("padding-left")) || 0;
				
				jQuery(".dropdown-list-container", this.control).css("top", t+"px");
				jQuery(".dropdown-list-container", this.control).css("left", -l+"px");
				
				//save needed control's appearence
				this.dim.resultContainer = {
					height: t
				};
				
				h = jQuery(".dropdown-list-container", this.control).outerHeight();
				this.dim.listContainer = {
					height: h
				}
				
				h = jQuery(".dropdown-list-wrapper", this.control).innerHeight();
				h -= parseInt(jQuery(".dropdown-list-wrapper", this.control).css("paddingTop")) || 0;
				h -= parseInt(jQuery(".dropdown-list-wrapper", this.control).css("paddingBottom")) || 0;
				w = jQuery(".dropdown-list-wrapper", this.control).innerWidth();
				w -= parseInt(jQuery(".dropdown-list-wrapper", this.control).css("paddingLeft")) || 0;
				w -= parseInt(jQuery(".dropdown-list-wrapper", this.control).css("paddingRight")) || 0;
				
				this.dim.listWrapper = {
					width: w,
					height: h
				};
				
				//events
				this.arrow.bind("click", function() {
					if (!self.select.disabled) {
						if (self.showed) {
							self.hideMenu.apply(self,[]);
						} else {
							self.showMenu.apply(self,[]);
						}
					}
					return false;
				});
				this.result.bind("dblclick", function() {
					if (!self.select.disabled) {
						self.showMenu.apply(self,[]);
					}
					return false;
				});
				this.items.each(function() {
					jQuery(this).bind("mouseover", function() {
						if (!jQuery(this).is(".disabled")) {
							jQuery(this).addClass("hover");
						}
					});
					jQuery(this).bind("click", function(event) {
						
						self.selectItem.apply(self, [this]);
						self.hideMenu.apply(self,[]);
						return false;
					});
					jQuery(this).bind("mouseout", function() {
						jQuery(this).removeClass("hover");
					});
				});
				//bind this element change event (for instance by script)
				jQuery(this.select).bind("change", function() {
					var v = this.value || "";
					if (v == "") {
						jQuery(self.result).addClass("dropdown-result_emptyValueSelected");
					} else {
						jQuery(self.result).removeClass("dropdown-result_emptyValueSelected");
					}
					self.value ( this.value );
				});
				//bind form reset
				if (jQuery(this.select).parents("form").length) {
					jQuery(this.select).parents("form").bind("reset", function() {
						self.value ( self.itemsValue[self.items.index(self.initial)] );
					});
				}
				
				//bind document click to close dropdown list
				jQuery(document).bind("click", function(event){
					if (event && event.target) {
						if (jQuery(event.target).parents(".dropdown").length) {
							return false;
						}
					}
					self.onDocClick.apply(self,[event]);
				});
				
				//hide original control
				jQuery(this.select).hide();
				jQuery(".dropdown-list-container", this.control).hide();
				
				jQuery(this.select).triggerHandler("change");
				
				if (jQuery.browser.msie && jQuery.browser.version < 7) {
					jQuery(this.arrow).bind("mouseover", function(){
						jQuery(this).addClass("dropdown-arrow-hover");
					});
					jQuery(this.arrow).bind("mouseout", function(){
						jQuery(this).removeClass("dropdown-arrow-hover");
					});
				}
			},
			
			value: function( val ) {
				if (val == undefined) {
					return this.itemsValue[this.items.index(this.current)];
				} else {
					for (var i=0, n=this.items.length; i < n; i++) {
						v = this.itemsValue[this.items.index(this.items[i])];
						if ( v == val ) {
							this.items.removeClass("selected");
							jQuery(this.items[i]).addClass("selected");
							
							this.current = jQuery(this.items[i]);
							jQuery(".dropdown-result", this.control).html( "<span>"+this.current.html()+"</span>" );
							if (this.elem.value != val) {
								this.elem.value = val;
								jQuery(this.elem).trigger("keyup");
								jQuery(this.elem).trigger("change");
								jQuery(this.elem).triggerHandler("click");
							}
							break;
						}
					}
				}
			},
			
			resizeContainer: function() {
				var container = jQuery(".dropdown-list-container", this.control);
				
				parent_offset = this.control.offset();
				page_scroll = jQuery.dropDownMenuShared.getPageScroll();
				page_size = jQuery.dropDownMenuShared.getPageSize();
				
				view_offset = {
					left: parent_offset.left - page_scroll.xScroll,
					top: parent_offset.top - page_scroll.yScroll
				}
				
				jQuery(".dropdown-list-wrapper", this.control).css({
					overflow:"visible",
					height:"auto"
				});
				
				available_top = view_offset.top - 30;
				available_bottom = page_size.windowHeight - view_offset.top - this.dim.resultContainer.height - 30;
				available_bottom -= jQuery(".footer_holder").outerHeight();
				
				if (available_bottom > this.dim.listContainer.height) {
					//default, put it at bottom
					t = this.dim.resultContainer.height;
					if (this.options.checkContainerDim) {
						t += this.dim.controlContainer.padding.bottom;
						t += this.dim.controlContainer.border.bottom;
					}
					jQuery(".dropdown-list-container", this.control).css("top", t+"px");
					jQuery(".dropdown-list-wrapper", this.control).css({
						overflow: "visible",
						width: this.dim.listWrapper.width + "px",
						height: this.dim.listWrapper.height + "px"
					});
					jQuery(".jScrollPaneContainer", this.control).css({
						overflow: "visible",
						width: this.dim.listWrapper.width + "px",
						height: this.dim.listWrapper.height + "px"
					});
					jQuery(".dropdown-list-wrapper", this.control).jScrollPane(this.options.scrollPaneOptions);
				} else {
					t = this.dim.resultContainer.height;
					
					available_height = 0;
					if (available_top > available_bottom) {
						available_height = available_top;
					} else {
						available_height = available_bottom;
						
					}
					
					if (available_height < this.dim.listContainer.height) {
						jQuery(".dropdown-list-wrapper", this.control).css({
							overflow: "auto",
							height: available_height + "px"
						});
						jQuery(".jScrollPaneContainer", this.control).css({
							height: available_height + "px"
						});
						
						jQuery(".dropdown-list-wrapper", this.control).jScrollPane(this.options.scrollPaneOptions);
						
					} else {
						
						h = this.dim.listContainer.height;
						jQuery(".dropdown-list-wrapper", this.control).css({
							overflow: "visible",
							width: this.dim.listWrapper.width + "px",
							height: this.dim.listWrapper.height + "px"
						});
						
						jQuery(".jScrollPaneContainer", this.control).css({
							overflow: "visible",
							width: this.dim.listWrapper.width + "px",
							height: this.dim.listWrapper.height + "px"
						});
						
						jQuery(".dropdown-list-wrapper", this.control).jScrollPane(this.options.scrollPaneOptions);
					}
					
					if (available_top > available_bottom) {
						t = jQuery(".dropdown-list-container", this.control).outerHeight();
						if (this.options.checkContainerDim) {
							t += this.dim.controlContainer.padding.top;
							t += this.dim.controlContainer.border.top;
						}
						jQuery(".dropdown-list-container", this.control).css("top", -t+"px");
					} else {
						t = this.dim.resultContainer.height;
						if (this.options.checkContainerDim) {
							t += this.dim.controlContainer.padding.bottom;
							t += this.dim.controlContainer.border.bottom;
						}
						jQuery(".dropdown-list-container", this.control).css("top", t+"px");
					}
				}
				
			},
			
			showMenu: function() {
				if (jQuery.dropDownMenuShared.current != undefined) {
					jQuery.dropDownMenuShared.restoreCurrent();
					jQuery.dropDownMenuShared.current.hideMenu();
				}
				jQuery(".dropdown-list-container", this.control).show();
				this.control.addClass("dropdown-show");
				//strange, but IE 8 need this !!!!
				if (jQuery.browser.msie && jQuery.browser.version > 7) {
					clone = jQuery(".dropdown-list-container", this.control).clone();
					jQuery(this.control).append(clone);
					clone.remove();
				}
				//end of strange IE 8 hacks
				this.resizeContainer();
				if (this.iframeFix) {
					jQuery(".dropdown-list-container", this.control).find('iframe').css({
						top:0,
						left:0
					});
					jQuery(".dropdown-list-container", this.control).find('iframe').hide();
				}
				jQuery.dropDownMenuShared.current = this;
				jQuery.dropDownMenuShared.initCurrent();
				this.showed = true;
				
				jQuery(this.arrow).addClass("dropdown-arrow-open");
				
				jQuery(".content>.menu").css("zIndex",1);
			},
			
			hideMenu: function() {
				jQuery.dropDownMenuShared.restoreCurrent();
				jQuery.dropDownMenuShared.current = undefined;
				jQuery(".dropdown-list-container", this.control).hide();
				this.control.removeClass("dropdown-show");
				
				this.showed = false;
				jQuery(this.arrow).removeClass("dropdown-arrow-open");
				
				jQuery(".content>.menu").css("zIndex","");
			},
			
			selectItem: function(item) {
				if (jQuery(item).is(".selected") || jQuery(item).is(".disabled")) return false;
				this.value( this.itemsValue[this.items.index(item)] );
				
				if (this.options.itemSelected != undefined && typeof this.options.itemSelected == "function") {
					this.options.itemSelected(this.itemsValue[this.items.index(item)]);
				}
				
				return true;
			},
			
			onDocClick: function(event) {
				/*
				var o = this.control.offset();
				var l = o.left;
				var t = o.top;
				
				var h = this.control.outerHeight();
				h += this.result.outerHeight();
				h += jQuery(".dropdown-list-container", this.control).outerHeight();
				
				var w = jQuery(".dropdown-list-container", this.control).outerWidth();
				
				if (event.clientX < l || event.clientX > l + w || event.clientY < t || event.clientY > (t + h)) {
					this.hideMenu();
				}
				*/
				this.hideMenu();
			}
		}
	});
	
	
	jQuery.fn.dropDownMenu = function(o) {
		this.each(function() {
			var dropDown = jQuery(this).data("dropDown");
			if (!dropDown) {
				dropDown = new jQuery.dropDownMenu(this, o);
				jQuery(this).data("dropDown", dropDown);
			} else {
				//update options
				dropDown.options = jQuery.extend( dropDown.options, o );
				jQuery(this).data("dropDown", dropDown);
			}
			
			return dropDown;
		});
		
		return this;
	}
	
})(jQuery);