/******************************************************************************
 *	ShineBox JS, version 0.9												  *
 *	(c) 2008 Shine Advertising Co., LLC										  *
 *	http://www.shinenorth.com												  *
 ******************************************************************************/

var ShineBox = {
	boxes: {},
	
	status: {
		ready: false,
		animating: false,
		open: false,
		slow: false,
		box: false,
		initialOffsetTop: 0,
		initialOffsetLeft: 0,
		initialWidth: 0,
		initialHeight: 0,
		finalOffsetTop: 0,
		finalOffsetLeft: 0,
		finalWidth: 0,
		finalHeight: 0
	},

	tools: {
		getOffsetTop: function(element) {
			var offsetTop = 0;
			element = $(element);
			while(element != null) {
				offsetTop += element.offsetTop;
				element = element.offsetParent;
			}
			return offsetTop;
		},
		getOffsetLeft: function(element) {
			var offsetLeft = 0;
			element = $(element);
			while(element != null) {
				offsetLeft += element.offsetLeft;
				element = element.offsetParent;
			}
			return offsetLeft;
		},
		getWidth: function(element) {
			return $(element).clientWidth;
		},
		getHeight: function(element) {
			return $(element).clientHeight;
		},
		getWindowWidth: function() {
			return (window.innerWidth || (window.document.documentElement.clientWidth || window.document.body.clientWidth));
		},
		getWindowHeight: function() {
			return (window.innerHeight || (window.document.documentElement.clientHeight || window.document.body.clientHeight));
		},
		getWindowOffsetTop: function() {
			return (window.pageYOffset || (window.document.documentElement.scrollTop || window.document.body.scrollTop));
		},
		getWindowOffsetLeft: function() {
			return (window.pageXOffset || (window.document.documentElement.scrollLeft || window.document.body.scrollLeft));
		}
	},
	
	setup: function() {
		if(!ShineBox.status.ready) {
			document.observe('keyup', function(event) {
				if(ShineBox.status.open && event.keyCode == Event.KEY_ESC) {
					ShineBox.hide();
				}
			});
			
			document.observe('mousedown', function(event) {
				ShineBox.status.slow = event.shiftKey;
			});
			
			document.observe('mouseup', function(event) {
				ShineBox.status.slow = event.shiftKey;
			});
			
			window.onresize = function() {
				if(ShineBox.status.open) {
					ShineBox.status.finalOffsetTop = Math.round(ShineBox.tools.getWindowHeight() / 2) - Math.round(ShineBox.boxes[ShineBox.status.box].options.height / 2) + ShineBox.tools.getWindowOffsetTop();
					ShineBox.status.finalOffsetLeft = Math.round(ShineBox.tools.getWindowWidth() / 2) - Math.round(ShineBox.boxes[ShineBox.status.box].options.width / 2) + ShineBox.tools.getWindowOffsetLeft();

					ShineBox.boxes[ShineBox.status.box].container.style.top = ShineBox.status.finalOffsetTop + 'px';
					ShineBox.boxes[ShineBox.status.box].container.style.left = ShineBox.status.finalOffsetLeft + 'px';
				}
			}
			
			window.onscroll = function() {
				if(ShineBox.status.open) {
					ShineBox.status.finalOffsetTop = Math.round(ShineBox.tools.getWindowHeight() / 2) - Math.round(ShineBox.boxes[ShineBox.status.box].options.height / 2) + ShineBox.tools.getWindowOffsetTop();
					ShineBox.status.finalOffsetLeft = Math.round(ShineBox.tools.getWindowWidth() / 2) - Math.round(ShineBox.boxes[ShineBox.status.box].options.width / 2) + ShineBox.tools.getWindowOffsetLeft();

					ShineBox.boxes[ShineBox.status.box].container.style.top = ShineBox.status.finalOffsetTop + 'px';
					ShineBox.boxes[ShineBox.status.box].container.style.left = ShineBox.status.finalOffsetLeft + 'px';
				}
			}
			
			ShineBox.status.ready = true;
		}
	},
	
	addBox: function(label, containerElement, contentElement) {
		if(!ShineBox.status.ready) {
			ShineBox.setup();
		}
	
		ShineBox.boxes[label] = {
			container: $(containerElement),
			content: $(contentElement),
			options: {}
		};
		
		var options = (arguments.length > 3 ? arguments[3] : {});
		
		if(options.width) {
			$(containerElement).style.width = options.width;
		}
		
		if(options.height) {
			$(containerElement).style.height = options.height;
		}
		
		//hide the container and set width/height
		new Effect.Opacity(contentElement, {
			duration: 0,
			to: 0,
			afterFinish: function(){
				$(containerElement).style.display = '';
				$(containerElement).style.position = 'absolute';
				$(containerElement).style.overflow = 'hidden';
				ShineBox.boxes[label].options.width = ShineBox.tools.getWidth(containerElement);
				ShineBox.boxes[label].options.height = ShineBox.tools.getHeight(containerElement);
				ShineBox.boxes[label].options.innerHTML = $(contentElement).innerHTML;
				$(containerElement).style.display = 'none';
				$(contentElement).innerHTML = '';
			}
		});	
	},
	
	show: function(element, label) {
		if(!ShineBox.status.ready) {
			ShineBox.setup();
		}
	
		if(!ShineBox.status.animating) {
			if(!ShineBox.status.open) {
				ShineBox.status.animating = true;
			
				ShineBox.status.box = label;
				ShineBox.status.initialOffsetTop = ShineBox.tools.getOffsetTop(element);
				ShineBox.status.initialOffsetLeft = ShineBox.tools.getOffsetLeft(element);
				ShineBox.status.initialWidth = ShineBox.tools.getWidth(element);
				ShineBox.status.initialHeight = ShineBox.tools.getHeight(element);
				ShineBox.status.finalOffsetTop = Math.round(ShineBox.tools.getWindowHeight() / 2) - Math.round(ShineBox.boxes[label].options.height / 2) + ShineBox.tools.getWindowOffsetTop();
				ShineBox.status.finalOffsetLeft = Math.round(ShineBox.tools.getWindowWidth() / 2) - Math.round(ShineBox.boxes[label].options.width / 2) + ShineBox.tools.getWindowOffsetLeft();
				ShineBox.status.finalWidth = ShineBox.boxes[label].options.width;
				ShineBox.status.finalHeight = ShineBox.boxes[label].options.height;
				
				//move container into default position
				ShineBox.boxes[label].container.style.top = ShineBox.status.initialOffsetTop + "px";
				ShineBox.boxes[label].container.style.left = ShineBox.status.initialOffsetLeft + "px";
				ShineBox.boxes[label].container.style.height = ShineBox.status.initialHeight + "px";
				ShineBox.boxes[label].container.style.width = ShineBox.status.initialWidth + "px";
				
				new Effect.Parallel([
					new Effect.Appear(ShineBox.boxes[label].container, {
						sync: true
					}),
					new Effect.Morph(ShineBox.boxes[label].container, {
						style: {
							width: ShineBox.status.finalWidth + "px",
							height: ShineBox.status.finalHeight + "px",
							top: ShineBox.status.finalOffsetTop + "px",
							left: ShineBox.status.finalOffsetLeft + "px"
						},
						sync: true
					})
				], {
					duration: (ShineBox.status.slow ? 5 : 0.6),
					afterFinish: function(effect) {
						new Effect.Opacity(ShineBox.boxes[label].content, {
							duration: 0.3,
							to: 1,
							beforeStart: function(effect) {
								ShineBox.boxes[label].content.innerHTML = ShineBox.boxes[label].options.innerHTML;
							},
							afterFinish: function(effect) {
								ShineBox.status.animating = false;
								ShineBox.status.open = true;
							}
						});
					}
				});
			} else {
				if(ShineBox.status.box != label) {
					ShineBox.swap(element, label);
				}
			}
		}
	},
	
	hide: function() {
		if(!ShineBox.status.ready) {
			ShineBox.setup();
		}
	
		if(!ShineBox.status.animating) {
			if(ShineBox.status.open) {
				ShineBox.status.animating = true;
				
				new Effect.Opacity(ShineBox.boxes[ShineBox.status.box].content, {
					duration: 0.3,
					to: 0,
					afterFinish: function(effect) {
						new Effect.Parallel([
							new Effect.Morph(ShineBox.boxes[ShineBox.status.box].container, {
								style: {
									width: ShineBox.status.initialWidth + "px",
									height: ShineBox.status.initialHeight + "px",
									top: ShineBox.status.initialOffsetTop + "px",
									left: ShineBox.status.initialOffsetLeft + "px"
								},
								sync: true
							}),
							new Effect.Fade(ShineBox.boxes[ShineBox.status.box].container, {
								sync: true
							})
						], {
							duration: (ShineBox.status.slow ? 5 : 0.6),
							beforeStart: function(effect) {
								ShineBox.boxes[ShineBox.status.box].content.innerHTML = '';
							},
							afterFinish: function(effect) {
								ShineBox.status.animating = false;
								ShineBox.status.open = false;
							}
						});
					}
				});
			}
		}
	},
	
	swap: function(element, label) {
		if(!ShineBox.status.ready) {
			ShineBox.setup();
		}
	
		if(!ShineBox.status.animating) {
			ShineBox.status.animating = true;
			
			var openBox = ShineBox.status.box;
			var openInitialWidth = ShineBox.status.initialWidth;
			var openInitialHeight = ShineBox.status.initialHeight;
			var openInitialOffsetTop = ShineBox.status.initialOffsetTop;
			var openInitialOffsetLeft = ShineBox.status.initialOffsetLeft;
			
			ShineBox.status.box = label;
			ShineBox.status.initialOffsetTop = ShineBox.tools.getOffsetTop(element);
			ShineBox.status.initialOffsetLeft = ShineBox.tools.getOffsetLeft(element);
			ShineBox.status.initialWidth = ShineBox.tools.getWidth(element);
			ShineBox.status.initialHeight = ShineBox.tools.getHeight(element);
			ShineBox.status.finalOffsetTop = Math.round(ShineBox.tools.getWindowHeight() / 2) - Math.round(ShineBox.boxes[label].options.height / 2);
			ShineBox.status.finalOffsetLeft = Math.round(ShineBox.tools.getWindowWidth() / 2) - Math.round(ShineBox.boxes[label].options.width / 2);
			ShineBox.status.finalWidth = ShineBox.boxes[label].options.width;
			ShineBox.status.finalHeight = ShineBox.boxes[label].options.height;
			
			//move container into default position
			ShineBox.boxes[label].container.style.top = ShineBox.status.initialOffsetTop + "px";
			ShineBox.boxes[label].container.style.left = ShineBox.status.initialOffsetLeft + "px";
			ShineBox.boxes[label].container.style.height = ShineBox.status.initialHeight + "px";
			ShineBox.boxes[label].container.style.width = ShineBox.status.initialWidth + "px";
			
			new Effect.Opacity(ShineBox.boxes[openBox].content, {
				duration: 0.3,
				to: 0,
				afterFinish: function(effect) {
					new Effect.Parallel([
						new Effect.Morph(ShineBox.boxes[openBox].container, {
							style: {
								width: openInitialWidth + "px",
								height: openInitialHeight + "px",
								top: openInitialOffsetTop + "px",
								left: openInitialOffsetLeft + "px"
							},
							sync: true
						}),
						new Effect.Fade(ShineBox.boxes[openBox].container, {
							sync: true
						}),
						new Effect.Appear(ShineBox.boxes[label].container, {
							sync: true
						}),
						new Effect.Morph(ShineBox.boxes[label].container, {
							style: {
								width: ShineBox.status.finalWidth + "px",
								height: ShineBox.status.finalHeight + "px",
								top: ShineBox.status.finalOffsetTop + "px",
								left: ShineBox.status.finalOffsetLeft + "px"
							},
							sync: true
						})
					], {
						duration: (ShineBox.status.slow ? 5 : 0.6),
						beforeStart: function(effect) {
							ShineBox.boxes[openBox].content.innerHTML = '';
						},
						afterFinish: function(effect) {
							new Effect.Opacity(ShineBox.boxes[label].content, {
								duration: 0.3,
								to: 1,
								beforeStart: function(effect) {
									ShineBox.boxes[label].content.innerHTML = ShineBox.boxes[label].options.innerHTML;
								},
								afterFinish: function(effect) {
									ShineBox.status.animating = false;
									ShineBox.status.open = true;
								}
							});
						}
					});
				}
			});
		}
	}
}
