﻿var Accordion = Class.create({
	/* Setup
	 * 1. Triggers: h2.acc_trigger
	 * 2. Contents: div.acc_content_wrapper
	 * 3. Instantiate Accordion:
	 *	a. new Accordion($$('div.accordion')[0])
	 *	b. new Accordion("my-accordion")
	 *	c. new Accordion(elementOrId, {options...})
	 */
	initialize: function(wrapper, options) {
		this.options = Object.extend({
			toggleIndependence: false,
			defaultOpenPanel: 0, // Index|Trigger Element|"all"|-1 
			onOpen: "accordion:open",
			onClose: "accordion:close",
			triggerSelector: "h2.acc_trigger",
			contentSelector: "div.acc_content_wrapper",
			duration: 0.5
		}, options || {});
		
		this.animating = 0;
		this.wrapper = $(wrapper);
		this.triggers = this.wrapper.select(this.options.triggerSelector);
		this.contents = this.wrapper.select(this.options.contentSelector);
		
		if (this.options.defaultOpenPanel == "all") {
			this.options.toggleIndependence = true;
		}
		
		for (var i=0; i<this.triggers.length; i++) {
			this.triggers[i].observe("click", this.__triggerClick.bind(this));
			this.contents[i].down().childElements().last().style.marginBottom = "0";
			if (i === this.options.defaultOpenPanel
				|| this.triggers[i] == this.options.defaultOpenPanel
				|| this.options.defaultOpenPanel == "all") {
				this.triggers[i].addClassName("open");
			} else {
				this.contents[i].hide();
			}
		}
	},
	open: function(trigger) {
		this.animating++;
		// Search for and close previously opened panel, if necessary
		if (!this.options.toggleIndependence) {
			var previously = this.wrapper.down(this.options.triggerSelector + ".acc_trigger.open");
			if (previously) {
				this.close(previously);
			}
		}
		trigger = (typeof trigger == "number") ? this.triggers[trigger] : trigger ;
		var div = trigger.next().show().setStyle("height: auto;");
		var height = div.getHeight();
		div.setStyle({height: "0px", overflow: "hidden"});
		div.morph('height: ' + height + 'px', {
			duration: this.options.duration,
			afterFinish: function(fx) {
				fx.element.previous().addClassName("open");
				fx.element.style.height = "auto";
				this.animating--;
				this.wrapper.fire(this.options.onOpen, {accordion: this, trigger: fx.element.previous(), panel: fx.element});
			}.bind(this)
		});
	},
	close: function(trigger) {
		this.animating++;
		trigger = (typeof trigger == "number") ? this.triggers[trigger] : trigger ;
		var div = trigger.next().show().setStyle({height: "auto", overflow: "hidden"});
		var height = div.getHeight();
		div.style.height = height + "px";
		div.morph('height: 0px', {
			duration: this.options.duration,
			afterFinish: function(fx) {
				fx.element.previous().removeClassName("open");
				this.animating--;
				this.wrapper.fire(this.options.onClose, {accordion: this, trigger: fx.element.previous(), panel: fx.element});
			}.bind(this)
		});
	},
	toggle: function(trigger) {0
		trigger = (typeof trigger == "number") ? this.triggers[trigger] : trigger ;
		var method = (trigger.hasClassName("open")) ? "close" : "open" ;
		this[method](trigger);
	},
	getIndex: function(triggerOrPanel) {
		if (typeof triggerOrPanel == "number") {
			return triggerOrPanel;
		}
		for (var i=0; i<this.triggers.length; i++) {
			if (triggerOrPanel == this.triggers[i] || triggerOrPanel == this.contents[i]) {
				return i;
			}
		}
		return -1;
	},
	__triggerClick: function(e) {
		if (this.animating) {
			return;
		}
		var element = e.element();
		
		// If the clicked trigger is not open
		if (!element.hasClassName("open")) {
			this.open(element);
		} else {
			this.close(element);
		}
	}
});

