CH.ns(function() {with(CH) {
	
	LightBox = Class.create({
	
		id: null, options:null, initialized:false,
		
		initialize: function(content_id, options) {
			this.id = content_id;
			this.setOptions(options);
			this.initialized = false;
	
			this._smartLoad(function() {
				if(this.id) {
					this._initOverlay();
					this._initLightbox();
					
					this.initialized = true;
				}
			}.bind(this));
		},
		
		_initOverlay: function() {
			this.overlayObj = document.createElement("div");
			this.overlayObj.setAttribute('id', 'overlay_' + this.id);
			this.overlayObj.className = this.options.overlay_class;
			this.overlayObj.style.display = 'none';
			this.overlayObj.style.position = 'absolute';
			this.overlayObj.style.top = '0';
			this.overlayObj.style.left = '0';
			this.overlayObj.style.zIndex = '100000';
			this.overlayObj.style.width = '100%';
			
			var hide = this.hide.bindAsEventListener(this);
			this.overlayObj.onclick = function () {hide(); return false;};
	
			document.body.insertBefore(this.overlayObj, document.body.firstChild);
	
		},
		
		_initLightbox: function() {
			var objBody = document.body;
			this.lightboxObj = $(this.id); // holds the original lightbox object
			
			this.lightboxObj.remove(); // remove the original lightbox div
			
			// add the required lightbox attributes
			this.lightboxObj.style.position = 'absolute';
			this.lightboxObj.style.zIndex = '100001';
			this.lightboxObj.style.display = 'none';
			
			objBody.insertBefore(this.lightboxObj, document.body.firstChild);
			
			var dim = this.lightboxObj.getDimensions(); // get the lightbox dimensions
	
			// determine the width and height values
			if(this.options.height) {
				this.options.height = this.options.height;
			} else {
				this.options.height = dim.height;
			}
			
			if(this.options.width) {
				this.options.width = this.options.width;
			} else {
				this.options.width = dim.width;
			}
	
			// set the height and width attributes
			if(this.options.fixedHeight)
				this.lightboxObj.style.height = this.options.height + 'px';
			
			if(this.options.fixedWidth)
				this.lightboxObj.style.width = this.options.width + 'px';
			
			delete objBody;
		},
		
		_getPageSize: function() {
			var xScroll, yScroll;
			
			if (window.innerHeight && window.scrollMaxY) {	
				xScroll = document.body.scrollWidth;
				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
				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 = windowWidth;
			} else {
				pageWidth = xScroll;
			}
		
			return {pageWidth: pageWidth ,pageHeight: pageHeight , windowWidth: windowWidth, windowHeight: windowHeight};
		},
		
		_getWindowScroll: function() {
			var T, L, W, H;
			var w = window;
			
			with (w.document) {
				if (w.document.documentElement && documentElement.scrollTop) {
					T = documentElement.scrollTop;
					L = documentElement.scrollLeft;
				} else if (w.document.body) {
					T = body.scrollTop;
					L = body.scrollLeft;
				}
				
				if (w.innerWidth) {
					W = w.innerWidth;
					H = w.innerHeight;
				} else if (w.document.documentElement && documentElement.clientWidth) {
					W = documentElement.clientWidth;
					H = documentElement.clientHeight;
				} else {
					W = body.offsetWidth;
					H = body.offsetHeight
				}
			}
			
			return { top: T, left: L, width: W, height: H };
		}, 
		
		setPosition: function(top, left) {
			this.lightboxObj.setStyle({top: top + 'px'});
			this.lightboxObj.setStyle({left: left + 'px'});
		},
		
		_rePosition: function(event) {
			this._position();
		},
		
		_position: function(topPos, leftPos) {
			var pageSize = this._getPageSize();
			var windowScroll = this._getWindowScroll(); 
			
			// ie sends bad events, hack
			if (this.pageSize && this.pageSize.windowWidth == pageSize.windowWidth && this.pageSize.windowHeight == pageSize.windowHeight && 
				this.windowScroll.left == windowScroll.left && this.windowScroll.top == windowScroll.top) {
					return;
			}
			
			var top, left;
				
			if(topPos) {
				top = topPos;
			} else {
				top = (windowScroll.top + this.options.offsetTop());
			}
			
			if(leftPos) {
				left = leftPos
			} else {
				left = (windowScroll.left + this.options.offsetLeft());
			}
			
			this.setPosition(top, left);
			
			delete pageSize;
			delete windowScroll;
			delete top;
			delete left;
	
		},
		
		show: function(topPos, leftPos) {
			this._smartWait(function() {
				// dynamically set the height of the overlay object depending on the page height
				this.overlayObj.style.height = (this._getPageSize().pageHeight + 'px');
				
				// position the startpoint for the lightbox
				this._position(topPos, leftPos);
				
				if(this.options.autoPosition) {
					// Set the scroll and resize event handelers
					this.rePosition = this._rePosition.bindAsEventListener(this);
				    Event.observe(window, "resize", this.rePosition);
				   	Event.observe(window, "scroll", this.rePosition);
				   	
				   	delete rePosition;
				}
	
				// hide all embeds, objects and iframes
				$$('embed', 'object', 'iframe').each(function(e) {
						e.style.visibility = 'hidden';
					});
		
				// display the overlay and lightbox
					this.overlayObj.style.display = 'block';
					this.lightboxObj.style.display = 'block';
		
			}.bind(this));
		},
		
		hide: function() {
			Event.stopObserving(window, "resize", this.rePosition);
			Event.stopObserving(window, "scroll", this.rePosition);
			
			this.overlayObj.style.display = 'none';
			this.lightboxObj.style.display = 'none';
			this.lightboxObj.style.opacity = 1; // reset the opacity
	
			// show all embeds, objects and iframes
			$$('embed', 'object', 'iframe').each(function(e) {
					e.style.visibility = 'visible';
				});
			
		},
		
		// waits until initialize has been set before running the requested functionality
		_smartWait: function(callback) {
			
			var ejector = 0; 
			
			var timer = setInterval(function() {
					
				if(this.initialized) {
					callback();	
					
					clearInterval(timer);
					delete timer;
					delete ejector;
					
				}
				
				// page isnt loading correctly, lets bail
				if(ejector >= 5000) {
					clearInterval(timer);
					delete timer;
					delete ejector;
				}
				
				ejector++;
			}.bind(this), 10);
		},
		
		// waits until the page is loaded before running the requested functionality
		_smartLoad: function(callback) {
			if (/WebKit|khtml/i.test(navigator.userAgent)) {
				var timer = setInterval(function() {
					if (/loaded|complete/.test(document.readyState)) {
						clearInterval(timer);
						delete timer;
						
						callback();
					}}, 10);
			} else if (document.addEventListener) {
				document.addEventListener('DOMContentLoaded', callback, false);
			} else {
				if(window.addEventListener) {
					window.addEventListener('load', callback, false);
				} else if (window.attachEvent) {
					
					var script = document.getElementById("__ie_onload_lightbox");
	
					if(!script) {
						document.write('<script id="__ie_onload_lightbox" defer src="' + ((location.protocol == 'https:') ? '//0' : 'javascript:void(0)') + '"><\/script>');;
						script = document.getElementById("__ie_onload_lightbox");
					}
					
					script.onreadystatechange = function() {
						if (this.readyState == "complete") {
							callback();
						}
					};
				}
			}
		},
		
		setOptions: function(options) {
			this.options = {
				overlay_class: 'overlay_modal',
				top: 0,
				left: 0,
				autoPosition: true,
				offsetTop: function() { var dim = this.lightboxObj.getDimensions(); return ((this._getPageSize().windowHeight/2) - (dim.height/2)); }.bind(this), // default center
				offsetLeft: function() { var dim = this.lightboxObj.getDimensions(); return (this._getPageSize().windowWidth/2) - (dim.width/2); }.bind(this), // default center
				fixedHeight: true,
				fixedWidth: true
			};
			Object.extend(this.options, options || {});
		}
	});
}});