// miscellaneous functions
var misc = {};
misc.parseURL = function(url) {
    var a =  document.createElement('a');
    a.href = url;
    return {
        params: (function() {
            var ret = {},
                seg = a.search.replace(/^\?/,'').split('&'),
                len = seg.length, i = 0, s;
            for (;i<len;i++) {
                if (!seg[i]) { continue; }
                s = seg[i].split('=');
                ret[s[0]] = s[1];
            }
            return ret;
        })()
    };
};

var popup = {
	
	_config: {
		width: 500, // width of inner content
		height: 500, // height of inner content
		fxType: 'standard',
		duration: 500,
		overlayOpacity: 0.7,
		autoResize: true // true: popup will resize to fit within the viewport
	},
	
	init: function() {
		if (!this.initiated) {
			this._insertPopup();
			
			this.overlay.addEvent('click', function(e) {
				this.closeHandler(e);
			}.bind(this));
			
			this.closeBtn.addEvent('click', function(e) {
				this.closeHandler(e);
			}.bind(this));
			
			// bind events for common popup uses
			popup.bindings._init();
			
			this.initiated = true;
		}
	},
	
	show: function(content, config) {
		this.settings = $merge(this._config, config);
		this.init();
		
		if (content) {
			this.popupContent.set('html', content).setStyle('visibility', 'hidden');
		}
		
		var properties = this._getPosition();
		
		// // Ie6 doesn't support position fixed
		if (Browser.Engine.trident && Browser.Engine.version === 4) { //4 === IE6
			var docHeight = window.getSize().y + document.documentElement.scrollTop;
			this.overlay.setStyle('height', docHeight);
			
			// hide select boxes
			$$('select').setStyle('visibility', 'hidden');
		}
		
		var self = this;
		this.fx[this.settings.fxType]._show(properties, function() {
			self.popupContent.setStyle('visibility', 'visible');
		});
	},
	
	closeHandler: function(e) {
		var self = this;
		this.fx[this.settings.fxType]._hide(function() {
			popup.hide();
		});
		e.preventDefault();
	},
	
	hide: function() {
		// removes all inline styles, default CSS should be hidden
		this.popupContainer.set('style', '');
		this.popupContent.set('style', '');
		this.overlay.set('style', '');
		
		// // Ie6 doesn't support position fixed
		if (Browser.Engine.trident && Browser.Engine.version === 4) { //4 === IE6	
			// hide select boxes
			$$('select').setStyle('visibility', 'visible');
		}
	},
	
	_insertPopup: function() {
		this.popupContainer =  new Element('div', {
			id: 'popup'
		});
		
		this.popupContent = new Element('div', {
			'class': 'popup-content'
		}).inject(this.popupContainer, 'inside');
		
		this.closeBtn = new Element('a', {
			'class': 'close-popup',
			'html': 'Close Popup',
			'href': '#'
		}).inject(this.popupContainer, 'top');
			
		// insert popup after content div and close btn have been inserted (off the dom)
		this.popupContainer.inject($$('body')[0], 'top');
		
		this.overlay = new Element('div', {
			id: 'overlay'
		}).inject($$('body')[0], 'top');
	},
	
	_getPosition: function() {
	
		var width = this.settings.width,
			height = this.settings.height,
			viewport = $$('body').getSize(),
			padding = {},
			scrollPos = $(document).getScroll();
			
		// assume opposite padding will be the same
		padding.x = parseInt(this.popupContainer.getStyle('padding-left'), 10) * 2;// + parseInt(this.popupContainer.getStyle('padding-right'), 10);
		padding.y = parseInt(this.popupContainer.getStyle('padding-top'), 10) *2 ;// + parseInt(this.popupContainer.getStyle('padding-bottom'), 10);
		
		if (width === 'auto' && height === 'auto') {
			// get natural dimensions
			this.popupContainer.setStyles({
				'visibility': 'hidden',
				'display': 'block'
			});
			var dimensions = this.popupContent.getSize();
			this.popupContainer.setStyles({
				'display': 'none',
				'visibility': 'visible'
			});
			width = dimensions.x;
			height = dimensions.y;
		}

		if (this.settings.autoResize) {
			if (width + padding.x > viewport[0].x) {
				width = viewport[0].x - padding.x;
			}
			
			if (height + padding.y > viewport[0].y) {
				height = viewport[0].y - padding.y;
			}
		}
		
		// get top / left pos
		var top = viewport[0].y / 2 - (height / 2) + scrollPos.y,
			left = viewport[0].x / 2 - (width / 2) + scrollPos.x;
		
		// check popup doesn't display outisde of body
		if (top < scrollPos.y) {
			top = padding.y + scrollPos.y;
		}
		
		if (left < scrollPos.x) {
			left = padding.x + scrollPos.x;
		}
		
		return {
			width: width,
			height: height,
			top: top,
			left: left
		}
	}
};

