﻿/* Copyright (c) 2007 Paul Bakaus (paul.bakaus@googlemail.com) and Brandon Aaron (brandon.aaron@gmail.com || http://brandonaaron.net)
 * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
 * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
 *
 * $LastChangedDate: 2007-12-20 08:46:55 -0600 (Thu, 20 Dec 2007) $
 * $Rev: 4259 $
 *
 * Version: 1.2
 *
 * Requires: jQuery 1.2+
 */

(function($){
	
$.dimensions = {
	version: '1.2'
};

// Create innerHeight, innerWidth, outerHeight and outerWidth methods
$.each( [ 'Height', 'Width' ], function(i, name){
	
	// innerHeight and innerWidth
	$.fn[ 'inner' + name ] = function() {
		if (!this[0]) return;
		
		var torl = name == 'Height' ? 'Top'    : 'Left',  // top or left
		    borr = name == 'Height' ? 'Bottom' : 'Right'; // bottom or right
		
		return this.is(':visible') ? this[0]['client' + name] : num( this, name.toLowerCase() ) + num(this, 'padding' + torl) + num(this, 'padding' + borr);
	};
	
	// outerHeight and outerWidth
	$.fn[ 'outer' + name ] = function(options) {
		if (!this[0]) return;
		
		var torl = name == 'Height' ? 'Top'    : 'Left',  // top or left
		    borr = name == 'Height' ? 'Bottom' : 'Right'; // bottom or right
		
		options = $.extend({ margin: false }, options || {});
		
		var val = this.is(':visible') ? 
				this[0]['offset' + name] : 
				num( this, name.toLowerCase() )
					+ num(this, 'border' + torl + 'Width') + num(this, 'border' + borr + 'Width')
					+ num(this, 'padding' + torl) + num(this, 'padding' + borr);
		
		return val + (options.margin ? (num(this, 'margin' + torl) + num(this, 'margin' + borr)) : 0);
	};
});

// Create scrollLeft and scrollTop methods
$.each( ['Left', 'Top'], function(i, name) {
	$.fn[ 'scroll' + name ] = function(val) {
		if (!this[0]) return;
		
		return val != undefined ?
		
			// Set the scroll offset
			this.each(function() {
				this == window || this == document ?
					window.scrollTo( 
						name == 'Left' ? val : $(window)[ 'scrollLeft' ](),
						name == 'Top'  ? val : $(window)[ 'scrollTop'  ]()
					) :
					this[ 'scroll' + name ] = val;
			}) :
			
			// Return the scroll offset
			this[0] == window || this[0] == document ?
				self[ (name == 'Left' ? 'pageXOffset' : 'pageYOffset') ] ||
					$.boxModel && document.documentElement[ 'scroll' + name ] ||
					document.body[ 'scroll' + name ] :
				this[0][ 'scroll' + name ];
	};
});

$.fn.extend({
	position: function() {
		var left = 0, top = 0, elem = this[0], offset, parentOffset, offsetParent, results;
		
		if (elem) {
			// Get *real* offsetParent
			offsetParent = this.offsetParent();
			
			// Get correct offsets
			offset       = this.offset();
			parentOffset = offsetParent.offset();
			
			// Subtract element margins
			offset.top  -= num(elem, 'marginTop');
			offset.left -= num(elem, 'marginLeft');
			
			// Add offsetParent borders
			parentOffset.top  += num(offsetParent, 'borderTopWidth');
			parentOffset.left += num(offsetParent, 'borderLeftWidth');
			
			// Subtract the two offsets
			results = {
				top:  offset.top  - parentOffset.top,
				left: offset.left - parentOffset.left
			};
		}
		
		return results;
	},
	
	offsetParent: function() {
		var offsetParent = this[0].offsetParent;
		while ( offsetParent && (!/^body|html$/i.test(offsetParent.tagName) && $.css(offsetParent, 'position') == 'static') )
			offsetParent = offsetParent.offsetParent;
		return $(offsetParent);
	}
});

function num(el, prop) {
	return parseInt($.curCSS(el.jquery?el[0]:el,prop,true))||0;
};

})(jQuery);


/* Copyright (c) 2006 Brandon Aaron (http://brandonaaron.net)
 * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) 
 * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
 *
 * $LastChangedDate: 2007-07-21 18:44:59 -0500 (Sat, 21 Jul 2007) $
 * $Rev: 2446 $
 *
 * Version 2.1.1
 */