var BoxBox = {
	browser: {},
	overlay: null,
	isOverlayOn: false,
	overlayFX: null,
	window: null,
	isOpen: false,
	clickTriggers: [],
	options: {
		overlayColor: "#000",
		overlayOpacity: 0.6,
		fadeDuration: 0.25,
		resizeDuration: 0.25,
		width: 500,
		height: 300,
		sizeToContent: false, // TODO: make this better
		clickTriggerClass: null
	},
	initialize: function(options) { // TODO: allow re-initialization with new options
		if (this.initialized) { return this; }
		this.initialized = true;

		this.options = Object.extend(this.options, options || {});
		
		this.detectBrowser();

		/* !!! KH EDITS */		
		// Create BoxBox container
		this.container = $(document.forms[0]).appendChild(
			new Element("div", {id: "boxbox_container"})
		);
		
		// Create Overlay
		this.overlay = $('boxbox_container').appendChild(
			new Element("div", {id: "boxbox_overlay", style: "display:none;"})
		);
		// Create Window
		this.window = $('boxbox_container').appendChild(
			new Element("div", {id: "boxbox_window", style: "display:none;"})
		);
		/* !!! END KH EDITS */

		var bodyTarget = this.window;
		if (this.options.skin && this.options.skinBodyTarget) {
			this.window.update(this.options.skin);
			bodyTarget = this.window.down("#"+this.options.skinBodyTarget);
		}

		// Create Window
		this.body = bodyTarget.appendChild(
			new Element("div", {id: "boxbox_body"})
		);
		
		// Ensure Resize updates
		Event.observe(window, "resize", this.__resize.bindAsEventListener(this));
		
		// Ensure Scroll updates
		// Event.observe(window, "scroll", this.__scroll.bindAsEventListener(this));
		
		if (this.clickTriggerClass) {
			this.findTriggers();
		}

		// Close when overlay is clicked
		Event.observe(this.overlay, "click", this.__overlayClick.bindAsEventListener(this));
		
		// When fade-in starts
		document.observe("boxbox:fadeInStart", this.__fadeInStart.bindAsEventListener(this));
		// When fade-in completes
		document.observe("boxbox:fadeInComplete", this.__fadeInComplete.bindAsEventListener(this));
		
		// When fade-out begins
		document.observe("boxbox:fadeOutStart", this.__fadeOutStart.bindAsEventListener(this));
		// When fade-out completes
		document.observe("boxbox:fadeOutComplete", this.__fadeOutComplete.bindAsEventListener(this));

		return this;
	},
	
	//
	// EVENT HANDLERS
	//
	
	__resize: function(e) {
		this.resizeIntId = null;
		
		var resize = function() {
			// Delay keeps IE from persisting overlay width when making browser skinnier
			clearInterval(BoxBox.resizeIntId);
			BoxBox.resizeIntId = null;
			this.resizeOverlay();
			// this.resizeContent(optimal_height, optimal_width);
			this.center();
		};
		
		this.resizeIntId = setInterval(resize.bind(this), 25);
	},
	__scroll: function(e) {
		// TODO: handle horizontal scrolling
		this.centerVertically();
		this.overlay.style.top = document.documentElement.scrollTop + "px";
		this.resizeOverlay();
	},
	__overlayClick: function(e) {
		e.stop();
		this.close();
	},
	__fadeInStart: function(e) {
		//console.log("Overlay fade in has begun.");
	},
	__fadeInComplete: function(e) {
		//console.log("Overlay fade in complete.");
		this.showWindow();
	},
	__fadeOutStart: function(e) {
		//console.log("Overlay fade-out has begun.");
		if (this.contentSource) {
			this.contentSource.insert(this.body.firstChild);
		}
	},
	__fadeOutComplete: function(e) {
		//console.log("Overlay fade-out complete.");
	},
	__triggerDomEvent: function(e, eventName) {
		e.stop(); // TODO: don't stop events when no need to (non A, Button, etc)
		var target = null;
		var link = e.findElement("A");
		
		if (link.href.match(/\.(jpg|gif|png)$/i)) {
			// Open up linked image
			var img = new Image();
			img.src = link.href;
			BoxBox.open(img);
		}
		
		return;		
		
		if (link) { // Try link href first
			target = link.href.split("#")[1];
		}
		if (target == null) {
			target = e.element().readAttribute("rel");
		}
		if (target) {
			target = $(target);
			if (target) {
				BoxBox.open($(target));
			}
		}
	},
	
	//
	// "PUBLIC" API METHODS
	//

	open: function(content, options) { // TODO: enable temp override options
		if(this.isOpen) return; // already open
		this.isOpen = true;
		this.showOverlay();
		this.contentToLoad = content; // Might need to re-center after content loaded
	},
	
	close: function() {
		if (!this.isOpen) return;
		this.isOpen = false;
		document.fire("boxbox:close");
		this.hideWindow();
		this.hideOverlay();
	},
	
	resize: function(width, height) {
		this.setWidth(width);
		this.setHeight(height);
	},
	
	resizeToContent: function() {
		var ow = this.body.getWidth();
		var oh = this.body.getHeight();
		this.body.setStyle({
			width: "auto",
			height: "auto",
			position: "absolute"
		});
		var dims = this.body.getDimensions();
		this.body.setStyle({
			width: ow + "px",
			height: oh + "px",
			position: "static"
		});
		if (Prototype.Browser.IE) {
			dims.width += 3;
		}
		this.resize(dims.width, dims.height);
	},
	
	setWidth: function(width) {
		this.body.morph({width: width+"px"},{
			duration: this.options.resizeDuration,
			afterUpdate: function(e) {
				BoxBox.centerHorizontally();
			},
			queue: { position: 'end', scope: 'boxbox' }
		});
	},
	
	setHeight: function(height) {
		this.body.morph({height: height+"px"}, {
			duration: this.options.resizeDuration,
			afterUpdate: function(e) {
				//BoxBox.centerVertically();
				BoxBox.adjustHeight();
			},
			queue: { position: 'front', scope: 'boxbox' }
		});
		
	},
	
	findTriggers: function(CssSelector, sDomEventName) {
		var selector = (CssSelector) ? CssSelector : this.clickTriggerClass ;
		var eventName = (sDomEventName) ? sDomEventName : "click" ;
		if (selector) {
			$$(selector).each(function(t, i) {
				if (!BoxBox.clickTriggers.include(t)) {
					BoxBox.clickTriggers.push(t);
					t.observe(eventName, BoxBox.__triggerDomEvent.bindAsEventListener(BoxBox, eventName));
				}
			});
		}
	},

	//
	// WINDOW
	//
	
	showWindow: function() {
		// this.showLoader();	// starts loader within empty window
		this.loadContent();
		this.container.setStyle({
			visibility: "visible"
		});
		this.window.setStyle({
			display: "block",
			visibility: "visible",
			position: "absolute"
		});

		var w = (this.options.sizeToContent) ? this.body.getWidth() : this.options.width ;
		var h = (this.options.sizeToContent) ? this.body.getHeight() : this.options.height ;
		
		this.body.setStyle({
			width: w + "px",
			height: h + "px"
		});

		this.center();
		document.fire("boxbox:open");
	},
	
	hideWindow: function() {
		
		/* !!! KH EDITS: Animate the window / body to get rid of weird fragmented closing event in Firefox */
		this.hideWinFX = new Effect.Fade(this.window, {
			duration: 0.1
		});
		
		this.hideBodyFx = new Effect.Fade(this.body, {
			duration: 0.1,
			afterFinish: function(e) {
				this.body.setStyle('display:block');
			}.bind(this)			
		});
				
		this.container.setStyle({
			visibility: "hidden"
		});
	},
	
	loadContent: function() { // Overload this with optional content arg
		this.contentSource = null;
		var content = (this.contentToLoad) ? this.contentToLoad : "" ;
		if (typeof content == "string") {
			this.body.innerHTML = content;
		} else if (typeof content.nodeName != "undefined") {
			this.body.update();
			this.contentSource = $(content.parentNode);
			this.body.insert(content);
		}
		document.fire("boxbox:contentloaded");
	},
	
	center: function() {
		this.centerHorizontally();
		this.centerVertically();
	},
	
	centerHorizontally: function(){
		var scroll = document.documentElement.scrollLeft;
		var s_left = scroll + Math.round((this.getViewportWidth() - (this.window.offsetWidth || 0)) / 2);
		this.window.setStyle({left: s_left + 'px'});
	},

	centerVertically: function(){
		// TODO: make sure bottom edge doesn't go past this.getViewportHeight()
		//var scroll = document.documentElement.scrollTop;
		//var s_top = scroll + Math.round((this.getViewportHeight() - (this.window.offsetHeight || 0)) / 2);
		var s_top = Math.round((this.getViewportHeight() - (this.window.offsetHeight || 0)) / 2);
		if (s_top < 20) {
			s_top = 20; // leave some room at the top
		}
		this.window.setStyle({top: s_top + 'px'});
	},
	
	adjustHeight: function() {
		//var scroll = document.documentElement.scrollTop;
		//var s_top = scroll + Math.round((this.getViewportHeight() - (this.window.offsetHeight || 0)) / 2);
		var s_top = Math.round((this.getViewportHeight() - (this.window.offsetHeight || 0)) / 2);
		if (s_top < 20) {
			s_top = 20; // leave some room at the top
		}		
		this.window.morph({top: s_top+"px"}, {
			duration: this.options.resizeDuration
		});		
	},
	
	//
	// OVERLAY
	//
	
	resizeOverlay: function(){
		this.overlay.setStyle({
			height: '100%',
			width: '100%'
		});
		if(!this.browser.isSafari3){
			// Safari3 includes vertical scrollbar in this.getDocumentWidth()!
			// Leave overlay width at 100% for now...
			this.overlay.setStyle({width: this.getDocumentWidth() + 'px'});
		}
	},
	
	toggleOverlay: function() { // Change to custom event
		var method = (this.isOverlayOn) ? "hide" : "show" ;
		this[method + "Overlay"]();
	},

	showOverlay: function() {
		if (this.overlayFX && this.overlayFX.state == "running") {
			return; // keep from animating when already doing so
		}
		
		document.fire("boxbox:fadeInStart");
		
		var options = this.options;
		
		this.overlay.setOpacity(0);
		this.isOverlayOn = true;
		
		this.resizeOverlay(); // size the overlay before showing
		var onFadeInCompleteEvent = "boxbox:fadeInComplete";
		
		if (this.browser.overlayRequiresImage) { // TODO (may be an IE6 thing) !!!!!!!!!!!!!!!!!
			this.overlay.setStyle({
				visibility: 'visible',
				backgroundColor: 'transparent',
				backgroundImage: 'url(' + options.assetURL + options.overlayBgImage + ')',
				backgroundRepeat: 'repeat',
				opacity: 1
			});
			document.fire(onFadeInCompleteEvent);
		} else {
			this.overlay.setStyle({
				visibility: 'visible',
				backgroundColor: options.overlayColor
			});
			this.overlayFX = new Effect.Appear(this.overlay, {
				to: options.overlayOpacity,
				duration: options.fadeDuration,
				afterFinish: function(e) {
					document.fire(onFadeInCompleteEvent, e);
				}.bind(this)
			});
		}
	},
	
	hideOverlay: function() {
		if (this.overlayFX && this.overlayFX.state == "running") {
			return; // keep from animating when already doing so
		}
		
		document.fire("boxbox:fadeOutStart");
		
		var options = this.options;
		var onFadeOutCompleteEvent = "boxbox:fadeOutComplete";
		
		if (this.browser.overlayRequiresImage) { // TODO
			this.overlay.setStyle('visibility', 'hidden');
			document.fire(onFadeOutCompleteEvent);
			this.isOverlayOn = false;
		} else {
			this.overlayFX = new Effect.Fade(this.overlay, {
				duration: options.fadeDuration,
				afterFinish: function(e) {
					this.isOverlayOn = false;
					document.fire(onFadeOutCompleteEvent, e);
				}.bind(this)
			});
		}
	},
	
	//
	// DIMENSIONS
	//
	
	getViewportWidth: function() { // !!! SB
		var width = window.innerWidth; // Safari
		var mode = document.compatMode;
		if(mode || isIE){
			width = this.browser.isStrict ? document.documentElement.clientWidth : document.body.clientWidth;
		}
		return width;
	},
	getViewportHeight: function() { // !!! SB
		var height = window.innerHeight; // Safari
		var mode = document.compatMode;
		if((mode || this.browser.isIE) && !this.browser.isOpera){
			height = this.browser.isStrict ? document.documentElement.clientHeight : document.body.clientHeight;
		}
		return height;
	},
	getDocumentWidth: function() {
		var scrollWidth = this.browser.isStrict ? document.documentElement.scrollWidth : document.body.scrollWidth;
		return Math.max(scrollWidth, this.getViewportWidth());
	},
	getDocumentHeight: function() {
		var scrollHeight = this.browser.isStrict ? document.documentElement.scrollHeight : document.body.scrollHeight;
		return Math.max(scrollHeight, this.getViewportHeight());
	},
	
	detectBrowser: function() {
		// TODO: use a global browser detect instead
		var b = this.browser;
		b.ua = navigator.userAgent.toLowerCase();
		b.isStrict = document.compatMode == 'CSS1Compat';
		b.isOpera = b.ua.indexOf("opera") > -1;
		b.isIE = b.ua.indexOf('msie') > -1;
		b.isIE7 = b.ua.indexOf('msie 7') > -1;
		b.isBorderBox = b.isIE && !b.isStrict;
		b.isSafari = (/webkit|khtml/).test(b.ua);
		b.isSafari3 = b.isSafari && !!(document.evaluate);
		b.isGecko = !b.isSafari && b.ua.indexOf('gecko') > -1;
		b.isWindows = (b.ua.indexOf('windows') != -1 || b.ua.indexOf('win32') != -1);
		b.isMac = (b.ua.indexOf('macintosh') != -1 || b.ua.indexOf('mac os x') != -1);
		b.isLinux = (b.ua.indexOf('linux') != -1);
		
		b.overlayRequiresImage = false; // TODO: actually check this
	}
}

