Effects = {
	SetOpacity : function(element, opacity) {
		opacity = Math.floor(opacity);
		if(navigator.userAgent.indexOf('MSIE') > -1) {
			element.style.zoom = 1;
			element.style.filter = 'alpha(opacity=' + opacity + ')';
		}
		else
			element.style.opacity = opacity/100;
	},
	
	GetOpacity : function(element) {
		if(navigator.userAgent.indexOf('MSIE') > -1) {
			if(element.style.filter == '') return 100;
			new RegExp('.*opacity[\s=]+([0-9\.]+)').exec(element.style.filter);
			if(isNaN(RegExp.$1) || RegExp.$1 == '') return 100;
			else return RegExp.$1 * 1;
		}
		else
			if(isNaN(element.style.opacity) || element.style.opacity == '') return 100;
			else return element.style.opacity * 100;
	},
	
	Fade : function(element, opacity, fadetime, interval, callback, callbackObj, /* internal -> */ startTime, startOpac) {
		if(!startTime) {
			if(!interval) interval = 20;
			startOpac = Effects.GetOpacity(element);
			startTime = new Date();
		}
		var elapsed = new Date().getTime() - startTime.getTime();
		var perc = elapsed / fadetime;

		if(perc >= 1) {
			Effects.SetOpacity(element, opacity);
			if(callback) callback.call(callbackObj, element);
			return;
		}
		
		//var opac = startOpac + Math.round(perc * (opacity - startOpac));
		var opac = this.CalcSmoothDist(startOpac, opacity, perc);
		Effects.SetOpacity(element, opac);
		setTimeout(function() { Effects.Fade(element, opacity, fadetime, interval, callback, callbackObj, startTime, startOpac); }, interval);
	},
	
	SlideFromRelPosX : function(element, startX, endX, slidetime, interval, callback, callbackObj, /* internal -> */ startTime) {
		if(!startTime) {
			if(!interval) interval = 20;
			startTime = new Date();
		}
		var elapsed = new Date().getTime() - startTime.getTime();
		var perc = elapsed / slidetime;

		if(perc >= 1) {
			element.style.left = endX.toString() + 'px';
			if(callback) callback.call(callbackObj, element);
			return;
		}
		
		element.style.left = this.CalcSmoothDist(startX, endX, perc).toString() + 'px';
		setTimeout(function() { Effects.SlideFromRelPosX(element, startX, endX, slidetime, interval, callback, callbackObj, startTime); }, interval);
	},
	
	CalcSmoothDist : function(start, end, percent) {
		return start + (Math.cos(Math.PI + Math.PI * percent) / 2 + 0.5) * (end - start);
	},
	
	ShrinkHeight : function(element, slideTime, interval, callback, callbackObj, startTime) {
		if(!element.startHeight) {
			element.startHeight = element.offsetHeight;
		}
		
		if(!startTime) {
			if (element.style.overflow) {
				element.oldOverflow = element.style.overflow;
				element.style.overflow = 'hidden';
			}
			element.style.display = 'block';
			if(!interval) interval = 20;
			startTime = new Date();
		}
		
		var elapsed = new Date().getTime() - startTime.getTime();
		var perc = elapsed / slideTime;

		var height = this.CalcSmoothDist(element.startHeight, 0, perc);
		if(height <= 1 || perc >= 1) {
			element.style.display = 'none';
			if (element.style.overflow) {
				element.style.overflow = element.oldOverflow;
			}
			element.oldOverflow = null;
			if(callback) callback.call(callbackObj, element)
			return;
		}
		
		element.style.height = height.toString() +'px';
		setTimeout(function() { Effects.ShrinkHeight(element, slideTime, interval, callback, callbackObj, startTime); }, interval);
	},
	
	GrowHeight : function(element, slideTime, interval, callback, callbackObj, startTime) {
		if(!element.startHeight) {
			return;
		}
		
		if(!startTime) {
			if (element.style.overflow) {
				element.oldOverflow = element.style.overflow;
				element.style.overflow = 'hidden';
			}
			element.style.display = 'block';
			if(!interval) interval = 20;
			startTime = new Date();
		}
		
		var elapsed = new Date().getTime() - startTime.getTime();
		var perc = elapsed / slideTime;

		var height = this.CalcSmoothDist(0, element.startHeight, perc);
		if(height >= element.startHeight || perc >= 1) {
			element.style.height = element.startHeight;
			element.style.display = 'block';
			if (element.style.overflow) {
				element.style.overflow = element.oldOverflow;
			}
			element.oldOverflow = null;
			if(callback) callback.call(callbackObj, element);
			return;
		}
		
		element.style.height = height.toString() +'px';
		setTimeout(function() { Effects.GrowHeight(element, slideTime, interval, callback, callbackObj, startTime); }, interval);
	},
	
	ShrinkWidth : function(element, slideTime, interval, callback, callbackObj, startTime) {
		if(!element.startWidth) {
			element.startWidth = element.offsetWidth;
		}
		
		if(!startTime) {
			if (element.style.overflow) {
				element.oldOverflow = element.style.overflow;
				element.style.overflow = 'hidden';
			}
			element.style.display = 'block';
			if(!interval) interval = 20;
			startTime = new Date();
		}
		
		var elapsed = new Date().getTime() - startTime.getTime();
		var perc = elapsed / slideTime;

		var width = this.CalcSmoothDist(element.startWidth, 0, perc);
		if(width <= 1 || perc >= 1) {
			element.style.display = 'none';
			if (element.style.overflow) {
				element.style.overflow = element.oldOverflow;
			}
			element.oldOverflow = null;
			if(callback) callback.call(callbackObj, element);
			return;
		}
		
		element.style.width = width.toString() +'px';
		setTimeout(function() { Effects.ShrinkWidth(element, slideTime, interval, callback, callbackObj, startTime); }, interval);
	},
	
	GrowWidth : function(element, slideTime, interval, callback, callbackObj, startTime) {
		if(!element.startWidth) {
			return;
		}
		
		if(!startTime) {
			if (element.style.overflow) {
				element.oldOverflow = element.style.overflow;
				element.style.overflow = 'hidden';
			}
			element.style.display = 'block';
			if(!interval) interval = 20;
			startTime = new Date();
		}
		
		var elapsed = new Date().getTime() - startTime.getTime();
		var perc = elapsed / slideTime;

		var width = this.CalcSmoothDist(0, element.startWidth, perc);
		if(width >= element.startWidth || perc >= 1) {
			element.style.width = element.startWidth;
			element.style.display = 'block';
			if (element.style.overflow) {
				element.style.overflow = element.oldOverflow;
			}
			element.oldOverflow = null;
			if(callback) callback.call(callbackObj, element);
			return;
		}
		
		element.style.width = width.toString() +'px';
		setTimeout(function() { Effects.GrowWidth(element, slideTime, interval, callback, callbackObj, startTime); }, interval);
	},
	
	SlideIn : function(element, slideTime, interval, callback, callbackObj, startTime) {
		if(!element.startLeft) {
			element.startLeft = element.offsetLeft;
			element.w = element.offsetWidth / 2;
			element.endLeft = element.startLeft + element.w;
		}
		
		if(!startTime) {
			if(!interval) interval = 20;
			var startTime = new Date();
		}
		
		var elapsed = new Date().getTime() - startTime.getTime();
		var perc = elapsed / slideTime;

		var left = this.CalcSmoothDist(element.startLeft, element.endLeft, perc);
		if(left >= element.endLeft || perc >= 1) {
			element.style.left = element.endLeft;
			if(callback) callback.call(callbackObj, element);
			return;
		}
		
		element.style.left = left.toString() +'px';
		setTimeout(function() { Effects.SlideIn(element, slideTime, interval, callback, callbackObj, startTime); }, interval);
	},
	
	SlideOut : function(element, slideTime, interval, callback, callbackObj, startTime) {
		if(!element.startLeft) {
			return;
		}
		
		if(!startTime) {
			if(!interval) interval = 20;
			var startTime = new Date();
		}
		
		var elapsed = new Date().getTime() - startTime.getTime();
		var perc = elapsed / slideTime;
		var adjusted = element.startLeft - 1;

		var left = this.CalcSmoothDist(element.endLeft, adjusted, perc);
		if(left <= adjusted || perc >= 1) {
			element.style.left = element.startLeft;
			if(callback) callback.call(callbackObj, element);
			return;
		}
		
		element.style.left = left.toString() +'px';
		setTimeout(function() { Effects.SlideOut(element, slideTime, interval, callback, callbackObj, startTime); }, interval);
	},
	
	SlideDown : function(element, slideTime, interval, callback, callbackObj, startTime) {
		if(!element.startTop) {
			element.startTop = element.offsetTop;
			element.h = element.offsetHeight / 2;
			element.endTop = element.startTop + element.h;
		}
		
		if(!startTime) {
			if(!interval) interval = 20;
			var startTime = new Date();
		}
		
		var elapsed = new Date().getTime() - startTime.getTime();
		var perc = elapsed / slideTime;

		var top = this.CalcSmoothDist(element.startTop, element.endTop, perc);
		if(top >= element.endTop || perc >= 1) {
			element.style.top = element.endTop;
			if(callback) callback.call(callbackObj, element);
			return;
		}
		
		element.style.top = top.toString() +'px';
		setTimeout(function() { Effects.SlideDown(element, slideTime, interval, callback, callbackObj, startTime); }, interval);
	},
	
	SlideUp : function(element, slideTime, interval, callback, callbackObj, startTime) {
		if(!element.startTop) {
			return;
		}
		
		if(!startTime) {
			if(!interval) interval = 20;
			var startTime = new Date();
		}
		
		var elapsed = new Date().getTime() - startTime.getTime();
		var perc = elapsed / slideTime;
		var adjusted = element.startTop - 1;

		var top = this.CalcSmoothDist(element.endTop, adjusted, perc);
		if(top <= adjusted || perc >= 1) {
			element.style.top = element.startTop;
			if(callback) callback.call(callbackObj, element);
			return;
		}
		
		element.style.top = top.toString() +'px';
		setTimeout(function() { Effects.SlideUp(element, slideTime, interval, callback, callbackObj, startTime); }, interval);
	},
		
	LockElementPlacement : function(element) {
		//element.style.overflow = 'hidden';
		element.style.height = element.offsetHeight.toString() + 'px';
		element.style.width = element.offsetWidth.toString() + 'px';
		for(var i=0; i<element.childNodes.length; i++) {
			var e = element.childNodes[i];
			if(e.style.position == 'absolute') continue;
			if(e.nodeType == 3) {
				var span = document.createElement('span');
				span.innerHTML = e.nodeValue;
				element.replaceChild(span, e);
				e = span;
			}
			e.style.overflow = 'hidden';
			e.style.height = e.offsetHeight.toString() + 'px';
			e.style.width = e.offsetWidth.toString() + 'px';
			e.style.padding = '0';
			e.style.top = e.offsetTop + 'px';
			e.style.left = e.offsetLeft + 'px';
			e.style.position = 'absolute';
		}
		element.style.padding = '0';
	},
	
	ShowLoader : function(show) {
		try {
			if(SnapLayoutsManager) {
				if(show)
					SnapLayoutsManager.Freeze();
				else
					SnapLayoutsManager.UnFreeze();
			}
		} catch(e) { }
		if(show) {
			if(Effects.loaderVals)
				if(Effects.loaderVals.showing) return;
			Effects.loaderVals = [];
			Effects.loaderVals.overflowX = document.body.style.overflowX;
			Effects.loaderVals.overflowY = document.body.style.overflowY;
			Effects.loaderVals.overflow = document.body.style.overflow;
			Effects.loaderVals.scrollPos = this.GetWindowScrollPosition();
			Effects.loaderVals.showing = true;
			
			document.body.style.overflow = 'hidden';
			document.body.style.overflowX = 'hidden';
			document.body.style.overflowY = 'hidden';
			document.body.style.border = '0px solid red'; // IE6 bug workaround
			
			var bg = document.createElement('div');
			bg.id = 'effects_loader_bg';
			bg.style.position = 'absolute';
			bg.style.left = '0';
			bg.style.top = '0';
			bg.style.width = '100%';
			bg.style.height = '100%';
			bg.style.zIndex = '11000';
			bg.style.backgroundColor = 'black';
			
			pos = this.GetWindowScrollPosition();
			this.SetWindowScrollPosition(0);
			bg.style.top = pos + 'px';

			var img = document.createElement('img');
			img.src = $basePath + 'resources/templates/images/loading.gif';
			img.style.position = 'absolute';
			img.style.left = '50%';
			img.style.top = '50%';
			img.width = '32';
			img.height = '32';
			img.style.marginLeft = '-16px';
			img.style.marginTop = '-16px';
			bg.appendChild(img);
			document.body.appendChild(bg);
			Effects.SetOpacity(bg, 75);
		} else {
			if(!Effects.loaderVals) return;
			if(!Effects.loaderVals.showing) return;
			document.body.style.overflow = Effects.loaderVals.overflow;
			document.body.style.overflowX = Effects.loaderVals.overflowX;
			document.body.style.overflowY = Effects.loaderVals.overflowY;
			this.SetWindowScrollPosition(Effects.loaderVals.scrollPos);
			document.body.removeChild(document.getElementById('effects_loader_bg'));
			Effects.loaderVals = null;
		}
	},
	
	bg : null,
	ShowDialog : function(width, height, title, body, buttons) {
		if(this.bg) this.HideDialog();

		try {
			if(SnapLayoutsManager)
				SnapLayoutsManager.Freeze();
		} catch(e) { }
		
		Effects.dialogVals = [];
		Effects.dialogVals.overflowX = document.body.style.overflowX;
		Effects.dialogVals.overflowY = document.body.style.overflowY;
		Effects.dialogVals.overflow = document.body.style.overflow;
		Effects.dialogVals.showing = true;
		document.body.style.overflow = 'hidden';
		document.body.style.overflowX = 'hidden';
		document.body.style.overflowY = 'hidden';

		var bg = document.createElement('div');
		bg.style.position = 'absolute';
		bg.style.left = '0';
		bg.style.top = '0';
		bg.style.width = '100%';
		bg.style.height = '100%';
		bg.style.zIndex = '10000';
		bg.KeepTop = function() {
			if(this.bg == null) return;
			var pos; 
			if (window.innerHeight)
				pos = window.pageYOffset;
			else if (document.documentElement && document.documentElement.scrollTop)
				pos = document.documentElement.scrollTop;
			else if (document.body)
				pos = document.body.scrollTop;
			if(!this.parentNode) return;
			this.style.top = pos + 'px';
			this.timer = new Timer(50);
			this.timer.Elapsed.AddHandler(this.KeepTop, this);
			this.timer.RunOnce();
		}
		document.body.appendChild(bg);
		bg.KeepTop();
		Effects.bg = bg;

		var bg1 = document.createElement('div'); // fullscreen overlay
		bg1.style.backgroundColor = 'black';
		bg1.style.position = 'absolute';
		bg1.style.left = '0';
		bg1.style.top = '0';
		bg1.style.width = '100%';
		bg1.style.height = '100%';
		bg1.style.zIndex = '0';
		this.SetOpacity(bg1, 75);
		this.bg.appendChild(bg1);
		
		var bg2 = document.createElement('div'); // translucent dark border shadow
		this.SetOpacity(bg2, 30);
		bg2.style.backgroundColor = 'white';
		bg2.style.position = 'absolute';
		bg2.style.left = '50%';
		bg2.style.top = '50%';
		bg2.style.marginLeft = '-' + Math.floor((width + 24) / 2) + 'px';
		bg2.style.marginTop = '-' + Math.floor((height + 24) / 2) + 'px';
		bg2.style.width = (width + 24) + 'px';
		bg2.style.height = (height + 24) + 'px';
		bg2.style.zIndex = '1';
		this.bg.appendChild(bg2);
		
		var div = document.createElement('div'); // the main opaque background in which the dialog contents go
		div.id = 'dialog-container';
		div.style.backgroundColor = '#373841';
		div.style.position = 'absolute';
		div.style.left = '50%';
		div.style.top = '50%';
		div.style.marginLeft = '-' + Math.floor(width / 2) + 'px';
		div.style.marginTop = '-' + Math.floor(height / 2) + 'px';
		div.style.width = width + 'px';
		div.style.height = height + 'px';
		div.style.zIndex = '2';
		this.bg.appendChild(div);
		
		var div2 = document.createElement('div');
		div2.style.height = '36px';
		div2.style.padding = '21px 0 0 16px';
		div2.style.backgroundImage = 'url(' + $basePath + 'resources/templates/images/dialog-title.gif)';
		div2.style.fontSize = '16pt';
		div2.style.fontFamily = 'arial';
		div2.style.fontWeight = 'bold';
		div2.style.color = '#deff9d'
		div2.innerHTML = title;
		div.appendChild(div2);
		
		var close = document.createElement('a');
		close.id = 'dialog-close-button';
		close.href = 'javascript:void(0)';
		close.onclick = function() { Effects.HideDialog(); };
		close.style.width = '25px';
		close.style.height = '25px';
		close.style.backgroundImage = 'url(' + $basePath + 'resources/templates/images/close.gif)';
		close.onmouseover = function() { this.style.backgroundPosition = '0 -25px'; }
		close.onmouseout = function() { this.style.backgroundPosition = '0 0'; }
		close.style.position = 'absolute';
		close.style.top = '22px';
		close.style.right = '10px';
		div2.appendChild(close);
		
		var div3 = document.createElement('div');
		div3.id = 'dialog-html-container';
		var buttonsHeight = 30;
		var h = (buttons ? height - 57 - buttonsHeight : height - 57) - 32;
		var w = width - 32;
		div3.style.height = h + 'px';
		div3.style.width = w + 'px';
		div3.style.margin = '16px';
		div3.style.overflow = 'hidden';
		div3.style.color = 'white';
		div3.style.fontSize = '8pt';
		div3.style.fontFamily = 'verdana';
		if(body) {
			if(typeof(body) == 'object')
				div3.appendChild(body);
			else
				div3.innerHTML = body;
		}
		div.appendChild(div3);

		if(buttons) {
			var div4 = document.createElement('div');
			div4.style.textAlign = 'center';
			div4.style.width = w + 'px';
			div4.style.marginLeft = '16px';
			if(typeof(buttons) == 'object')
				div4.appendChild(buttons);
			else
				div4.innerHTML = buttons;
			div.appendChild(div4);
		}
	},
	
	HideDialog : function() {
		if(!Effects.dialogVals)
			return;
		try {
			if(SnapLayoutsManager)
				SnapLayoutsManager.UnFreeze();
		} catch(e) { }
		if(Effects.bg) {
			Effects.bg.style.display = 'none';
			Effects.bg.parentNode.removeChild(this.bg);
			Effects.bg = null;
			document.body.style.overflow = Effects.dialogVals.overflow;
			document.body.style.overflowX = Effects.dialogVals.overflowX;
			document.body.style.overflowY = Effects.dialogVals.overflowY;
			Effects.dialogVals = null;
		}
	},
	
	GetWindowHeight : function() {
		var windowHeight=0;
		if (typeof(window.innerHeight)=='number')
			windowHeight=window.innerHeight;
		else if (document.documentElement && document.documentElement.clientHeight)
			windowHeight= document.documentElement.clientHeight;
		else if (document.body && document.body.clientHeight)
			windowHeight=document.body.clientHeight;
		return windowHeight;
	},
	
	GetWindowWidth : function() {
		var windowWidth=0;
		if (typeof(window.innerWidth)=='number')
			windowWidth=window.innerWidth;
		else if (document.documentElement && document.documentElement.clientHeight)
			windowHeight= document.documentElement.clientHeight;
		else if (document.body && document.body.clientHeight)
			windowHeight=document.body.clientHeight;
		return windowWidth;
	},
	
	ScrollWindow : function(amount) {
		this.SetWindowScrollPosition(this.GetWindowScrollPosition() + amount);
	},
	
	GetWindowScrollPosition : function() {
		var pos = 0;
		if (window.innerHeight)
			pos = window.pageYOffset;
		else if (document.documentElement && document.documentElement.scrollTop)
			pos = document.documentElement.scrollTop;
		else if (document.body)
			pos = document.body.scrollTop;
		return pos;
	},
	
	SetWindowScrollPosition : function(y) {
		if (document.documentElement)
			document.documentElement.scrollTop = y;
		else if (document.body)
			document.body.scrollTop = y;
	}
}