(function($){

/**
 * The bgiframe is chainable and applies the iframe hack to get 
 * around zIndex issues in IE6. It will only apply itself in IE6 
 * and adds a class to the iframe called 'bgiframe'. The iframe
 * is appeneded as the first child of the matched element(s) 
 * with a tabIndex and zIndex of -1.
 * 
 * By default the plugin will take borders, sized with pixel units,
 * into account. If a different unit is used for the border's width,
 * then you will need to use the top and left settings as explained below.
 *
 * NOTICE: This plugin has been reported to cause perfromance problems
 * when used on elements that change properties (like width, height and
 * opacity) a lot in IE6. Most of these problems have been caused by 
 * the expressions used to calculate the elements width, height and 
 * borders. Some have reported it is due to the opacity filter. All 
 * these settings can be changed if needed as explained below.
 *
 * @example $('div').bgiframe();
 * @before <div><p>Paragraph</p></div>
 * @result <div><iframe class="bgiframe".../><p>Paragraph</p></div>
 *
 * @param Map settings Optional settings to configure the iframe.
 * @option String|Number top The iframe must be offset to the top
 * 		by the width of the top border. This should be a negative 
 *      number representing the border-top-width. If a number is 
 * 		is used here, pixels will be assumed. Otherwise, be sure
 *		to specify a unit. An expression could also be used. 
 * 		By default the value is "auto" which will use an expression 
 * 		to get the border-top-width if it is in pixels.
 * @option String|Number left The iframe must be offset to the left
 * 		by the width of the left border. This should be a negative 
 *      number representing the border-left-width. If a number is 
 * 		is used here, pixels will be assumed. Otherwise, be sure
 *		to specify a unit. An expression could also be used. 
 * 		By default the value is "auto" which will use an expression 
 * 		to get the border-left-width if it is in pixels.
 * @option String|Number width This is the width of the iframe. If
 *		a number is used here, pixels will be assume. Otherwise, be sure
 * 		to specify a unit. An experssion could also be used.
 *		By default the value is "auto" which will use an experssion
 * 		to get the offsetWidth.
 * @option String|Number height This is the height of the iframe. If
 *		a number is used here, pixels will be assume. Otherwise, be sure
 * 		to specify a unit. An experssion could also be used.
 *		By default the value is "auto" which will use an experssion
 * 		to get the offsetHeight.
 * @option Boolean opacity This is a boolean representing whether or not
 * 		to use opacity. If set to true, the opacity of 0 is applied. If
 *		set to false, the opacity filter is not applied. Default: true.
 * @option String src This setting is provided so that one could change 
 *		the src of the iframe to whatever they need.
 *		Default: "javascript:false;"
 *
 * @name bgiframe
 * @type jQuery
 * @cat Plugins/bgiframe
 * @author Brandon Aaron (brandon.aaron@gmail.com || http://brandonaaron.net)
 */
$.fn.bgIframe = $.fn.bgiframe = function(s) {
	// This is only for IE6
	if ( $.browser.msie && /6.0/.test(navigator.userAgent) ) {
		s = $.extend({
			top     : 'auto', // auto == .currentStyle.borderTopWidth
			left    : 'auto', // auto == .currentStyle.borderLeftWidth
			width   : 'auto', // auto == offsetWidth
			height  : 'auto', // auto == offsetHeight
			opacity : true,
			src     : 'javascript:false;'
		}, s || {});
		var prop = function(n){return n&&n.constructor==Number?n+'px':n;},
		    html = '<iframe class="bgiframe"frameborder="0"tabindex="-1"src="'+s.src+'"'+
		               'style="display:block;position:absolute;z-index:-1;'+
			               (s.opacity !== false?'filter:Alpha(Opacity=\'0\');':'')+
					       'top:'+(s.top=='auto'?'expression(((parseInt(this.parentNode.currentStyle.borderTopWidth)||0)*-1)+\'px\')':prop(s.top))+';'+
					       'left:'+(s.left=='auto'?'expression(((parseInt(this.parentNode.currentStyle.borderLeftWidth)||0)*-1)+\'px\')':prop(s.left))+';'+
					       'width:'+(s.width=='auto'?'expression(this.parentNode.offsetWidth+\'px\')':prop(s.width))+';'+
					       'height:'+(s.height=='auto'?'expression(this.parentNode.offsetHeight+\'px\')':prop(s.height))+';'+
					'"/>';
		return this.each(function() {
			if ( $('> iframe.bgiframe', this).length == 0 )
				this.insertBefore( document.createElement(html), this.firstChild );
		});
	}
	return this;
};

})(jQuery);



