var popup;

(function($) { 
    /* 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();	
	    }
    	
    });


    $(function()	{
    		   
	    popup = new wvPopup($('.thickbox'));
    	
    });
    
})(jQuery);
