/* version .43 */

/* options added:

	iframe: true;
	- this will pop your content up in an iframe - which will allow for printing.  Width and height are required
	
	position: 'relative'
	- this will position your windows relative to the link you clicked
	
	mode: 'tooltip'
	closeOnMouseOut: true
	- this will do tooltip-style modal windows.  
	- closeOnMouseOut will shut the tooltip off when you roll off of the activator.  If false, the tooltip will shut off when you roll inside the popup and then out of the popup.
	
*/

var FlexBox = Class.create();

FlexBox.prototype = {
	initialize: function(element, options) {
		
		this.isIE6 = typeof document.body.style.maxHeight === 'undefined';
		this.isSafari = navigator.userAgent.indexOf('AppleWebKit/') > -1;
		this.showing = false;
		
		if (arguments.length > 1) {
		
			if (typeof element == 'string') {
				this.element = ( (element.indexOf('.') < 0) && (element.indexOf('#') < 0) ) ? $(element) : $$(element);
			}
			else {
				this.element = element;
			}
		}
		else {
			this.element = options = element;
		}
		
		this.options = {
			/* you can set these in the instantiation or the CSS */
			fade: true, // whether the overlay fades or not //
			overlayColor: '#666',
			opacity: .6,
			speed: .2,
			width: 'auto', // the width of the popup //
			height: 'auto', // the height of the popup //
			popupContentClass: 'popup-content',
			popupCloseClass: 'close-button',
			action: 'click',
			closeOnMouseOut: true,
			position: 'fixed',
			offsetTop: 0,
			offsetLeft: 0
		}
		
		Object.extend(this.options, options || {});
	
		if(this.options.mode == 'tooltip') {
			this.options.overlayColor = '#fff';
			this.options.opacity = 0;
			this.options.fade = false;
			this.options.position = 'relative';
		}
	
		this._init();
	
		if (this.element.length) {
			this.element.each(function(element) {
				this.setupShowTarget(element);
			}.bind(this));
		}
		else {
			this.setupShowTarget(this.element);
		}
		
	},
	
	_init : function() {
		
		// build the overlay and popup frame if they are not on the page yet //
		if ( !$('overlay') ) {
			new Insertion.Bottom(document.body, '<div id="overlay"></div>');
			new Insertion.Bottom(document.body, '<div id="popup-frame"></div>');
			new Insertion.Bottom($('popup-frame'), '<div id="popup-content"></div>');
		}
		
		// IE6 needs to be tweaked to hide select boxes and such //
		if ( this.options.hideSelects ) {
			if (this.isIE6) {
				new Insertion.Bottom(document.body, "<iframe id='hide-selects'></iframe>");
				$('hide-select').style.display = 'none';
			}
		}
		
		this.overlay = $('overlay');
		this.popupFrame = $('popup-frame');
		this.popupContent = $('popup-content');
	
		$('overlay').style.display = 'none';	
		$('popup-frame').style.display = 'none';	
		$('popup-content').style.display = 'none';	
		
		// cache the events so we can unbind //
		this.watchKeyEvent = this.watchKeyPress.bindAsEventListener(this);
		this.deactivateEvent = this.deactivate.bindAsEventListener(this);
		this.activateEvent = this.activate.bindAsEventListener(this);
		this.detectExitEvent = this.detectExit.bindAsEventListener(this, this.popupFrame)
	
		// IE6 problems are fixed here //
		if (this.isIE6) {
			this.overlay.setStyle({ 'position':'absolute' });
			this.popupFrame.setStyle({ 'position': 'absolute' });
			$(document.body).setStyle({ 'height': '100%' } );
			$(document.getElementsByTagName('html')[0]).setStyle({ 'height':'100%' });
		}
		
		// Safari has a problem with dynamic iframes.  Lets make sure we don't do them. //
		if (this.isSafari) {
			if (this.options.iframe) {
				this.options.iframe = false;
				this.options.height = 'auto';
			}
		}
	
		this.init = true;
	},
	
	setupShowTarget: function(element) {
		
		var link = element.href;
		
		if (link.indexOf('#') > -1) {
			link = link.split('#')[1];
			$(link).style.display = 'none';
		}
		
		this.popupClass = this.options.popupClass || $(element).classNames();
		
		Event.observe(element, this.options.action, this.activateEvent);
		
		if (this.options.mode == 'tooltip' && this.options.closeOnMouseOut ) {
			Event.observe(element, 'mouseout', this.deactivateEvent);
		}
	
	},
	
	watchKeyPress : function(e) {
	
		if (e.keyCode == Event.KEY_ESC) {
			this.deactivate();
		}
		
	},
	
	activate: function(e) {
	
		// makes sure that the anchor text isn't in a span or em or something //
		if (Event.element(e)) {
			var link = Event.element(e).readAttribute('href') ? Event.element(e).readAttribute('href') : Event.element(e).parentNode.readAttribute('href');
			this.originalElement = Event.element(e);
		}
		
		// programmatic activation //
		else { 
		 	var link = e;
		}
		
		if (!this.observing) {		
			// add the event listeners to turn off the windows //
			if (!this.options.modal) {
				Event.observe(document, 'keypress', this.watchKeyEvent);
				Event.observe('overlay', 'click', this.deactivateEvent);
			}
			
			if (this.options.mode != 'tooltip') {
				this.toggleOverlay();
			}
			
			this.observing = true;
		}
		
		if (link.indexOf('#') < 0) {
			var pageToOpen = link;
		}
		else {
			var pageToOpen = link.split('#')[1];
			var content = $(pageToOpen).innerHTML;
		}
		
		/* show the content! */
		
		// if the link isn't to a bookmark, we're in ajax mode //
		if( (link.indexOf('#') < 0) ) {
			
			// mode is iframed external popup //
			if( this.options.iframe ) {
				this.display( '<iframe src="' + pageToOpen + '" width="' + this.options.width + '" height="' + this.options.height + '" frameborder="0" id="iframe-' + pageToOpen + '" name="iframe_' + pageToOpen + '"></iframe>' );
			}
			
			// mode is normal ajax popup //
			else {
				this.remote = true;
				this.getData( pageToOpen );
			}
		}
		
		else {
		
			// mode is iframed in-page element popup //
			if( this.options.iframe ) {
				
				this.popupContent.innerHTML = '<iframe width="' + this.options.width + '" height="' + this.options.height + '" frameborder="0" id="iframe-' + pageToOpen + '" name="iframe_' + pageToOpen + '" class="' + this.options.popupContentClass + '" style="display: block;" allowtransparency="true"></iframe>';
				
				var repHTML = content;
				var repClass = $(pageToOpen).className || this.options.popupContentClass;
			
				window.setTimeout(function() {
				
					window.frames[0].document.body.style.background = 'none';
					
					var rep = window.frames[0].document.createElement('div');
					rep.innerHTML = repHTML;
					rep.className = repClass;
					
					/* lets set some default base styles and override typical frame borders and padding so we can use the defined class  */
					
					rep.style.display = 'block';
					rep.style.border = 'none';
					rep.style.padding = '0';
					rep.style.textAlign = 'left';
					
					window.frames[0].document.body.appendChild(rep); 
					
					var pageCloseTargets = document.getElementsByClassName(this.options.popupCloseClass, rep);
					
					for(var x=0; x<pageCloseTargets.length; x++) {
						Event.observe(pageCloseTargets[x], 'click', this.deactivateEvent);	
					}
					
					var ifHead = window.frames[0].document.getElementsByTagName('head')[0];
					
					for (var x = 0; x < document.styleSheets.length; x++) {
						var sheet = window.frames[0].document.createElement('link');
						sheet.rel = 'stylesheet';
						sheet.href = document.styleSheets[x].href;
						sheet.type = 'text/css';
						sheet.media = document.styleSheets[x].media.mediaText ? document.styleSheets[x].media.mediaText : document.styleSheets[x].media;
						ifHead.appendChild(sheet);
					}
				
					// set all links to link back to the original window
					
					var links = window.frames[0].document.getElementsByTagName('a');
					for (var x=0; x < links.length; x++) {
						links[x].target = '_parent';
					}
					
					window.frames[0].document.body.appendChild(rep); 
				
					this.display();
				
				}.bind(this), 5);
				
			}
			
			// mode is normal in-page element popup //
			else {
				this.display( content );
			}
		}
		
		if (this.options.mode == 'tooltip' && !this.options.closeOnMouseOut ) {
			Event.observe(this.popupFrame, 'mouseout', this.detectExitEvent);
		}
		
		if(e) Event.stop(e);
	
	},
	
	toggleOverlay: function() {
	
		var bg = this.options.overlayColor || $('overlay').getStyle('background');
		$('overlay').setStyle({'background': bg });
	
		if (this.options.fade && bg != 'none') {
			$('overlay').style.display == 'block' ? 
			new Effect.Fade('overlay', { duration: this.options.speed, from: this.options.opacity, to: 0 }) : 
			new Effect.Appear('overlay', { duration: this.options.speed, from: 0.0, to: this.options.opacity });
		}
		
		else {
			if(bg != 'none') $('overlay').setStyle({'opacity' : this.options.opacity } );
			$('overlay').style.display == 'block' ? $('overlay').style.display = 'none' : $('overlay').style.display = 'block';
		}
		
	}, 
	
	display: function(content){
	
		// set up the dom if not ready //
		if(!this.init) {
			this._init()
		}
	
		if (!this.options.iframe) this.popupContent.update(content);
		if (!this.options.iframe) this.popupContent.addClassName(this.options.popupContentClass);
		
		var popupWidth = (this.options.width == 'auto') ? this.options.width : ( this.options.width + 'px' || this.popupContent.getStyle('width') );
		this.popupContent.style.width = popupWidth;
		
		var popupHeight = (this.options.height == 'auto') ? this.options.height : ( this.options.height + 'px' || this.popupContent.getStyle('height') );
		(this.options.height != 'auto') ? this.popupContent.style.height = popupHeight : this.popupContent.style.height = '';
		
		this.popupFrame.style.display = 'block';
			
		popupHeight = this.popupContent.getHeight();
		
		// get all close targets //
		var pageCloseTargets = this.popupContent.getElementsByClassName(this.options.popupCloseClass);
		
		for(var x=0; x<pageCloseTargets.length; x++) {
			Event.observe(pageCloseTargets[x], 'click', this.deactivateEvent);	
		}
		
		(this.options.position == 'absolute' || this.options.position == 'fixed') ? this.position(popupWidth, popupHeight) : this.positionTo(this.originalElement);
	
		this.popupContent.style.display = 'block';
		
		if (this.popupClass != '') {
			var insideTargets = this.popupContent.getElementsByClassName(this.popupClass);
				insideTargets.each(function(element) {
				this.setupShowTarget(element);
			}.bind(this));		
		}
	
		this.showing = true;
	
	
	},
	
	position: function(width, height) {
	
		// width and height are the dimensions of the popup //
		
		var scrollPosition = self.pageYOffset ? self.pageYOffset : document.documentElement.scrollTop || document.body.scrollTop;
		var pageHeight = self.innerHeight ||  document.documentElement.clientHeight || document.body.clientHeight || 0;
		
		this.popupFrame.style.position = (this.options.position == 'absolute') ? 'absolute' : 'fixed';
		
		this.popupFrame.style.left = '50%';
		this.popupFrame.style.marginLeft = '-' + parseInt(width) / 2 + 'px';
		
		if (this.options.align == 'top') {
			this.popupFrame.style.top =  (this.options.position == 'absolute') ? scrollPosition + 'px' : 0;
			this.popupFrame.style.marginTop = '0';
		}
		
		else {	
		
			var viewportCenter = parseInt( (pageHeight - parseInt(height)) / 2);
			var absCenter = scrollPosition + viewportCenter;
		
			this.popupFrame.style.top =  (this.options.position == 'absolute') ? (absCenter + 'px') : '50%';
			this.popupFrame.style.marginTop = (this.options.position == 'absolute') ? '0' : '-' + parseInt(height) / 2 + 'px';
		}
		
		// IE6 problems are fixed here //
		if (this.isIE6) {
			this.popupFrame.style.top = scrollPosition;
			this.popupFrame.style.position = 'absolute';
			this.popupFrame.style.marginTop =  (this.options.align == 'top') ? '0' : ( ( ( pageHeight - parseInt(height) ) / 2) + 'px' );
		}
	
	},
	
	positionTo: function(element) {
		
			var x = element.offsetLeft;
			var y = element.offsetTop;
		
			var width = element.offsetWidth;
			x = x + width + this.options.offsetLeft;
			y = y + this.options.offsetTop;
			
			this.popupFrame.style.marginLeft = 0;
			
			this.popupFrame.style.position = 'absolute';
			this.popupFrame.style.left = x + 'px';
			this.popupFrame.style.top = y + 'px';
	
	},	
	
	
	isChildOf: function(el, base) {
		
		var toElement = el;
		
		if(toElement) {
			if ( $(toElement).childOf(base) ) {
				return true;
			}
		
			return false;
		
		}
		
		
	},
	
	detectExit : function(evt, base) {
	
		// get the element that you left //
		var toElement = evt.relatedTarget || evt.toElement;
		
		// check to see if a mouseover element is a child.  if so, return false so we dont run the mouse event //	
		if(this.isChildOf(toElement, base)) {
				return false;
			}
		
		// otherwise, you are leaving the box.  Reset the tabs. //
		this.deactivate(evt);

	},
	
	deactivate: function(e) {
	
		if (!this.options.modal) {
			Event.stopObserving(document, 'keypress', this.watchKeyEvent);
			Event.stopObserving('overlay', 'click', this.deactivateEvent);
			Event.stopObserving(this.popupFrame, 'mouseout', this.detectExitEvent);
		}
		
		this.observing = false;
		
		if (this.options.mode != 'tooltip') {
			this.toggleOverlay();
		}
		
		this.popupContent.removeClassName(this.options.popupContentClass);
		
		this.hidePage();
		
		this.remote = false;
		this.showing = false;
		
		if(e) Event.stop(e);
	},
	
	hidePage: function() {
	
		// remove the event listeners on any close mechanisms in the content page itself //
		var pageCloseTargets = this.popupContent.getElementsByClassName(this.options.popupCloseClass);
		
		for (var x=0; x<pageCloseTargets.length; x++) {
			Event.stopObserving(pageCloseTargets[x], 'click', this.deactivateEvent);	
		}
		
		this.popupContent.style.display = 'none';
		this.popupContent.style.zIndex = '-10';
		this.popupFrame.style.display = 'none';
		
		
	}
	
}


