/* Webvision Utilities
/  ----------------------------------------------
/ Handy helpers to override or improve jQuery functionality
/ and to provide handy helper functions 
/  --------------------------------------------*/

/*----------------------------------------------------------------------------
Last Updated by:	Qasim Alyas

Change history:
	- Added loader img alt attribute

-----------------------------------------------------------------------------*/

var popup;

(function($) {

	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);
			height += 32;	// apply correction factor for all browsers now, even FF4+
			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',
			loaderAlt: 'Loading'
		},
		
		// 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, 'alt': this.options.loaderAlt}).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();	
		}
		
	});
	
	
	$(function()	{
			   
		popup = new wvPopup($('.thickbox'));
		
	});

})(jQuery);

