/* Webvision Utilities
/  ----------------------------------------------
/ Handy helpers to override or improve jQuery functionality
/ and to provide handy helper functions 
/  --------------------------------------------*/

var wvUtilities = new Class({
						
	Extends: Options,
	
	options:	{
		debug: false
	},
	
	details:	{
		version: '0.92',
		date: '16/07/08'
	},
	
	initialize: function(options)	{
		this.setOptions(options);
		this.safari = $.browser.safari;
	},
	
	// GET VIEWPORT SIZE
	// ------------------------------------
	// Gets the browser's viewport width / height in a cross-browser fashion
	// Returns a width / height object and saves it as this.viewport
	// ------------------------------------
	getViewportSize: function()	{
		docEl = document.documentElement;
		this.viewport = {
			width: window.innerWidth || self.innerWidth || (docEl && docEl.clientWidth) || document.body.clientWidth,
			height: window.innerHeight || self.innerHeight || (docEl && docEl.clientHeight) || document.body.clientHeight
		}
		return this.viewport;
	},
	
	// GET TRUE HEIGHT
	// ------------------------------------
	// jQuery's height seems to have difficulty returning a true value when margins and padding are involved.
	// Returns an integer which is generally more accurate. Needs optimizing.
	// Sometimes returns incorrect values for Safari - work in progress.
	// ------------------------------------
	getTrueHeight: function(el)	{
		height = $(el).height();
		height += parseInt($(el).css('margin-top').replace(/(?:px)|(?:auto)/gi, ""));
		height += parseInt($(el).css('margin-bottom').replace(/(?:px)|(?:auto)/gi, ""));
		height += parseInt($(el).css('padding-top').replace(/(?:px)|(?:auto)/gi, ""));
		height += parseInt($(el).css('padding-bottom').replace(/(?:px)|(?:auto)/gi, ""));
		height += (parseInt($(el).find(':first-child').css('padding-top').replace(/(?:px)|(?:auto)/gi, "")) || 0);
		height += (parseInt($(el).find(':first-child').css('margin-top').replace(/(?:px)|(?:auto)/gi, "")) || 0);
		height += (parseInt($(el).find(':last-child').css('padding-bottom').replace(/(?:px)|(?:auto)/gi, "")) || 0);
		height += (parseInt($(el).find(':last-child').css('margin-bottom').replace(/(?:px)|(?:auto)/gi, "")) || 0);
		if(!$.browser.mozilla)	height += 32;
		return height;
	},
	
	// GET PARAMETERS
	// ------------------------------------
	// Chops a URL up and stores the parameters in a mootools Hash object.
	// Based on the original thickbox code.
	// Returns the Hash object and saves it as this.parameters
	// ------------------------------------
	getParameters: function(href)	{
		var params = this.parameters = new Hash();	
		pairs = href.replace(/.*\?/, '').split(/[;&]/);
		pairs.each(function(pair)	{
			keyVal = pair.split('=');
			if(keyVal && keyVal.length == 2)	{
				key = unescape(keyVal[0]);
				val = unescape(keyVal[1]).replace(/\+/g, ' ');
				params.set(key, val);
			}
		});
		return params;
	},
	
	// LOG
	// ------------------------------------
	// Allows cross-browser debugging. Set debug: true in the options,
	// Firefox will log to the firebug console, all other browsers will alert the value.
	// ------------------------------------
	log: function(msg)	{
		if($.browser.mozilla)	console.log(msg);
		else if(this.options.debug)	alert(msg);
	}
	
});