FlexBox.AJAX = { 

		indicateLoad : function(state) {
			
			if (state == 'load') {
				// show spinner //
				var loading = '<p class=\"loading\">';
				loading += this.options.spinner ? '<img src=\"' + this.options.spinner + '\ " />' : 'Loading...'
				loading += '</p>';
				
				this.display(loading);
			}
			
		},
		
		getData: function(url) {
				
			this.remoteLoading = true;	
			var cacheNum = new Date().getTime();
			
			// so we dont get two re-centering windows //
			if (this.options.height != 'auto') 
				this.indicateLoad('load');
			
			var req = new Ajax.Request(url, {
				method: 'get',
				parameters: { ms: cacheNum },
				onSuccess: function(request) { 
		
					this.display(request.responseText); 
					this.indicateLoad('done');
					this.remoteLoading = false;
								
				}.bind(this),
				
				onComplete: function() { 
					if (typeof this.options.afterRemote == 'function') {
						this.options.afterRemote.apply(this);
					}
				}.bind(this),
				onFailure: function() { 
					alert('I in ur page messing up ur ajax'); 
				}
			});

		}
		

};
	
// add the add-on methods to the main tab prototype //
Object.extend(FlexBox.prototype, FlexBox.AJAX)


// -----------------helper functions -----------------
// ---------------------------------------------------

