/*
	Mootools requirements (v1.11):
		-All Core, Class, Native, Element, Window, Drag
		-Effects (Base, CSS, Style, Styles)
*/

//	initialize request object
var xhr = null;
try {
	xhr = new XMLHttpRequest();
} catch (trymicrosoft) {
	try {
		xhr = new ActiveXObject("Msxml2.XMLHTTP");
	} catch (othermicrosoft) {
		try {
			xhr = new ActiveXObject("Microsoft.XMLHTTP");
		} catch (failed) {
			xhr = null;	//no support found
		}
	}
}

//	previous popup dimensions
var savedPopups = {};

var popup = new Abstract(new Element('div', {id: 'popup'})).extend({

	mins: {width: 310, height: 140},			//	minimum popup size (px)
	resizableDefault: true,						//	resizable by default?
	movableDefault: true,						//	movable by default?
	handleModals: true,							//	allow modal dialog?
	useEffects: true,								//	use transition effects?
	transTime: {open: 800, close: 200},	//	time (ms) for effect transitions (only applies if useEffects is true)
	showLabels: true,								//	display labels on move, resize, and close controls?
	
	setShim: function() {
		if ($defined(this.shim)) {
				if ($chk(this.isModal) && $defined(this.veil)) {
					if (!$defined(this.modalShimmed) || !this.modalShimmed) {
						this.shim.setStyles(this.veil.getCoordinates());
						this.modalShimmed = true;
					}
				} else {
					this.shim.setStyles(this.getCoordinates())
				}
		}
	},
	transitioning: false,
	startMeUp: function() {
		//	instantiate the iframe shim if necessary -- hides <select> and flash content in some browsers
		if (window.ie6 || (window.gecko && navigator.userAgent.test('mac', 'i'))) {
			this.shim = new Element('iframe', {
				id: 'popupShim', 
				styles: {
				    'position' : 'absolute',
				    'display' : 'none'
				}
			}).setOpacity(0.01);
			$$('body')[0].adopt(this.shim);
		}
		//	instantiate the popup's veil if you want to allow modal dialog
		if (this.handleModals == true) {
			this.veil = new Abstract(new Element('div', {
				id: 'veil'
			}).setOpacity(0.4)).extend({
				covered: false,
				cover: function() {
					this.setStyles({
						'display': 'block',
						'height': window.getScrollHeight().toInt(),
						'width': window.getScrollWidth().toInt()
					});
					this.covered = true;
				},
				uncover: function() {
					this.setStyle('display', 'none');
					this.covered = false;
				}              
			});
			$$('body')[0].adopt(this.veil);
		}
		//	inserts popup into the DOM tree
		$$('body')[0].adopt(this);
		//	details the opening and closing behavior
		function openActionStart() {
			this.className = 'ready';
			this.transitioning = true;
		}
		function openActionEnd() {
			if ($defined(this.shim)) this.shim.setStyle('display', 'block');
			this.adopt(new Element('div', {'class': 'popupContent'}).setHTML(this.content));
			//this.setHTML(this.content);  
			if ($defined(this.isModal) && $defined(this.veil)) this.veil.cover();
			this.setShim();
			this.control();
			if (this.popupName) $('moveHandle').adopt(new Element('span').setText(this.popupName));
			this.setStyle('height', (this.getStyle('height').toInt() - ($('moveHandle').getSize().size.y + $('resizeHandle').getSize().size.y)) + 'px');
			this.addClass('open');
			this.transitioning = false;
		}
		function closeActionStart() {
			if (this.transitioning == true && $defined(this.openAction)) {
				this.openAction.stop()
			}
			if ($defined(this.modalShimmed)) this.modalShimmed = false;
			this.empty();
			if ($chk(this.url) && this.transitioning == false) savedPopups[this.url] = this.getCoordinates();
			this.transitioning = true;
		}
		function closeActionEnd() {
			this.className = '';
			if ($defined(this.shim)) this.shim.setStyle('display', 'none');
			if ($defined(this.veil) && this.veil.covered == true) this.veil.uncover();
			this.transitioning = false;
		}
		//	optionally use animation effect
		if (this.useEffects == true) {
			this.openAction = new Fx.Styles(this, {
				duration: this.transTime.open,
				onStart: openActionStart.bind(this),
				onComplete: openActionEnd.bind(this)
			});
			this.closeAction = new Fx.Style(this, 'height', {
				duration: this.transTime.close,
				onStart: closeActionStart.bind(this),
				onComplete: closeActionEnd.bind(this)
			});			
		} else {
			this.openAction = {
				start: function(args) {
					openActionStart.bind(popup)();
					popup.setStyles(args);
					openActionEnd.bind(popup)();
				}
			};
			this.closeAction = {
				start: function(from, to) {
					closeActionStart.bind(popup)();
					closeActionEnd.bind(popup)();
				}
			}			
		}
	},
	open: function(url, props) {
		//	determine if the popup can be resized and/or moved
		this.resizable = this.resizableDefault;
		this.movable = this.movableDefault;
		if ($chk(props.resizable)) {
			this.resizable = (props.resizable == "true" || props.resizable == 'TRUE');
		} 
		if ($chk(props.movable)) {
			this.movable = (props.movable == "true" || props.movable == 'TRUE');
		}
		//	determines if the popup is a modal dialog
		this.isModal = props.modal;
		//	gives the popup 'window' a title if specified
		this.popupName = props.name;
		//	initial dimensions set to either last saved dimensions, property-set dimensions, or minimum dimensions and centered (default)
		var popupStyles = {
			'width':	($pick((savedPopups[url]) ? savedPopups[url].width : null, 
							$pick(props.width, this.mins.width))).toInt() + 'px',
			'height':	($pick((savedPopups[url]) ? savedPopups[url].height : null, 
							$pick(props.height, this.mins.height))).toInt() + 'px',
			'left':		($pick((savedPopups[url]) ? savedPopups[url].left : null, 
							$pick(props.x, 
							((window.getWidth()/2).toInt() - ($pick(props.width, this.mins.width)).toInt()/2)))).toInt() + 'px',
			'top':		($pick((savedPopups[url]) ? savedPopups[url].top : null, 
							$pick(props.y, 
							((window.getHeight()/2).toInt() - ($pick(props.height, this.mins.height)).toInt()/2)))).toInt() + 'px'
		};
		//	ensures the popup will not appear off-screen
		if ((popupStyles.top.toInt() + popupStyles.height.toInt()) > (window.getScrollTop() + window.getHeight())) {
			popupStyles.top = (window.getScrollTop() + window.getHeight() - popupStyles.height.toInt()) + 'px';
		}
		if (popupStyles.top.toInt() < window.getScrollTop()) popupStyles.top = window.getScrollTop() + 'px';
		if ((popupStyles.left.toInt() + popupStyles.width.toInt()) > (window.getScrollLeft() + window.getWidth())) {
			popupStyles.left = (window.getScrollLeft() + window.getWidth() - popupStyles.width.toInt()) + 'px';
		}
		if (popupStyles.left.toInt() < window.getScrollLeft()) popupStyles.left = window.getScrollLeft() + 'px';
		//	 store calculated popup styles
		this.styles = popupStyles;
		this.nextUrl = url;
		//	send ajax request, wait for callback
		this.openRequest();
	},
	openRequest: function() {
		xhr.open('GET', this.nextUrl, true);
		xhr.onreadystatechange = this.openCallback.bind(this);
		xhr.send(null);
	},	
	openCallback: function() {
		if (xhr.readyState == 4) {
			if (xhr.status == 200) {
				//	function to initiate opening the popup
				function doOpen(popup) {
					popup.url = popup.nextUrl;
					if ($defined(popup.popupSource)) {
						popup.setStyles(popup.popupSource.getCoordinates())
					}
					popup.openAction.start({
						'width': popup.styles.width,
						'height': popup.styles.height,
						'left': popup.styles.left,
						'top': popup.styles.top
					})
				}
				//	retrieves the requested page as a string
				this.content = xhr.responseText;
				if (this.content.contains('<body>')) {
					//	remove the header and footer from the requested page
					this.content = this.content.split('<body>')[1].split('</body>')[0];
				}
				
				//	if the popup is already open/used, close and re-open it, otherwise just open it
				if (this.hasClass('ready')) {
					if (this.useEffects == true) {
						(this.close(true)).chain((function() {
							doOpen(this)
						}).bind(this))
					} else {
						this.close();
						doOpen(this);
					}
				} else {
					doOpen(this)
				}
			} else {
				alert('Problem connecting to server (request status ' + xhr.status + ').  Please try again later.')
			}
		}			
	
	},
	close: function(needsReturned) {
		//	initiates closing the popup
		if ($defined(needsReturned)) {
			return this.closeAction.start(this.getStyle('height'),0);
		} else {
			this.closeAction.start(this.getStyle('height'),0);
		}
	},
	control: function() {
		//	adds movement control (conditional)
		this.adopt(new Element('div', {id: 'moveHandle'}));
		if (this.movable) {
			$('moveHandle').setStyle('cursor', 'move');
			if (this.showLabels == true) $('moveHandle').setProperty('title', 'Move');
			var movingPopup = new Drag.Move(this, {
				handle: 'moveHandle', 
				snap: 10,
				onDrag: this.setShim.bind(this),
				onComplete: (function() {
					var position = this.getPosition();
					if (position.x < 0) this.setStyle('left', '0px');
					if (position.y < 0) this.setStyle('top', '0px');
				}).bind(this)
			});
		}
		//	adds close control (always)
		this.adopt(new Element('div', {id: 'closeHandle'}));
		if (this.showLabels == true) $('closeHandle').setProperty('title', 'Close');
		$('closeHandle').addEvent('click', (function() {
			this.close()
		}).bind(this));
		//	adds resize control (conditional)
		this.adopt(new Element('div', {id: 'resizeHandle'}));
		if (this.resizable) {
			$('resizeHandle').setStyle('cursor', 'se-resize');
			if (this.showLabels == true) $('resizeHandle').setProperty('title', 'Resize');
			this.makeResizable({
				handle: 'resizeHandle',
				limit: {x: [this.mins.width], y: [this.mins.height]},
				onDrag: this.setShim.bind(this)
			});
		} else {
			$('resizeHandle').setStyle('background-image', 'none');
		}
	}
});

function registerBoxLinks() {
	$$('a').each(function(link) {
		//	gathers all links of class 'boxlink'
		if (link.className.contains('boxlink')) {
			//	builds popup properties
			var props = {};
			$each(link.getAttribute('type').split(','), function(propPair) {
				propPair = propPair.split(':');
				props[propPair[0].trim()] = propPair[1].trim();
			});
			//	adds popup opener events to each link on click
			link.addEvent('click', function(event) {
				event = new Event(event);
				popup.popupSource = $(event.target);
				event.preventDefault();
				popup.open(
					link.getAttribute('href'), 
					props
				);
			});			
		}
	});
}

if ($defined(xhr)) {
	window.addEvents({
		//	gets things going
		'domready': function() {
			registerBoxLinks();
			popup.startMeUp();
		},
		//	closes popup when 'esc' key is pressed
		'keydown': function(event) {
			event = new Event(event);
			if (event.key == 'esc' && $defined(popup.close)) popup.close()
		}
	})
}