var wvPopup = new Class({
						
	Extends: wvUtilities,
	
	// ------------------------------------
	// Default options
	// ------------------------------------
	options:	{
		size:	{
			width: 400,				// Default width
			height: 200				// Default height
		},
		overlay:	{
			closes: true,			// Whether clicking on the overlay closes the popup
			opacity: 0.7			// Opacity of the overlay
		},
		margin:	{
			top: 30,				// Distance from the top of the screen
			bottom: 30,				// Distance from the bottom of the screen
			left: 50,				// Distance from the left of the screen
			right: 50				// Distance from the right of the screen
		},
		displayTitleBar: true,		// Whether to display a title bar or not
		name: 'wvPopup',			// The class, name and ID of the generated IFRAME
		onLoad: $lambda(true),		// A function that is called when the iframe's content is loaded
		autoClearMargins: false,	// Whether to reset margins, paddings and borders to 0
		loaderSource: '/magazine/graphics/loadingAnimation.gif'
	},
	
	// INITIALIZATION
	// ------------------------------------
	// INITIALIZATION
	// ------------------------------------
	initialize: function(elements, options)	{
		this.elements = elements;
		this.setOptions(options);
		this.parent(options);
		this.ie6 = ($.browser.msie && $.browser.version < 7);
		this.create();
		this.getViewportSize();
		this.bindEvents();
	},
	
	bindEvents: function()	{
		var self = this;
		this.elements.click(function(e)	{
			self.overlay.css('display', 'block');
			self.loader.css('display', 'block');
			if(self.ie6)	{
				$("HTML, BODY").css({
					height: "100%",
					width: "100%"
				});
				$("HTML").css("overflow","hidden");
				scrollTo(0, 0);
				self.shim.css('display', 'block');
			}
			self.title.children('> div').eq(1).text($(this).attr('title'));
			self.getParameters(this.href);
			self.loadContents(this.href);
			e.preventDefault();
			return false;
		});
		this.closeButton.click(function(e)	{
			self.hide();	
			return false;
		}).hover(function()	{
			$(this).addClass('wvPopupCloseButtonHover');	
		},function()	{
			$(this).removeClass('wvPopupCloseButtonHover');	
		});
		if(this.options.overlay.closes)	this.overlay.click(function()	{	
			self.hide();
		});
	},
	
	show: function()	{
		var self = this;
		this.overlay.css('display', 'block');
		this.loader.css('display', '');
		this.container.css({
			'display': 'block',
			'left': -9999
		});
		if(this.ie6)	{
			$("HTML, BODY").css({
				height: "100%",
				width: "100%"
			});
			$("HTML").css("overflow","hidden");
		}
		this.setSize();
		this.position();
		$(window).bind('resize', function()	{
			self.getViewportSize();
			self.setSize();
			self.position();
		});
	},
	
	hide: function()	{
		this.overlay.css('display', '');
		this.container.css('display', '');
		this.loader.css('display', '');
		if(this.ie6)	{
			$("HTML, BODY").css({
				height: "",
				width: "",
				overflow: ""
			});	
			this.shim.css('display', '');
		}
		this.iframe.remove();
		$(window).unbind('resize');
	},
	
	setSize: function()	{
		width = this.parameters.has('width') ? this.parameters.get('width') : this.options.size.width;
		height = this.parameters.has('height') ? this.parameters.get('height') : this.options.size.height;
		titleheight = this.title.outerHeight();
		if(width > this.viewport.width)	width = this.viewport.width - (this.options.margin.left + this.options.margin.right);
		if(height > this.viewport.height)	height = this.viewport.height - (this.options.margin.top + this.options.margin.bottom);
		if(width == 'full')	width = this.viewport.width - (this.options.margin.left + this.options.margin.right);
		$(this.container).css('width', width + "px");
		$(this.iframe).css('width', width + "px");
		if(height == 'auto')	{
			iframeheight = this.getTrueHeight($(this.iframeBody));
			
			if((iframeheight + titleheight) > this.viewport.height)	{
				iframeheight = this.viewport.height - titleheight;
				$(this.iframe).attr('scrolling', 'auto');
			}
			else	{
				$(this.iframe).attr('scrolling', 'no');
			}
			$(this.container).css('height', (iframeheight + titleheight) + "px");
			$(this.iframe).css('height', iframeheight + "px");

		}
		else	{
			$(this.container).css('height', height + "px");
			$(this.iframe).css('height', (height - titleheight) + "px");
		}
	},
	
	loadContents: function(url)	{
		var self = this;
		this.createIframe();
		this.container.css('display', '');
		$(this.iframe).attr('src', url).load(function(e)	{
			self.iframeWin = this.contentWindow;
			self.iframeDoc = self.iframeWin.document;
			self.iframeBody = self.iframeDoc.body;
			if(self.options.autoClearMargins)	{
				// Force margin/padding 0 on HTML and BODY tags
				var css = {
					'margin': 0,
					'padding': 0,
					'border': 0
				};
				$(self.iframeDoc).css(css);
				$(self.iframeBody).css(css);
			}
			$(self.iframeBody).addClass(self.options.name + 'Content');
			self.show();
			self.options.onLoad(self.iframeBody);
		});
	},
	
	position: function()	{
		this.getViewportSize();
		var width = this.container.outerWidth();
		var height = this.container.outerHeight();
		leftcorner = (this.viewport.width - width) / 2;
		topcorner = (this.viewport.height - height) / 2;
		this.container.css({
			'left': leftcorner.toInt(),
			'top': topcorner.toInt()
		});
	},
	
	create: function()	{
		this.createOverlay();
		this.createLoader();
		this.createContainer();
		this.createTitleBar();
		this.createCloseButton();
	},
	
	createOverlay: function()	{
		if(this.ie6)	this.shim = $('<iframe />').addClass(this.options.name + 'HideSelect').appendTo($('BODY'));
		this.overlay = $('<div />').addClass(this.options.name + 'Overlay').css('opacity', this.options.overlay.opacity).appendTo($('BODY'));
	},
	
	createLoader: function()	{
		this.loader = $('<img />').addClass(this.options.name + 'Loader').attr('src', this.options.loaderSource).appendTo($('BODY'));
	},
	
	createContainer: function()	{
		this.container = $('<div></div>').addClass(this.options.name).appendTo($('BODY'));
	},
	
	createTitleBar: function()	{
		this.title  = $('<div />').addClass(this.options.name + 'Title').appendTo(this.container);
		this.titletext = $('<div></div>').appendTo(this.title);
		if(!this.options.displayTitleBar)	this.title.css({
			'display': 'none',
			'height': 0
		});
	},
	
	createCloseButton: function()	{
		this.closeButton = $('<a href="#">Close</a>').addClass(this.options.name + 'CloseButton').prependTo(this.title);
	},
	
	createIframe: function()	{
		this.iframe = $('<iframe frameborder="0" marginheight="0" marginwidth="0" scrolling="auto" />').attr({
			'id': this.options.name + 'Iframe',
			'name': this.options.name + 'Iframe'
		}).appendTo(this.container);
	},
	
	refresh: function()	{
		this.getViewportSize();
		this.setSize();
		this.position();	
	}
	
});

var popup;

$(function()	{
		   
	popup = new wvPopup($('.thickbox'));
	
});