/* OLD
var BoxBox = {
	browser: {},
	overlay: null,
	isOverlayOn: false,
	overlayFX: null,
	window: null,
	isOpen: false,
	clickTriggers: [],
	options: {
		overlayColor: "#000",
		overlayOpacity: 0.6,
		fadeDuration: 0.25,
		resizeDuration: 0.25,
		width: 500,
		height: 300,
		sizeToContent: false, // TODO: make this better
		clickTriggerClass: null
	},
	initialize: function(options) { // TODO: allow re-initialization with new options
		if (this.initialized) { return this; }
		this.initialized = true;
		
		this.options = Object.extend(this.options, options || {});
		
		this.detectBrowser();
		
		// Create Overlay
		this.overlay = $(document.forms[0]).appendChild(
			new Element("div", {id: "boxbox_overlay", style: "display:none;"})
		);
		// Create Window
		this.win = $(document.forms[0]).appendChild(
			new Element("div", {id: "boxbox_window", style: "display:none;"})
		);

		var bodyTarget = this.win;
		if (this.options.skin && this.options.skinBodyTarget) {
			this.win.update(this.options.skin);
			bodyTarget = this.win.down("#"+this.options.skinBodyTarget);
		}

		// Create Window
		this.body = bodyTarget.appendChild(
			new Element("div", {id: "boxbox_body"})
		);
		
		// Ensure Resize updates
		Event.observe(window, "resize", this.__resize.bindAsEventListener(this));
		
		// Ensure Scroll updates
		Event.observe(window, "scroll", this.__scroll.bindAsEventListener(this));
		
		if (this.clickTriggerClass) {
			this.findTriggers();
		}

		// Close when overlay is clicked
		Event.observe(this.overlay, "click", this.__overlayClick.bindAsEventListener(this));
		
		// When fade-in starts
		document.observe("boxbox:fadeInStart", this.__fadeInStart.bindAsEventListener(this));
		// When fade-in completes
		document.observe("boxbox:fadeInComplete", this.__fadeInComplete.bindAsEventListener(this));
		
		// When fade-out begins
		document.observe("boxbox:fadeOutStart", this.__fadeOutStart.bindAsEventListener(this));
		// When fade-out completes
		document.observe("boxbox:fadeOutComplete", this.__fadeOutComplete.bindAsEventListener(this));

		return this;
	},
	
	//
	// EVENT HANDLERS
	//
	
	__resize: function(e) {
		this.resizeIntId = null;
		
		var resize = function() {
			// Delay keeps IE from persisting overlay width when making browser skinnier
			clearInterval(BoxBox.resizeIntId);
			BoxBox.resizeIntId = null;
			this.resizeOverlay();
			// this.resizeContent(optimal_height, optimal_width);
			this.center();
		};
		
		this.resizeIntId = setInterval(resize.bind(this), 25);
	},
	__scroll: function(e) {
		// TODO: handle horizontal scrolling
		this.centerVertically();
		this.overlay.style.top = ((this.browser.isSafari) ? document.body.scrollTop : document.documentElement.scrollTop) + "px";
		this.resizeOverlay();
	},
	__overlayClick: function(e) {
		e.stop();
		this.close();
	},
	
	__fadeInStart: function(e) {},
	__fadeInComplete: function(e) {
		this.showWindow();
	},
	__fadeOutStart: function(e) {
		if (this.contentSource) {
			this.contentSource.insert(this.body.firstChild);
		}
	},
	__fadeOutComplete: function(e) {},
	
	__triggerDomEvent: function(e, eventName) {
		e.stop(); // TODO: don't stop events when no need to (non A, Button, etc)
		var target = null;
		var link = e.findElement("A");
		
		if (link.href.match(/\.(jpg|gif|png)$/i)) {
			// Open up linked image
			var img = new Image();
			img.src = link.href;
			BoxBox.open(img);
		}
		
		return;

		if (link) { // Try link href first
			target = link.href.split("#")[1];
		}
		if (target == null) {
			target = e.element().readAttribute("rel");
		}
		if (target) {
			target = $(target);
			if (target) {
				BoxBox.open($(target));
			}
		}
	},
	
	//
	// "PUBLIC" API METHODS
	//

	open: function(content, options) { // TODO: enable temp override options
		if(this.isOpen) return; // already open
		this.isOpen = true;
		this.showOverlay();
		this.contentToLoad = content; // Might need to re-center after content loaded
	},
	
	close: function() {
		if (!this.isOpen) return;
		this.isOpen = false;
		document.fire("boxbox:close");
		this.hideWindow();
		this.hideOverlay();
	},
	
	resize: function(width, height) {
		this.setWidth(width);
		this.setHeight(height);
	},
	
	resizeToContent: function() {
		var ow = this.body.getWidth();
		var oh = this.body.getHeight();
		this.body.setStyle({
			width: "auto",
			height: "auto",
			position: "absolute"
		});
		var dims = this.body.getDimensions();
		this.body.setStyle({
			width: ow + "px",
			height: oh + "px",
			position: "static"
		});
		if (Prototype.Browser.IE) {
			dims.width += 3;
		}
		this.resize(dims.width, dims.height);
	},
	
	setWidth: function(width) {
		this.body.morph({width: width+"px"},{
			duration: this.options.resizeDuration,
			afterUpdate: function(e) {
				BoxBox.centerHorizontally();
			}
		});
	},
	
	setHeight: function(height) {
		this.body.morph({height: height+"px"}, {
			duration: this.options.resizeDuration,
			afterUpdate: function(e) {
				BoxBox.centerVertically();
			}
		});
	},
	
	findTriggers: function(CssSelector, sDomEventName) {
		var selector = (CssSelector) ? CssSelector : this.clickTriggerClass ;
		var eventName = (sDomEventName) ? sDomEventName : "click" ;
		if (selector) {
			$$(selector).each(function(t, i) {
				if (!BoxBox.clickTriggers.include(t)) {
					BoxBox.clickTriggers.push(t);
					t.observe(eventName, BoxBox.__triggerDomEvent.bindAsEventListener(BoxBox, eventName));
				}
			});
		}
	},

	//
	// WINDOW
	//
	
	showWindow: function() {
		// this.showLoader();	// starts loader within empty window
		this.loadContent();
		
		this.win.setStyle({
			display: "block",
			visibility: "visible",
			position: "absolute"
		});

		var w = (this.options.sizeToContent) ? this.body.getWidth() : this.options.width ;
		var h = (this.options.sizeToContent) ? this.body.getHeight() : this.options.height ;
		
		this.body.setStyle({
			width: w + "px",
			height: h + "px"
		});

		this.center();
		document.fire("boxbox:open");
	},
	
	hideWindow: function() {
		this.body.setStyle({
			width: "auto",
			height: "auto"
		});
		this.win.setStyle({
			display: "none",
			visibility: "hidden"
		});
	},
	
	loadContent: function() { // Overload this with optional content arg
		this.contentSource = null;
		var content = (this.contentToLoad) ? this.contentToLoad : "" ;
		if (typeof content == "string") {
			this.body.innerHTML = content;
		} else if (typeof content.nodeName != "undefined") {
			this.body.update();
			this.contentSource = $(content.parentNode);
			this.body.insert(content);
		}
		document.fire("boxbox:contentloaded");
	},
	
	center: function() {
		this.centerHorizontally();
		this.centerVertically();
	},
	
	centerHorizontally: function(){
		var scroll = document.documentElement.scrollLeft;
		var s_left = scroll + Math.round((this.getViewportWidth() - (this.win.offsetWidth || 0)) / 2);
		this.win.setStyle({left: s_left + 'px'});
	},

	centerVertically: function(){
		// TODO: make sure bottom edge doesn't go past this.getViewportHeight()
		var scroll = (this.browser.isSafari) ? document.body.scrollTop : document.documentElement.scrollTop;
		var s_top = scroll + Math.round((this.getViewportHeight() - (this.win.offsetHeight || 0)) / 2);
		this.win.setStyle({top: s_top + 'px'});
	},
	
	//
	// OVERLAY
	//
	
	resizeOverlay: function(){
		this.overlay.setStyle({
			height: '100%',
			width: '100%'
		});
		if(!this.browser.isSafari3){
			// Safari3 includes vertical scrollbar in this.getDocumentWidth()!
			// Leave overlay width at 100% for now...
			this.overlay.setStyle({width: this.getDocumentWidth() + 'px'});
		}
	},
	
	toggleOverlay: function() { // Change to custom event
		var method = (this.isOverlayOn) ? "hide" : "show" ;
		this[method + "Overlay"]();
	},

	showOverlay: function() {
		if (this.overlayFX && this.overlayFX.state == "running") {
			return; // keep from animating when already doing so
		}
		
		document.fire("boxbox:fadeInStart");
		
		var options = this.options;
		
		this.overlay.setOpacity(0);
		this.isOverlayOn = true;
		
		this.resizeOverlay(); // size the overlay before showing
		var onFadeInCompleteEvent = "boxbox:fadeInComplete";
		
		if (this.browser.overlayRequiresImage) { // TODO (may be an IE6 thing) !!!!!!!!!!!!!!!!!
			this.overlay.setStyle({
				visibility: 'visible',
				backgroundColor: 'transparent',
				backgroundImage: 'url(' + options.assetURL + options.overlayBgImage + ')',
				backgroundRepeat: 'repeat',
				opacity: 1
			});
			document.fire(onFadeInCompleteEvent);
		} else {
			this.overlay.setStyle({
				visibility: 'visible',
				backgroundColor: options.overlayColor
			});
			this.overlayFX = new Effect.Appear(this.overlay, {
				to: options.overlayOpacity,
				duration: options.fadeDuration,
				afterFinish: function(e) {
					document.fire(onFadeInCompleteEvent, e);
				}.bind(this)
			});
		}
	},
	
	hideOverlay: function() {
		if (this.overlayFX && this.overlayFX.state == "running") {
			return; // keep from animating when already doing so
		}
		
		document.fire("boxbox:fadeOutStart");
		
		var options = this.options;
		var onFadeOutCompleteEvent = "boxbox:fadeOutComplete";
		
		if (this.browser.overlayRequiresImage) { // TODO
			this.overlay.setStyle('visibility', 'hidden');
			document.fire(onFadeOutCompleteEvent);
			this.isOverlayOn = false;
		} else {
			this.overlayFX = new Effect.Fade(this.overlay, {
				duration: options.fadeDuration,
				afterFinish: function(e) {
					this.isOverlayOn = false;
					document.fire(onFadeOutCompleteEvent, e);
				}.bind(this)
			});
		}
	},
	
	//
	// DIMENSIONS
	//
	
	getViewportWidth: function() { // !!! SB
		var width = window.innerWidth; // Safari
		var mode = document.compatMode;
		if(mode || isIE){
			width = this.browser.isStrict ? document.documentElement.clientWidth : document.body.clientWidth;
		}
		return width;
	},
	getViewportHeight: function() { // !!! SB
		var height = window.innerHeight; // Safari
		var mode = document.compatMode;
		if((mode || this.browser.isIE) && !this.browser.isOpera){
			height = this.browser.isStrict ? document.documentElement.clientHeight : document.body.clientHeight;
		}
		return height;
	},
	getDocumentWidth: function() {
		var scrollWidth = this.browser.isStrict ? document.documentElement.scrollWidth : document.body.scrollWidth;
		return Math.max(scrollWidth, this.getViewportWidth());
	},
	getDocumentHeight: function() {
		var scrollHeight = this.browser.isStrict ? document.documentElement.scrollHeight : document.body.scrollHeight;
		return Math.max(scrollHeight, this.getViewportHeight());
	},
	
	detectBrowser: function() {
		var b = this.browser;
		b.ua = navigator.userAgent.toLowerCase();
		b.isStrict = document.compatMode == 'CSS1Compat';
		b.isOpera = b.ua.indexOf("opera") > -1;
		b.isIE = b.ua.indexOf('msie') > -1;
		b.isIE7 = b.ua.indexOf('msie 7') > -1;
		b.isBorderBox = b.isIE && !b.isStrict;
		b.isSafari = (/webkit|khtml/).test(b.ua);
		b.isSafari3 = b.isSafari && !!(document.evaluate);
		b.isGecko = !b.isSafari && b.ua.indexOf('gecko') > -1;
		b.isWindows = (b.ua.indexOf('windows') != -1 || b.ua.indexOf('win32') != -1);
		b.isMac = (b.ua.indexOf('macintosh') != -1 || b.ua.indexOf('mac os x') != -1);
		b.isLinux = (b.ua.indexOf('linux') != -1);
		
		b.overlayRequiresImage = false; // TODO: actually check this
	}
}
*/
document.observe("dom:loaded", function() {
	if (Prototype.Browser.IE) {
		console = {
			log: function() {
				var msg = "";
				for (var i=0; i<arguments.length; i++) {
					msg += arguments[i].toString() + " (" + typeof arguments[i] + ")\n";
				}
				// alert(msg);
			}
		}
	}

	bb = BoxBox.initialize({
		skin:	'<div id="boxbox_skin_wrap">' +
					'<div id="boxbox_skin_close">' +
						'<a href="javascript:BoxBox.close();">Close</a>' +
					'</div>' +
					'<div id="boxbox_skin">' +
						'<div class="hd">' +
							'<div class="aux"></div>' +
						'</div>' +
						'<div class="bd1">' +
							'<div class="bd2">' +
								'<div class="bd3">' +
									'<div id="boxbox_skin_inner"></div>' +
								'</div>' +
							'</div>' +
						'</div>' +
						'<div class="ft">' +
							'<div class="aux"></div>' +
						'</div>' +
					'</div>' +
				'</div>',
		skinBodyTarget: "boxbox_skin_inner" 
	});
	BoxBox.findTriggers("a.boxbox_trigger");
	// BoxBox.findTriggers("a", "mouseover");
})
