var WidgetDropDown = Class.create();
WidgetDropDown.prototype = {
	initialize: function(clientId) {
		this.id				= clientId;
		this.inited			= false;
		this._visible			= false;
		this._keepAlive		= false;
		this._hideTimer		= null;
		this.parentObject	= null;
		this.onShow			= function(){};
		this.runtimeAdjusting = true;
		this.cancelEventsSet = false;
	},
	init: function() {
		//if( Flux.Context.isUserAuthenticated() )
		if (!this._initElements()) return;
		
		if (!this.parentObject)
			this.parentObject = this.id + "_ddbutton";
			
		this._setActions();
		this.inited = true;
	},
	_initElements: function() {
		if (this._elementsInited) return;
		this.ddholder	= $(this.id + "_ddholder");
		this.button		= $(this.id + "_ddbutton"); // this.ddholder.down('.ddButton'); // 
		this.popup		= $(this.id + "_dd"); //this.ddholder.down('.itemsList'); //
		this.mate		= ((this.ddholder) ? this.ddholder.down('iframe') : null);	//this.mate		= $(this.id + "_ddmate");
		if (!this.button || !this.popup || !this.mate || !this.ddholder) return false;
		
		this.closestRelative = ((Prototype.Browser.IE) ? this.ddholder : this.button);
		this.closestRelative = this.button; // ((Prototype.Browser.IE) ? this.ddholder : this.button);
		
		this._posAdjustment(true);
		return (this._elementsInited = true);
	},
	_posAdjustment: function(force) {
		if (!(this.runtimeAdjusting || force)) return;
		this.mate.frameBorder = 0;
		[this.popup, this.mate].each(Position.absolutize); // #1 ORDER!!
		[this.popup, this.mate].each(Element.show); // #2 ORDER!!
		
		this.closestRelative.style.position = "relative";
		this.popup.style.width = this.popup.getWidth() + 'px';
		Position.clone(this.ddholder, this.popup, { setHeight: false, setWidth: false, offsetTop: this.button.getHeight()});
		this.popup.style.zIndex = 10000;
		this.mate.style.zIndex	= 999;
		this.button.style.zIndex = 100;
		Position.clone(this.popup, this.mate);
		
		[this.mate, this.popup].each(Element.hide);
		this.closestRelative.style.position = "static";
	},
	_setActions: function() {
		if (this.cancelEventsSet) return;
		this.button.observe('click', this.showPopupEvt.bindAsEventListener(this, true));
		
		[this.button, this.popup].invoke('observe', 'mouseout', this.hidePopup.bind(this));
		[this.button, this.popup].invoke('observe', 'mouseover', this.keepAlive.bind(this));
	},
	showPopup: function(show, evt) { // for API compatibility
		if (evt)
			return this.showPopupEvt(evt);
		else
			return this._showPopup(show);
	},
	showPopupEvt: function(evt) {
		this._showPopup(true);
		Event.stop(evt);
		return false;
	},
	_showPopup: function(show) {
		if (!this.inited) return;
		
		this._resetTimer();

		show = !!show;
		if (!(this._visible || show)) return;
		
		if (this._visible && this._keepAlive){
			this._keepAlive = false;
			return;
		}
		
		this._initElements();
		if (show) this._posAdjustment();

		this.closestRelative.style.position = ((show) ? 'relative' : 'static');

		[this.popup, this.mate].each(Element[((show) ? 'show' : 'hide')]);
		this.onShow(show, this.button, this.popup, this.mate, this.ddholder);
	
		this._visible = show;
	},
	forseHidePopup: function() {
		this._keepAlive = false;
		this._showPopup();
	},
	hidePopup: function() {
		if (!this._visible) return;
		this._keepAlive = false;
		this._setupTimer(this._showPopup.bind(this, false));
	},
	keepAlive: function() {
		if (!this._visible) return;
		this._keepAlive = true;
		this._resetTimer();
		return false;
	},
	_setupTimer: function(handler) {
		this._resetTimer();
		this._hideTimer = window.setTimeout(handler, 500);
	},
	_resetTimer: function() {
		if (!this._hideTimer) return;
		window.clearTimeout(this._hideTimer);
		this._hideTimer = null;
	}
};