// effects -- just standard show/hide
popup.fx = {
	standard: {
		_show: function(properties, callback) {
					
			popup.popupContainer.setStyles({
				'top': properties.top,
				'left': properties.left,
				'display': 'block'
			});	
			
			popup.popupContent.setStyles({
				'width': properties.width,
				'height': properties.height
			});
			
			popup.overlay.setStyles({
				'display': 'block',
				'opacity': popup.settings.overlayOpacity
			});
			
			callback();
		},
		_hide: function(callback) {
			popup.popupContent.set('html', ''); // remove content
			callback();
		}
	}
}

// common uses with event bindings -- iframe, flash and ajax
popup.bindings = {

	_init: function() {
		$$('a.iframe').addEvent('click', this._iframe);
		$$('a.flash').addEvent('click', this._flash);
		$$('a.ajax').addEvent('click', this._ajax);
	},
	getConfig: function(url, defaults) {
		var params = misc.parseURL(url).params,
			config = defaults;
		
		if (params.w && params.h) {
			config = $merge({
				width: parseInt(params.w, 10),
				height: parseInt(params.h, 10)
			}, defaults);
		}
		
		return config;
	},
	_iframe: function() {
		var html,
			config = popup.bindings.getConfig(this.href, {
				autoResize: false
			});
			
		html = '<iframe src="' + this.href + '" width="100%" height="100%" frameborder="0"></iframe>';
		popup.show(html, config);
		return false;
	},
	_flash: function() {
		var html,
			config = popup.bindings.getConfig(this.href, {});

		// IE8 doesn't adhere to 100% height so '<object width="100%" height="100%">' must be explicitly set to '<object width="640%" height="396">' :(
		html = '<object width="100%" height="100%">\
					<param name="movie" value="' + this.href + '"></param>\
					<param name="allowFullScreen" value="true"></param>\
					<param name="allowScriptAccess" value="always"></param>\
					<param name="wmode" value="transparent"></param>\
					<embed src="' + this.href + '" type="application/x-shockwave-flash" width="100%" height="100%" allowFullScreen="true" allowScriptAccess="always" wmode="transparent"></embed>\
				</object>';
				
		// IE doesn't like object tag in popup
		if (Browser.Engine.trident && Browser.Engine.version === 4) {
			html = '<embed src="' + this.href + '" type="application/x-shockwave-flash" width="100%" height="100%" allowFullScreen="true" allowScriptAccess="always" wmode="transparent"></embed>';
		}
		
		popup.show(html, config);
		return false;
	},
	_ajax: function() {
		var html,
			config = popup.bindings.getConfig(this.href, {
				width: 'auto',
				height: 'auto',
				autoResize: false
			});
		
		// show loading popup
		popup.show('', {
			'width': 100,
			'height': 100
		});
		html = new Request({
			url: this.href,
			onSuccess: function(data) {
				// hide loading div
				popup.hide();
				// show div with new data
				popup.show(data, config);
			}
		}).get();

		return false;
	}
};

window.addEvent('domready', function() {
	popup.init();
});

