/*
Product Name: dhtmlxSuite 
Version: 4.0.3 
Edition: Professional 
License: content of this file is covered by DHTMLX Commercial or Enterprise license. Usage without proper license is prohibited. To obtain it contact sales@dhtmlx.com
Copyright UAB Dinamenta http://www.dhtmlx.com
*/
function dhtmlXPopup(conf) {
	
	var that = this;
	
	this.conf = conf||{};
	conf = null;
	
	this.mode = (this.conf.mode||"bottom"); // popup position related to caller element
	this.conf.zi = window.dhx4.newId();
	
	this.conf.isIE = (navigator.userAgent.indexOf("MSIE")>=0);
	
	this.p = document.createElement("DIV");
	this.p.style.display = "none";
	this.p.innerHTML = "
"+
				"";
	
	document.body.appendChild(this.p);
	
	this.skinParams = {
		dhx_terrace: {
			t0: 19, // minimal top offset for polygon, i.e. space between polygon top and arrow top
			t1: 9,  // if no more space at top, and "t0 allowed" - move top polygon position a bit to bottom, t1 = offset for empty space at top
			t2: 19, // same as t0, for width
			t3: 9   // same as t1, for width
		},
		dhx_skyblue: {t0: 12, t1: 9, t2: 12, t3: 9},
		dhx_web: {t0: 12, t1: 9, t2: 12, t3: 9}
	};
	
	this.p.onclick = function(e) {
		e = e||event;
		that._clearClick = true;
		if (that._nodeObj != null) {
			that.callEvent("onContentClick",[]);
			return true;
		}
		var t = (e.target||e.srcElement);
		var id = null;
		while (t != that.p && t != null) {
			if (typeof(t._idd) != "undefined" && !t._isSeparator) {
				id = t._idd;
				t = null;
			} else {
				t = t.parentNode;
			}
		}
		t = null;
		if (id != null) {
			that.callEvent("onClick",[id]);
			if (that != null && that.isVisible != null && that.isVisible() && that.callEvent("onBeforeHide",["select",e,id]) === true) {
				e.cancelBubble = true;
				that.hide();
			}
		}
	}
	
	this.separator = "DHXSEP_"+window.dhx4.newId();
	
	this.tpl = [];
	this._setTemplate = function(t) {
		this.tpl = t.split(",");
	}
	
	this.show = function(id) { // 4 coords for custom object, x, y, width, height
		
		var p = null;
		
		if (arguments.length == 1) {
			
			// if id not specified show on first
			
			if (!id) {
				id = this.conf.id[0];
			} else {
				if (!this._idExists(id)) return;
			}
			if (this.conf.toolbar) {
				p = this.conf.toolbar._getItemDim(id);
			}
			if (this.conf.ribbon) {
				p = this.conf.ribbon._getItemDim(id);
			}
			if (this.conf.form) {
				p = this.conf.form._getItemDim(id);
			}
			
		} else if (arguments.length == 4) {
			
			this._clearClick = true;
			
			// show for custom object, 4 coords
			p = {
				left:   arguments[0],
				top:    arguments[1],
				width:  arguments[2],
				height: arguments[3]
			}
			
			id = null;
		}
		
		if (!p) return;
		
		this.p.style.visibility = "hidden";
		this.p.style.display = "";
		
		this._setPos(p);
		
		this.p.style.zIndex = window.dhx4.zim.reserve(this.conf.zi);
		this.p.style.visibility = "visible";
		
		this._lastId = id;
		
		this.callEvent("onShow",[id]);
		
		
	}
	
	this._setPos = function(p, state) {
		
		var x = p.left;
		var y = p.top;
		var w = p.width;
		var h = p.height;
		
		this._posData = {
			left: x,
			top: y,
			width: w,
			height: h
		};
		
		var d = window.dhx4.screenDim();
		
		var mode = state||this.mode;
		if (typeof(state) == "undefined") state = false;
		
		// avail space form each side, negative value = no-space
		var availSpace = {
			top: (y-this.p.offsetHeight)-d.top,
			bottom: d.bottom-(y+h+this.p.offsetHeight),
			left: x-this.p.offsetWidth-d.left,
			right: d.right-(x+w+this.p.offsetWidth)
		};
		
		if (!state && availSpace[mode] < 0) {
			var k = this._getAvailPos(mode, availSpace);
			if (k !== false) {
				this._setPos(p, k);
				return;
			}
			
		}
		
		if (mode == "top" || mode == "bottom") {
			
			var t0 = this.skinParams[this.conf.skin].t2;
			var t1 = this.skinParams[this.conf.skin].t3;
			
			var pw2 = Math.round(this.p.offsetWidth/2); // 1/2 polygon width
			var aw2 = Math.round(this.p.lastChild.offsetWidth/2); // 1/2 arrow width
			
			// define max left and right position of input including rendering [d.left..d.right] area
			if (x < d.left) { var x1 = Math.min(x+w, d.left); w = x+w-x1; x = x1; } // left
			if (x+w > d.right) w = d.right-x; // right
			
			// arrow position
			var ta = Math.round(x+w/2);
			
			// polygon top
			var left = ta - pw2;
			var maxLeft = ta - t0 - aw2;
			var maxLeftRight = ta+aw2+t0-this.p.offsetWidth;
			
			
			if (left < d.left-t1) { // left
				left = Math.min(d.left-t1, maxLeft);
			} else if (left+this.p.offsetWidth > d.right+t1) { // right
				left = Math.max(maxLeftRight, d.right+t1-this.p.offsetWidth); // -scrollWidth here?
			}
			
			// draw polygon
			this.p.style.left = left+"px";
			this.p.style.top = (mode=="top"?y-this.p.offsetHeight:y+h)+"px";
			
			// fix arrow offset (it inside polygon)
			ta = ta-left-aw2;
			
			// draw arrow
			this.p.lastChild.className = "dhx_popup_arrow dhx_popup_arrow_"+mode;
			this.p.lastChild.style.top = (mode=="top"?this.p.offsetHeight-this.p.lastChild.offsetHeight:0)+"px";
			this.p.lastChild.style.left = ta+"px";
			
			
		}
		
		
		if (mode == "left" || mode == "right") {
			
			var t0 = this.skinParams[this.conf.skin].t0;
			var t1 = this.skinParams[this.conf.skin].t1;
			
			var ph2 = Math.round(this.p.offsetHeight/2); // 1/2 polygon height
			var ah2 = Math.round(this.p.lastChild.offsetHeight/2); // 1/2 arrow height
			
			// define max top and bottom position of input including rendering [d.top..d.bottom] area
			if (y < d.top) { var y1 = Math.min(y+h, d.top); h = y+h-y1; y = y1; } // top
			if (y+h > d.bottom) h = d.bottom-y; // bottom
			
			// arrow position
			var ta = Math.round(y+h/2);
			
			// polygon top
			var top = ta - ph2;
			var maxTop = ta - t0 - ah2;
			var maxTopBottom = ta+ah2+t0-this.p.offsetHeight;
			
			
			if (top < d.top-t1) { // top
				top = Math.min(d.top-t1, maxTop);
			} else if (top+this.p.offsetHeight > d.bottom+t1) { // bottom
				top = Math.max(maxTopBottom, d.bottom+t1-this.p.offsetHeight);
			}
			
			// draw polygon
			this.p.style.left = (mode=="left"?x-this.p.offsetWidth:x+w)+"px";
			this.p.style.top = top+"px";
			
			// fix arrow offset (it inside polygon)
			ta = ta-top-ah2;
			
			// draw arrow
			this.p.lastChild.className = "dhx_popup_arrow dhx_popup_arrow_"+mode;
			this.p.lastChild.style.left = (mode=="left"?this.p.offsetWidth-this.p.lastChild.offsetWidth:0)+"px";
			this.p.lastChild.style.top = ta+"px";
			
		}
		
		if (this._IEDisp && this._nodeId != null) {
			var t = document.getElementById(this._nodeId);
			//t.style.visibility = "hidden";
			window.setTimeout(function(){
				t.style.visibility = "visible";
				t = null;
			},1);
		}
	}
	
	this._getAvailPos = function(mode, data) {
		
		var seq = {
			top: ["bottom","right","left"],
			bottom: ["top","right","left"],
			left: ["right", "bottom", "top"],
			right: ["left", "bottom", "top"]
		};
		
		var dir = null;
		
		// check "next" with avail space
		for (var q=0; q 0) dir = seq[mode][q];
		}
		
		// define which side have more space
		if (dir == null) {
			dir = "bottom";
			for (var a in data) if (data[a] > data[dir]) dir = a;
		}
		
		if (dir == mode) return false;
		
		return dir;
		
	}
	
	this._repaint = function() {
		if (this.isVisible()) this._setPos(this._posData);
	}
	
	this.clear = function() {
		
		if (this._nodeObj) {
			if (this.conf.isIE && typeof(dhtmlXLayoutObject) != "undefined" && this._nodeObj instanceof dhtmlXLayoutObject) {
				this.p.onmousedown = null;
			}
			if (this._nodeObj.unload) {
				this._nodeObj.unload();
			} else if (this._nodeObj.destruct) {
				this._nodeObj.destruct();
			}
			this._nodeObj = this._nodeId = null;
			// events if any
			if (this._nodeObjEv != null) {
				for (var q=0; qtbody
		while (r.childNodes.length > 0) r.removeChild(r.lastChild);
		
		r = null;
		
		this.itemData = {};
	}
	
	this.hide = function() {
		if (this.p.style.display != "none") {
			this.p.style.display = "none";
			window.dhx4.zim.clear(this.conf.zi);
			var id = this._lastId;
			this._lastId = null;
			this.callEvent("onHide",[id]);
		}
	}
	
	this.isVisible = function() {
		return (this.p.style.display == "");
	}
	
	this.itemData = {};
	
	this.getItemData = function(id) {
		if (!id) return this.itemData;
		if (this.itemData[id]) return this.itemData[id];
		return {};
	}
	
	this.setSkin = function(skin) {
		this.conf.skin = skin;
		this.p.className = "dhx_popup_"+this.conf.skin;
		if (this._nodeObj != null && typeof(this._nodeObj.setSkin) == "function") this._nodeObj.setSkin(this.conf.skin);
		this._repaint();
	}
	
	this.attachList = function(template, data) {
		
		this._setTemplate(template);
		
		this.clear();
		var r = this.p.firstChild.firstChild.firstChild; // table->tbody
		
		for (var q=0; qtbody
		
		var tr = document.createElement("TR");
		tr.className = "dhxnode";
		r.appendChild(tr);
		
		var td = document.createElement("TD");
		td.className = "dhx_popup_td";
		td.innerHTML = "";
		
		if (data.width) td.firstChild.style.width = data.width+"px";
		if (data.height) td.firstChild.style.height = data.height+"px";
		
		tr.appendChild(td);
		
		td = tr = r = null;
		
		if (typeof(this["_attach_init_"+mode]) == "function") {
			this["_attach_init_"+mode](data);
			this._enableIEVFix();
		}
		
		this._repaint();
		
		return this._nodeObj;
		
	}
	
	this.unload = function() {
		
		if (typeof(window.addEventListener) == "function") {
			window.removeEventListener("click", this._doOnClick, false);
			window.removeEventListener("keyup", this._doOnKeyUp, false);
			window.removeEventListener("unload", this._doOnUnload, false);
		} else {
			document.body.detachEvent("onclick", this._doOnClick, false);
			document.body.detachEvent("onkeyup", this._doOnKeyUp, false);
			document.body.detachEvent("onunload", this._doOnUnload, false);
		}
		
		this.clear();
		
		this._doOnClick = null;
		this._doOnUnload = null;
		this._doOnKeyUp = null;
		
		
		if (this.conf.toolbarEvent != null && this.conf.toolbar != null) {
			if (this.conf.toolbar.detachEvent != null) {
				// make sure toolbar wasn't unloaded
				this.conf.toolbar.detachEvent(this.conf.toolbarEvent);
			} else {
				this.conf.toolbar._getItemDim = null;
			}
		}
		
		if (this.conf.ribbonEvent != null && this.conf.ribbon != null) {
			if (this.conf.ribbon.detachEvent != null) {
				this.conf.ribbon.detachEvent(this.conf.ribbonEvent);
			} else {
				this.conf.ribbon._getItemDim = null;
			}
		}
		
		if (this.conf.slider) {
			for (var q=0; q= 0) {
				if (t.parentNode != null && t.parentNode.parentNode != null && t.parentNode.parentNode._idd != null) {
					id = t.parentNode.parentNode._idd;
					if (t.parentNode.parentNode._type == "ra") id = [t.parentNode.parentNode._group, t.parentNode.parentNode._value];
				}
			} else {
				// check if button, editor or combo
				var k = true;
				var f = false;
				while (k && !f) {
					var p = (t.className||"").toLowerCase();
					if (p.length > 0) f = (p == "dhxform_btn" || p.search(/dhxeditor_inside/gi) >= 0 || p == "dhxcombo_input" || p.search(/dhxcombolist/gi) >=0);
					t = t.parentNode;
					k = (t != null);
				}
				if (f) return;
			}
			t = null;
			if (id != null && that._idExists(id)) return;
		}
		if (that.isVisible() && that.callEvent("onBeforeHide",["click",e]) === true) {
			that.hide();
		}
	}
	this._doOnKeyUp = function(e) {
		e = e||event;
		if (e.keyCode == 27) {
			if (that.isVisible() && that.callEvent("onBeforeHide",["esc",e]) === true) {
				that.hide();
			}
		}
	}
	this._doOnUnload = function() {
		that.unload();
	}
	
	if (typeof(window.addEventListener) == "function") {
		window.addEventListener("click", this._doOnClick, false);
		window.addEventListener("keyup", this._doOnKeyUp, false);
		window.addEventListener("unload", this._doOnUnload, false);
	} else {
		document.body.attachEvent("onclick", this._doOnClick, false);
		document.body.attachEvent("onkeyup", this._doOnKeyUp, false);
		document.body.attachEvent("onunload", this._doOnUnload, false);
	}
	
	this._idExists = function(id) {
		var r = false;
		for (var q=0; q=0 || document.compatMode != "CSS1Compat"));
	
	// IE6 hover functionality
	this._IEHover = (this.conf.isIE && navigator.userAgent.search("MSIE 6.0")>=0);
	if (this._IEHover) {
		this._IEHoverInit = function() {
			this.p.onmouseover = function() {
				var t = event.srcElement;
				while (t != this && t._IEHover != true) t = t.parentNode;
				if (t._IEHover) {
					if (that._IEHoverTM) window.clearTimeout(that._IEHoverTM);
					if (that._lastIEHover == t) return;
					that._IEHoverRender(t);
					t = null;
				}
			}
			this.p.onmouseout = function() {
				if (that._IEHoverTM) window.clearTimeout(that._IEHoverTM);
				that._IEHoverTM = window.setTimeout(function(){that._IEHoverRender(null);},1);
			}
			this._IEHoverRender = function(t) {
				if (this._lastIEHover != null) {
					if (this._lastIEHover.className.search(/tr_hover/gi) >= 0) {
						this._lastIEHover.className = this._lastIEHover.className.replace(/\s{0,}tr_hover/gi, "");
						this._lastIEHover = null;
					}
				}
				if (t != null && t.className.search(/tr_hover/gi) < 0) {
					t.className += " tr_hover";
					that._lastIEHover = t;
				}
			}
			this._IEHoverInited = true;
		}
		this._IEHoverClear =  function() {
			this.p.onmouseover = null;
			this.p.onmouseout = null;
			this._IEHoverInited = false;
		}
	}
	
	// IE6/7/8 first/last-child
	this._IEFirstLast = (this.conf.isIE && navigator.userAgent.search(/MSIE [6,7,8]\.0/i)>=0);
	
	// IE6 visibility fix
	this._enableIEVFix = function() {
		if (this.conf.isIE && navigator.userAgent.search("MSIE 6.0") >= 0) {
			var e1 = this.attachEvent("onHide", function(){
				document.getElementById(this._nodeId).style.visibility = "hidden";
			});
			var e2 = this.attachEvent("onShow", function(){
				document.getElementById(this._nodeId).style.visibility = "visible";
			});
			if (this._nodeObjEv == null) this._nodeObjEv = [];
			this._nodeObjEv.push(e1,e2);
		}
	}
	
	// auto-init, toolbar mode
	if (typeof(window.dhtmlXToolbarObject) != "undefined" && this.conf.toolbar != null && this.conf.toolbar instanceof window.dhtmlXToolbarObject && this.conf.id != null) {
		
		if (!(this.conf.id instanceof Array)) this.conf.id = [this.conf.id];
		
		this.skinParent = this.conf.toolbar.conf.skin;
		
		this._doOnToolbarClick = function(id) {
			for (var q=0; q