function showSelectBoxes(){
	var selects = document.getElementsByTagName("select");
	for (i = 0; i != selects.length; i++) {
		selects[i].style.visibility = "visible";
	}
}

// ---------------------------------------------------

function hideSelectBoxes(){
	var selects = document.getElementsByTagName("select");
	for (i = 0; i != selects.length; i++) {
		selects[i].style.visibility = "hidden";
	}
}

// ---------------------------------------------------

function showFlash(){
	var flashObjects = document.getElementsByTagName("object");
	for (i = 0; i != flashObjects.length; i++) {
		flashObjects[i].style.visibility = "visible";
	}

	var flashEmbeds = document.getElementsByTagName("embeds");
	for (i = 0; i != flashEmbeds.length; i++) {
		flashEmbeds[i].style.visibility = "visible";
	}
}

// ---------------------------------------------------

function hideFlash(){
	var flashObjects = document.getElementsByTagName("object");
	for (i = 0; i != flashObjects.length; i++) {
		flashObjects[i].style.visibility = "hidden";
	}

	var flashEmbeds = document.getElementsByTagName("embeds");
	for (i = 0; i != flashEmbeds.length; i++) {
		flashEmbeds[i].style.visibility = "hidden";
	}

}
// overwrite prototype's show method to specifically add block -- necessary if we want to use Effect.Appear and hide the background with CSS display: none; //

var newShow = { show : function(element) {
	$(element).style.display = 'block';
	return element;
  	}
  }
// 
Element.addMethods(newShow);

