/*
	Mootools requirements (v1.11):
		-All Core, Class, Native, Element, Window, Drag
		-Effects (Base, CSS, Style, Styles)
*/

//	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,
	getContent: function(url) {
		//	gets content from the current DOM tree (static HTML page)
		this.content = $(url + 'Content').clone();
		this.content.setStyle('display', 'block');
		this.content.className += ' popupContent';
	},
	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.getContent(this.url);
			this.className = 'ready';
			this.transitioning = true;
		}
		function openActionEnd() {
			if ($defined(this.shim)) this.shim.setStyle('display', 'block');
			this.adopt(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) {
		//	function to initiate opening the popup
		function doOpen(popup) {
			popup.url = url;
			if ($defined(popup.popupSource)) {
				popup.setStyles(popup.popupSource.getCoordinates())
			}
			popup.openAction.start({
				'width': popupStyles.width,
				'height': popupStyles.height,
				'left': popupStyles.left,
				'top': popupStyles.top
			})
		}
		//	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';
		
		//	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)
		}
	},
	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')) {
			//	hides the popup content on the page (id = anchor name + "Content")
			$(link.getAttribute('href').split('#')[1] + 'Content').setStyle('display', 'none'); 
			//	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').split('#')[1], 
					props
				);
			});			
		}
	});
}

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()
	}
});