// Global leModal methods and objects
// There is only EVER one leModal
// Need Dimensions and BgIframe plugins
jQuery.leModal = {
	
	// jQuery object references
	jOverlay: null,
	jOverlayClicker: null,
	jModalWin: null,
	
	// "Private" properties
	_currentSettings: null,
	_hasSetWindowEvents: false,
	_isVisible: false,
	
	
	//
	// Show the modal
	// 3 main divs, Overlay (dimmed out background), Clicker (handles on click of overlay event - required for IE6), ModalWin
	//
	show: function(settings){
		
		var cc = this;	
		
		cc._currentSettings = jQuery.extend({
			// Properties
			modalTopAdjustment: 10,
			overlayOpacity: 0.5,
			overlayBackground: 'black',
			modalWinBackground: 'white',
			zIndex: 5000,
			showAnimationType: 'fadeIn',
			showAnimationSpeed: 'normal',
			clickBackgroundToHide: true,
			// Callback methods
			setContentCallBack: null,
			beforeShowCallBack: null,
			beforeHideCallBack: null
		}, settings);
		
				
		if (cc.jOverlay == null){
		
			// Create the Overlay layer
			cc.jOverlay = jQuery('<div id="LeModalOverlay" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; z-index: ' + cc._currentSettings.zIndex + '; background: ' + cc._currentSettings.overlayBackground + ';"></div>');
			
			if (cc._currentSettings.clickBackgroundToHide){
				// Create the Clicker layer
				cc.jOverlayClicker = jQuery('<div id="LeModalOverlayClicker" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%;"></div>');
				cc.jOverlayClicker
					.appendTo(cc.jOverlay)
					.click(function(){
						cc.hide();
					});
			}
		
			cc.jOverlay
				.bgiframe()
				.hide()
				.css('opacity', cc._currentSettings.overlayOpacity)
				.appendTo('body');
		}
		
		if (cc.jModalWin == null){
		
			// Create the ModalWin
			cc.jModalWin = jQuery('<div id="LeModalWin" style="position: absolute; top: 0; left: 0; width: auto; height: auto; z-index: ' + cc._currentSettings.zIndex + '; background: ' + cc._currentSettings.modalWinBackground + ';"></div>');
			cc.jModalWin
				.hide()
				.appendTo('body');
		}
		cc.jModalWin.css({ width: 'auto', height: 'auto' });
		
		
		if (typeof cc._currentSettings.setContentCallBack == 'function'){
			
			// Call setContentCallBack if set
			cc._currentSettings.setContentCallBack(cc.jModalWin, cc.jOverlay);
			jQuery('.close',cc.jModalWin).click(function(){
				cc.hide();
				return false;
			});
		}
		
		// Set dimensions and positions
		cc.setDimensions();
		
		if (typeof cc._currentSettings.beforeShowCallBack == 'function'){
			cc._currentSettings.beforeShowCallBack(cc.jModalWin, cc.jOverlay);
		}
		
		// Show layers
		cc.jOverlay.show();
		cc._isVisible = true;
		
		if (cc._currentSettings.showAnimationType == 'slideDown'){
			cc.jModalWin.slideDown(cc._currentSettings.showAnimationSpeed, function(){ checkWindowEvents(); });
		}
		else if (cc._currentSettings.showAnimationType == 'show'){
			cc.jModalWin.show(cc._currentSettings.showAnimationSpeed, function(){ checkWindowEvents(); });
		}
		else {
			cc.jModalWin.fadeIn(cc._currentSettings.showAnimationSpeed, function(){ checkWindowEvents(); });
		}
		
		function checkWindowEvents(){
			if (!cc._hasSetWindowEvents){
		
				// Add an on window resixe event to reset dimensions and positions
				cc._hasSetWindowEvents = true;
				jQuery(window).resize(function(){
					if (cc._isVisible) cc.setDimensions();
				});
			}
		}
		
		
	},
	
	
	//
	// Hide modal
	//
	hide: function(){
	
		var cc = this;
		
		cc.jModalWin.stop();
		
		if (typeof cc._currentSettings.beforeHideCallBack == 'function'){
			cc._currentSettings.beforeHideCallBack(cc.jModalWin, cc.jOverlay);
		}
		
		if (cc.jOverlay != null){
			cc.jOverlay.hide();
		}
		
		if (cc.jModalWin != null){
			cc.jModalWin.hide();
		}
		
		cc._isVisible = false;
	
	},
	
	
	//
	// Set dimensons and positions
	//
	setDimensions: function(){
	
		var cc = this;
		cc._setModalWinDimensions();
		cc._setOverlayDimensions();
		
	},
	
	
	_setModalWinDimensions: function(){
		
		var cc = this;
		var top = jQuery(window).scrollTop() + cc._currentSettings.modalTopAdjustment;
		if (cc.jModalWin.height() > jQuery(window).height()){
			top = jQuery(window).scrollTop();
		}
		var left = parseInt((jQuery('body').width() - cc.jModalWin.width()) / 2);
		var width = cc.jModalWin.width();
		var height = cc.jModalWin.height();
		cc.jModalWin.css({
			top: top + 'px',
			left: left + 'px',
			width: width + 'px',
			height: height + 'px'
		});
		
	},
		
	_setOverlayDimensions: function(){
		
		var cc = this;
		var bodyHeight = jQuery(document).height();
		var checkHeight = parseInt(cc.jModalWin.css('top')) + cc.jModalWin.height();
		var height = bodyHeight;
		var modalTopAdjustment = cc._currentSettings.modalTopAdjustment;
		if (cc.jModalWin.height() > jQuery(window).height()){
			modalTopAdjustment = jQuery(window).scrollTop();
		}
		if (checkHeight > bodyHeight){
			height = checkHeight + modalTopAdjustment;
		}
		if (cc.jOverlay != null){
			cc.jOverlay
				.height(height)
				.width(jQuery('body').width());
		}
		
	}
	
};
