
DeclareEnum("UI.VAlignment", {
	Top: 0,
	Center: 0.5,
	Bottom: 1
});
DeclareEnum("UI.HAlignment", {
	Left: 0,
	Center: 0.5,
	Right: 1
});

DeclareClass("UI.PopupareaOptions", null, {
	constructor: function(obj){
		this.obj = obj;
		this.objVAlignment = UI.VAlignment.Bottom;
		this.objHAlignment = UI.HAlignment.Left;
		this.hAlignment = UI.HAlignment.Right;
		this.vAlignment = UI.VAlignment.Bottom;
		this.hideTimeout = 1500;
		this.allowAutoRedirection = true;
		
		this.offsetX = 0;
		this.offsetY = 0;
		this.singlePopup = true; // other opened popup will be closed;
	}
});

DeclareClass("UI.Popuparea", "UI.RenderableObject", {
	constructor : function(popupid) {
		if(!popupid) return null;
		this.base(popupid);
		
		if(UI.Popuparea.__popups[popupid]!=null)
			return UI.Popuparea.__popups[popupid];
		UI.Popuparea.__popups[popupid] = this;
		
		this.EnsureObject();
		this.CloseHandler = null;
		this.ContentCtrl = $(popupid + "_c");
		this.ContentCtrl.style.styleFloat = "left";
		this.ScrollElement = this.ContentCtrl.parentElement;
		this.ScrollElement.style.overflow = "auto";	
		
		this.setSize(0, 32000, 0, 32000);
		this.setSize(this.obj.getAttribute("minWidth"), this.obj.getAttribute("maxWidth"), this.obj.getAttribute("minHeight"), this.obj.getAttribute("maxHeight"));
			
		dom_attachEventForObject(this.obj, "mouseout", this.CreateCallback(this.__mouseOut));
		dom_attachEventForObject(this.obj, "mouseover", this.CreateCallback(this.__mouseOver));		
		dom_attachEventForObject(this.ContentCtrl, "resize", this.CreateCallback(this.__onResize));
	}
	,setPosition: function() {
		if(!this.__options || !this.__options.obj )
			return this.hidePopup();
		if(!this.bodyObj)
			this.bodyObj = $("MainArea")||document.body;
		var bodyRec = dom_RectangleObject.getScreenRect(this.bodyObj, true);
		var objRec	= dom_RectangleObject.getScreenRect(this.__options.obj);
		if(bodyRec == null || objRec == null)
			return this.hidePopup();
		var objHAlign = this.__options.objHAlignment, objVAlign = this.__options.objVAlignment;
		var hAlign = this.__options.hAlignment, vAlign = this.__options.vAlignment;

		if(this.__options.allowAutoRedirection){
			var isredirect = 0;
			do{
				var pp_right = objRec.left + objHAlign*objRec.getWidth() + this.obj.offsetWidth*hAlign + this.__options.offsetX;
				var pp_bottom = objRec.top + objVAlign*objRec.getHeight() + this.obj.offsetHeight*vAlign + this.__options.offsetY;
				var _tmp_redir = 0;
				if(pp_right > bodyRec.right || pp_right - this.obj.offsetWidth < 0){
					if(objVAlign != vAlign || objVAlign== UI.VAlignment.Center)
						objHAlign = hAlign = 1-hAlign;
					else
						hAlign += pp_right > bodyRec.right?-0.5:0.5;
					_tmp_redir =1;
				}
				if(pp_bottom > bodyRec.bottom || pp_bottom - this.obj.offsetHeight < 0){
					if(objHAlign != hAlign  || objHAlign==UI.HAlignment.Center)
						objVAlign = vAlign = 1-vAlign;
					else
						vAlign += pp_bottom > bodyRec.bottom? -0.5:0.5;
					_tmp_redir =1;
				}
				isredirect += _tmp_redir;
			}while(_tmp_redir>0 && isredirect<2)
		}		
		
		var eName = function(enumType, value){
			for(key in enumType)
				if(enumType[key] == value)
					return key;
			return null;
		}
		
		if( mclass = this.obj.getAttribute('mainCss')){
			var css = this.obj.className.replace(new RegExp("\\s"+mclass+"_\\w+","ig"), "");
			css += " ~0_~1_~2".format(mclass, eName(UI.VAlignment, vAlign), eName(UI.HAlignment, hAlign));
			if(css !=  this.obj.className)
				this.obj.className = css;
		}		
		
		var tmp = dom_RectangleObject.getRelativeDomRect(this.__options.obj, dom_RectangleObject.findRelativeObj(this.obj));
		
		var pp_left = tmp.left + objHAlign*tmp.getWidth() - this.obj.offsetWidth*(1-hAlign) + this.__options.offsetX;
		var pp_top = tmp.top + objVAlign*tmp.getHeight() - this.obj.offsetHeight*(1-vAlign) + this.__options.offsetY;
		if(this.obj.offsetTop!= pp_top || this.obj.offsetLeft != pp_left){				
			this.obj.style.top = pp_top;
			this.obj.style.left = pp_left;
		}			
	}
	,setWidth: function(width){	this.ScrollElement.style.width = width;	}
	,setSize: function(minwidth, maxWidth, minHeight, maxHeight) {	
		if(minwidth!=null) 
			this.ScrollElement.style.minWidth =	this.minWidth = minwidth;
		if(maxWidth!=null)
			this.ScrollElement.style.maxWidth = this.maxWidth =  maxWidth;
		if(minHeight!=null)
			this.ScrollElement.style.minHeight = this.minHeight = minHeight;
		if(maxHeight!=null)	
			this.ScrollElement.style.maxHeight = this.maxHeight = maxHeight;			
	}
	//,showPopupFromObject: function(obj, objVAlignment, objHAlignment, vAlignment, hAlignment, hideTimeout)
	,showPopupFromObject: function(options) {
		if(options ==null || options.obj == null)		
			throw "UI.Popuparea.showPopupFromObject: invalid arguments";
		this.__options = options;
		
		if(options.singlePopup)
			UI.Popuparea.__closeAllPopups();		
		this.EnsureObject();
		this.setPosition();
		this.ResizeHandlerID = window.setInterval(this.CreateCallback(this.setPosition),50);
		this.obj.className = this.obj.className.replace("popuparea-hide", "popuparea-show");
		this.obj.style.visibility = "visible";
		this.isActive = true;
		if(this.__options.hideTimeout !=-1){
			this.DeleteTimeout();
			this.SetHideTimeout(this.__options.hideTimeout);
		}
		if(window.event!=null)
			window.event.cancelBubble = true;
		if(UI.Popuparea.__openPopups.length == 0)
			window.setTimeout("dom_attachEventForObject(document,'click', UI.Popuparea.__closeAllPopups);",100);
		UI.Popuparea.__openPopups.push(this);
		return false;
	}
	,hidePopup: function(){
		if(!this.isActive)
			return;
		this.isActive = false;
		this.obj.className = this.obj.className.replace("popuparea-show", "popuparea-hide");
		this.obj.style.visibility = "hidden";		
		this.DeleteTimeout();
		for(var i=UI.Popuparea.__openPopups.length-1; i>=0; i--)
			if(UI.Popuparea.__openPopups[i] == this)
				UI.Popuparea.__openPopups.remove(i);
		
		if(UI.Popuparea.__openPopups.length == 0)
			dom_detachEventForObject(document, "click", UI.Popuparea.__closeAllPopups);
		window.clearInterval(this.ResizeHandlerID);
		
		if(typeof(this.CloseHandler)=='function')
			this.CloseHandler();
	}
	,DeleteTimeout: function(){	
		if(this.mouseOutHandler != null){
			clearTimeout(this.mouseOutHandler);
			this.mouseOutHandler = null;
		}	
	}
	,SetHideTimeout: function(interval){	
		if(this.mouseOutHandler == null)	
			this.mouseOutHandler = setTimeout(this.CreateCallback(this.hidePopup), interval);	
	}
	,SetContentHTML: function(html){
		this.ContentCtrl.innerHTML = html;
	}
	,IsOpen: function(){
		return !!this.isActive;
	}
	/*Privare members*/
	,__onResize : function(){
		var width = Math.max(parseInt(this.ScrollElement.style.minWidth), Math.min(parseInt(this.ScrollElement.style.maxWidth), this.ContentCtrl.offsetWidth))
		var overflowX = this.ContentCtrl.offsetWidth > parseInt(this.ScrollElement.style.maxWidth)?"scroll":"visible";
		var height = Math.max(parseInt(this.ScrollElement.style.minHeight), Math.min(parseInt(this.ScrollElement.style.maxHeight), this.ContentCtrl.offsetHeight))
		var overflowY = this.ContentCtrl.offsetHeight > parseInt(this.ScrollElement.style.maxHeight)?"scroll":"visible";
		
		if(this.ScrollElement.style.overflowX != overflowX)
				this.ScrollElement.style.overflowX = overflowX;
		if(this.ScrollElement.style.overflowY != overflowY)
			this.ScrollElement.style.overflowY = overflowY;
		if(this.ScrollElement.style.width != width)
			this.ScrollElement.style.width = width;
		if(this.ScrollElement.style.height != height)
				this.ScrollElement.style.height = height;
		this.setPosition();
	}
	,__mouseOver: [decl_virtual, function(){
		if(this.__options.hideTimeout!=-1)
			this.DeleteTimeout();
		if (window.event) window.event.returnValue=true;
	}]
	,__mouseOut: [decl_virtual, function(){
		if(this.__options.hideTimeout!=-1)
			this.SetHideTimeout(this.__options.hideTimeout);
		if (window.event) window.event.returnValue=true;
	}]
	/*Static members*/
	,__openPopups: [decl_static, []]
	,__popups: [decl_static, []]
	,__closeAllPopups: [decl_static, function(){
		for(var i=UI.Popuparea.__openPopups.length-1; i>=0; i--)
			UI.Popuparea.__openPopups[i].hidePopup();
		UI.Popuparea.__openPopups = [];
	}]
	,Find: [decl_static, function(id){
		return UI.Popuparea.__popups[id] || (new UI.Popuparea(id));
	}]
});
/*=============== Popup menu section ==================*/
function ui_GetPopupMenu(id){
	return UI.Popuparea.__popups[id] || (new UI.PopupMenu(id));
}
DeclareClass("UI.PopupMenu", "UI.Popuparea",{
	constructor : function(popupid){		
		this.base(popupid);		
		this.itemCss = this.obj.getAttribute("itemCss");
		this.itemHCss = this.obj.getAttribute("itemHCss");
		this.clickHandler = this.obj.getAttribute("clickFn");
		for(var i=0, j=this.ContentCtrl.children.length; i<j; i++)
			this.ContentCtrl.children[i].className = this.itemCss;
		dom_attachEventForObject(this.obj, "click", this.CreateCallback(this.onClick));
	}
	,FillMenu: function(itemTemplate, valuesArray,  selectedValue){
		var isOneDirection = !(valuesArray.length>0 && valuesArray[0] instanceof Array);
		var thisObj = this;
		var createItem = function(val){
			var item = document.createElement(isOneDirection==true?"div":"span");
			item.setAttribute("value", val.Value);
			item.innerHTML = itemTemplate.replace(/{value}/g,val.Value).replace(/{name}/g,val.Name);
			item.className = val.Value==selectedValue?thisObj.itemHCss:thisObj.itemCss;
			thisObj.ContentCtrl.appendChild(item);
			return item;
		}
		this.ContentCtrl.innerHTML = "";
		for (var i=0; i<valuesArray.length; i++){
			if(valuesArray[i] instanceof Array)
				for(var j=0; j<valuesArray[i].length; j++){
					var item = createItem(valuesArray[i][j]);
					if(j==valuesArray[i].length-1)
						this.ContentCtrl.appendChild(document.createElement("br"));
				}
			else
				createItem(valuesArray[i]);
		}
	}
	,onClick: function(){
		var srcElement = window.event.srcElement;
		if(this.obj!=srcElement && this.ContentCtrl!=srcElement && this.clickHandler!=null)
			if(typeof(this.clickHandler) == "function")
				this.clickHandler(srcElement.getAttribute("value") , srcElement.innerText);	
			else
				eval(this.clickHandler+"('"+srcElement.getAttribute("value")+"','"+srcElement.innerText.replace("'","\\\'")+"');")	
		this.hidePopup();
	}
	,__mouseOver: [decl_virtual, function(){
		var elem = event.srcElement;
		while(elem!=this.obj && elem.parentElement != this.ContentCtrl)
			elem = elem.parentElement;
		if(elem!=this.obj)
			elem.className = this.itemHCss;
		this.base.__mouseOver();		
	}]
	,__mouseOut: [decl_virtual, function(){
		var elem = event.srcElement;
		while(elem!=this.obj && elem.parentElement != this.ContentCtrl)
			elem = elem.parentElement;
		if(elem!=this.obj)
			elem.className = this.itemCss;
		this.base.__mouseOut();
	}]
});