/* version .48 */

/* options added:

added width and height param checking

*/

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',
			popupUpdater: 'popup-content',
			popupCloseClass: 'close-button',
			action: 'click',
			closeOnMouseOut: true,
			preservePopup: true,
			popupCloseOnMouseOut: true,
			position: 'fixed',
			offsetTop: 0,
			offsetLeft: 0,
			noFollow: true,
			orient: 'TR'
		}
		
		Object.extend(this.options, options || {});

		this.originalWidth = this.options.width;
		this.originalHeight = this.options.height;
		
		if(this.options.mode == 'tooltip') {
			this.options.overlayColor = 'transparent';
			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);
		}
		
	},
	
	setWidth: function(width) {
		this.options.width = width;
	},
	
	setHeight: function(height) {
		this.options.height = height;
	},
	
	_init : function() {
		
		// build the overlay and popup frame if they are not on the page yet //
		if ( !$('overlay') ) {
		
			var body = $(document.body);
		
			body.insert('<div id="overlay"></div>');
			body.insert('<div id="popup-frame"></div>');
			$('popup-frame').insert('<div id="popup-content"></div>')
			
			
			if (this.options.wrappers) {
				$('popup-content').insert(this.options.wrappers);
			}
		}
		
		// 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');
		this.popupUpdater = $(this.options.popupUpdater);
	
		$('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.className[0];
		
		Event.observe(element, this.options.action, this.activateEvent);
		
		if( this.options.action != 'click' && this.options.noFollow )
			Event.observe(element, 'click', function(e) { e.stop() } );
		
		if (this.options.mode == 'tooltip') {
			
			if (this.options.closeOnMouseOut ) {
				if (this.options.preservePopup) {
					// make the popup hoverable //
					Event.observe(element, 'mouseout', this.detectExitEvent);
				}
				else {
					// just use the element to tooltip // 
					Event.observe(element, 'mouseout', this.deactivateEvent);
				}
			}
			
		}
	
	},
	
	watchKeyPress : function(e) {
	
		if (e.keyCode == Event.KEY_ESC) {
			this.deactivate(e);
		}
		
	},
	
	activate: function(e) {
	
		// makes sure that the anchor text isn't in a span or em or something //
		if (Event.element(e)) {
			
			var target = Event.element(e);
			
			var link = target.readAttribute('href') ? target.readAttribute('href') : target.parentNode.readAttribute('href');
			this.originalElement = target;
		}
		
		// programmatic activation //
		else { 
		 	var link = e;
		}
		
		var query = link.toQueryParams();
		
		if (query.width) this.options.width = query.width;
		if (query.height) this.options.height = query.height;
		
		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();
			else 
				Event.observe(document, 'click', this.deactivateEvent);
		
			//this.toggleOverlay();
		
			this.observing = true;
		}
		
		if (link.indexOf('#') < 0) {
			var pageToOpen = link;
		}
		else {
			var pageToOpen = link.split('#')[1];
			var content = $(pageToOpen).innerHTML;
		}
		
		this.originalElement.addClassName('on');
			
		/* 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 {
				if (this.options.remote) pageToOpen = this.options.remote;
				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';
					
					// right now, getting the closeTargets in an iframe doesnt work.  gotta manually add:
					// onclick="window.parent.popup.deactivate(); return false;" to the close links.
					
					/* var pageCloseTargets = $(rep).select('.' + this.options.popupCloseClass);
					
					for(var x=0; x<pageCloseTargets.length; x++) {
						Event.observe(pageCloseTargets[x], 'click', this.deactivateEvent);	
					} */
					
					var ifHead = window.frames[0].document.getElementsByTagName('head')[0];
					//console.log(ifHead);
					
					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);
					}
					
					/*
					var meta1 = window.frames[0].document.createElement('meta');
					meta1.http-equiv = 'cache-control';
					meta1.content = 'no-cache';
					ifHead.appendChild(meta1);
					
					var meta2 = window.frames[0].document.createElement('meta');
					meta2.http-equiv = 'pragma';
					meta2.content = 'no-cache';
					ifHead.appendChild(meta2);
					
					var meta3 = window.frames[0].document.createElement('meta');
					meta3.http-equiv = 'expires';
					meta3.content = '-1';
					ifHead.appendChild(meta3);
				*/
					// 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.popupCloseOnMouseOut ) {
			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 });
	
		// sometimes AJAX popups screw up the height of the overlay, calculating only to 
		// the top of the viewport //
		if (this.isIE6 && $('overlay').style.display == 'none')
			$('overlay').setStyle({'height': $$('body')[0].getHeight() });
	
		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' && this.options.fade) $('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.popupUpdater.update(content);
			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.setStyle('display: block; visibility: hidden');
		
		popupHeight = this.popupContent.getHeight();
		
		(this.options.height != 'auto') ? this.popupContent.style.height = popupHeight : this.popupContent.style.height = '';
			
		// get all close targets //
		var pageCloseTargets = this.popupContent.select('.' + 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);
	
		if (this.popupClass != '') {
			var insideTargets = this.popupContent.select('.' + this.popupClass);
				insideTargets.each(function(element) {
				this.setupShowTarget(element);
			}.bind(this));		
		}
	
		this.popupContent.setStyle('display: block');
		this.popupFrame.setStyle('visibility: visible')
		
		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 xy = element.cumulativeOffset();
		
			var x = xy.left; // left
			var y = xy.top; // top
		
			var width = element.getWidth();
			var height = element.getHeight();
			
			var popupWidth = parseInt(this.popupContent.getWidth());
			var popupHeight = parseInt(this.popupContent.getHeight());
			
			var windowWidth = document.viewport.getWidth();
			
			var orient = this.options.orient;
			
			
			if ( (x + width + popupWidth + 20) >= windowWidth) {
			
				// ie6 hackola //
				if (this.isIE6)
					this.popupFrame.setStyle( 'visibility: visible' );
		
				this.popupContent.addClassName(this.options.inverseContentClass);
				orient = 'TL';
			}
			
			switch(orient) {
				case 'TC':
					x = x + width / 2 - popupWidth / 2;
					y = y - popupHeight;
					break;
				case 'BC':
					x = x + width / 2 - popupWidth / 2;
					y = y + height;
					break;
				case 'RM':
					x = x + width;
					y = y + (height / 2) - (popupHeight / 2) ;
					break;	
				case 'LM':
					x = x - popupWidth;
					y = y + (height / 2) - (popupHeight / 2) ;
					break;		
				case 'TR':
					x = x + width;
					y = y;
					break;			
				case 'TL':
					x = x - popupWidth;
					y = y;
					break;				
				default: // top right
					x = x + width;
					y = y;
					break;
			}
			
			x = x + this.options.offsetLeft;
			y = y + this.options.offsetTop;
			
			this.popupFrame.setStyle( { marginLeft : 0,
				position : 'absolute',
				left : x + 'px',
				top : y + 'px'
			});
	
		
	},	
	
	
	detectExit : function(e, base) {
	
		// get the element that you left //
		var toElement = e.relatedTarget || e.toElement;
	
		// if we leave the window //
		if (toElement == null) return
	
		// check to see if a mouseover element is a child.  if so, return false so we dont run the mouseout //	
		if( $(toElement).descendantOf(base)  ) {
				return false;
			}
		
		// otherwise, you are leaving the box.  Reset the tabs. //
		this.deactivate(e);

	},
	
	deactivate: function(e) {
	
		// make sure we don't click off the tooltip if we click inside, but if we click the close button, continue //
		if ( this.options.mode == 'tooltip')
			if( e.element().descendantOf(this.popupFrame) && e.type == 'click' && e.element().hasClassName(this.options.popupCloseClass) == false)
				return;
	
		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();
		else 
			Event.stopObserving(document, 'click', this.deactivateEvent);
		
		this.popupContent.removeClassName(this.options.popupContentClass);
		this.popupContent.removeClassName(this.options.inverseContentClass);
		
		this.originalElement.removeClassName('on');
		
		this.hidePage();
		
		this.remote = false;
		this.showing = false;
		
		this.options.width = this.originalWidth;
		this.options.height = this.originalHeight;
		
		if (this.options.noFollow)
			if(e) Event.stop(e);
	},
	
	hidePage: function() {
	
		// remove the event listeners on any close mechanisms in the content page itself //
		var pageCloseTargets = this.popupContent.select(this.options.popupCloseClass);
		
		for (var x=0; x<pageCloseTargets.length; x++) {
			Event.stopObserving(pageCloseTargets[x], 'click', this.deactivateEvent);	
		}
		
		this.popupFrame.style.display = 'none';
		this.popupUpdater.update('');
		
	}
	
}


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.isSafari && (this.options.height != 'auto' || (this.options.position != 'absolute' || this.options.position != 'fixed')) ) 
				this.indicateLoad('load');
			
			var req = new Ajax.Request(url, {
				method: 'get',
				parameters: { ms: cacheNum },
				onSuccess: function(request) { 
		
					this.display(request.responseText); 
					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);

