var LightBox = Class.create();
LightBox.prototype = {
	
	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 = '1000';
		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 = '1001';
		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
		this.lightboxObj.style.height = this.options.height + 'px';
		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");

				if(!script) {
					document.write("<scr"+"ipt id=__ie_onload defer src=//0><\/scr"+"ipt>");
					script = document.getElementById("__ie_onload");
					
					script.onreadystatechange = function() {
						if (this.readyState == "complete") {
							callback();
						}
					};
				} else {
					callback();
				}
				
				
			}
		}
	},
	
	setOptions: function(options) {
		this.options = {
			overlay_class: 'overlay_modal',
			top: 0,
			left: 0,
			autoPosition: true,
			offsetTop: function() { return ((this._getPageSize().windowHeight/2) - (this.options.height/2));}.bind(this), // default center
			offsetLeft: function() { return (this._getPageSize().windowWidth/2) - (this.options.width/2)}.bind(this) // default center
		};
		Object.extend(this.options, options || {});
	}
};