/** 
 *	ImagePulser v1.0.6
 *
 *	Version log:
 *  v1.0.6	- 	Added title_position and title_height / easing open & close options
 *	v1.0.5	- 	Fixed Bug#326 Maximized Traffic Camera Image Shifting Left
 *  v1.0.4	-	Added drop shadows & fixed ghost titles
 *	v1.0.3	-	Added fix for vertical expanding outside of viewport (Y value) 
 *	v1.0.2	-	Added title_formatter callback for hover-over titles
 *	v1.0.1	-	Added fix for image on the side of the screen (expands outside of viewport)
 *	v1.0.0	-	Initial
 *
 *	Known Bugs:
 *  - Image closes when hovering over title section if position is 'outside' - needs to be fixed in mouse_over_item
*/
;(function($) { 
	$.fn.imagepulser = function(config) { 
		var opts = $.extend({
				width: '320', 
				height: '240', 
				item_class: 'imagepulser-open', 
				padding_top: 0, 
				padding_left: 0, 
				close_counter: 0,
				easing_open_time: 200, 
				easing_open_effect: 'easeInQuad', 
				easing_close_time: 200, 
				easing_close_effect: 'easeOutQuad', 
				random_effects_after: 50,
				title_height:		0.30, 
				title_position:		'outside',
				title_formatter: function() {}

		}, config);
		
		$('img',this).each(function() {
			//Display image properties
			var h, w, t, l;
			
			//Mouseover for cloned() image
			var mouseover;
			
			//Absolutely positioned item
			var item;

			init(this);
			
			//Remove ghosts
			window.setInterval(function(e) {
				detach_ghosts(e);
			}, 2000);

			
			/**
			*	Grab dimensions of that & set to local h, w, t, l variables
			*	This is checked every time open is called, in case the page contents have moved
			*/
			function gather_dimensions(that) {
				h = $(that).height(); 
				w = $(that).width(); 
				t = $(that).offset().top; 
				l = $(that).offset().left; 
			}
			
			/** 
			 *	Remove any open pulsers that did not close correctly
			*/	
			function detach_ghosts(e) { 
				$('.imagepulser-cloned :visible').each(function() {
					if ( mouse_over_item(e,this) == false ) { 
						close(this);
					}
				}); 

				//Remove any ghost UI wrappers
				$('.ui-effects-wrapper:empty').remove();								
				
			}
			
			/**
			*	Clone the displayed element, hide it & position it over the 'real' element
			*	open should be called quickly after this, otherwise the offsets may change
			*/
			function attach(that) {
				var item = $(that).clone();
				$(item)
					.addClass('imagepulser-cloned')
					.css({
						height:	h, 
						width:  w,
						top:    t,
						left:   l,
						position: 'absolute', 
						'-moz-box-shadow': '0 0 30px -5px black',
						'-webkit-box-shadow': '0 0 30px 0 black'
					})
					.data('parent', $(that) )
					.appendTo('body').hide()
				;
				return item;
			}
			
			/**
			*	Remove the cloned item
			*/
			function detach(that) {
				return true;
				$(that).remove(); 
			}
			
			/**
			*	Animate the opening of the cloned item
			*/
			function open(item) {
				
				//Close any other items
				$('.' + opts.item_class).remove(); 
				$('.imagepulser-image-title').remove();
				$('.ui-effects-wrapper:empty').remove();				
			
				$(item).css({'z-index' : '2000'}).show();
				
				var itemtop = t - ( (h)/2 ) - opts.padding_top;
				var item_padding_top = opts.padding_top;
				var itemleft = l - ( (w)/2 ) - opts.padding_left;
				var item_padding_left = opts.padding_left;
				
				
				//Move the item to the right if we're negative
				if ( itemleft < 5 ) { 
					l = 5;		//Global for closing
					itemleft = 5;
					item_padding_left = 0; 
				}

				//Move the item to the left if final position overflows
				if ( (itemleft+opts.width) > $(window).width() - 20 ) { 
					var overflow = (itemleft+opts.width) - $(window).width();
					itemleft = itemleft - overflow -5 - 20;	//20 for scrollbar
				}
				
				//Move the item down if we're negative Y
				if ( itemtop < 5 ) { 
					t = 5;		//Global for closing
					itemtop = 5;
					item_padding_top = 0; 
				}
				

				//Add the left scroll if the viewport is less on the X value
				itemleft += $(window).scrollLeft(); 

				
				
				

				
				$(item).addClass("hover").stop() 
					.animate({
						paddingTop: opts.padding_top,
						paddingBottom: opts.padding_top,
						
						paddingLeft: item_padding_left, 
						paddingRight: item_padding_left,
						
						top:  itemtop,
						left: itemleft,
						
						width: opts.width, 
						height: opts.height
					}, opts.easing_open_time, opts.easing_open_effect, function() {
						$(item).dequeue('fx');
						
						var title = ''; 
						
						if ( opts.title_formatter ) { 
							title = opts.title_formatter( this );
						}


						//Attach title if it's not blank
						if ( title && title.length > 0 ) { 
						
							var title_height = ( opts.title_height > 1 ) ? opts.title_height : $(this).height() * opts.title_height;

							//Default is inside
							var title_top = $(this).offset().top + ( $(this).height() - title_height); 
							
							if ( opts.title_position == 'outside' ) { 
								title_top = $(this).offset().top + $(this).height();
							}
							


							
							var d = $('<div class="imagepulser-image-title" />')
								.html( title )
								.css({
									'position' : 'absolute',
									left	: 	$(this).position().left + item_padding_left,
									width	: 	$(this).width(),
									height	: 	title_height,
									top		:	title_top,
									opacity :  '0',
									'z-index' : 2002
								})
								.insertAfter(this)
								.fadeTo(600,1)
								.data('parent', $(this) )
								.hover(function(e) {
								}, function(e) { 
									if ( mouse_over_item(e, $(this).data('parent') ) == true ) 
										return false;
									
									mouseover = false;
									var ret = close($(this).data('parent'));
								
								})
								
							;
							
							$(this).data('title', d );
						};
						
						
					}).addClass(opts.item_class);
					mouseover = true;
			}
			
			/**
			*	Animate the closing of the item & detach when finished
			*/
			function close(item) { 
				
				$('.ui-effects-wrapper:empty').remove();				
				opts.close_counter++; 
				if ( opts.close_counter > opts.random_effects_after ) {
					return random_closer(item);
				}
				

				l = $(item).data('parent').offset().left;
				t = $(item).data('parent').offset().top;
				
				//Remove the title
				if ( $(item).data('title') ) { 
					$(item).data('title').hide('scale', {direction:''}, 400).fadeTo(0,800, function() { $(this).remove(); }).dequeue();
				}

				
				$(item).css({'z-index' : '0'}).hide();
				$(item).removeClass("hover").stop()  
					.animate({
						top: t,
						left: l,
						padding: 0,
						width: $(item).attr('imagepulse-width'), 
						height: $(item).attr('imagepulse-height')
						
					}, opts.easing_close_time, opts.easing_close_effect, function() {
						$(this).remove(); 
					}).removeClass(opts.item_class).dequeue();
				 
				return true;

			}
			
			function mouse_over_item(e, that) { 
				var w = $(that).width();
				var h = $(that).height();
				var t = $(that).offset().top;
				var l = $(that).offset().left;							
				
				//Prevent the closing if we're still 'inside' the image
				//This is for title functionality
				//Doesn't work for 'outside' yet...
				return (
						e.pageX >= l
						&& e.pageX <= l+w
						&& e.pageY >= t
						&& e.pageY <= t+h
				);
			
			}
			
			
			/**
			*	Main display image mouse over/out
			*/	
			//$(this).hover(function() {
			function init(that) { 
				var ow = $(that).width();
				var oh = $(that).height();
				
				//Wait until all images are loaded
				if ( ow == 0 || oh == 0 ) { 
					window.setTimeout(function () {
						init(that);
					}, 500);
					return false;
				}
				
				
				$(that).attr('imagepulse-width', ow );
				$(that).attr('imagepulse-height', oh );
			
			
				$(that).hoverIntent(function() {
						gather_dimensions(that); 
						item = attach(that); 
						open(item);
	
						/**
						*	Cloned image hover over
						*	When the cloned image resizes, the mouseover event fires for the displayed element
						*	We ignore the displayed element's mouseover if we're still on the cloned element in here. 
						*/
						$(item).hover(function(e) {
								//mouseover = true; 
							}, function(e) {

								if ( mouse_over_item(e,item) == true ) 
									return false;


								var ret = close(item);
								$('.ui-effects-wrapper:empty').remove();												
						}); 
						
					} , function(e) {
						if ( mouse_over_item(e,that) == true ) 
							return false;
						var ret = close(item); 
						$('.ui-effects-wrapper:empty').remove();										
						
				});
			}
			
			
			
			

			function select_rand(array) {
				var i = Math.floor( Math.random() * array.length ) ;
				return array[i]; 
				
			}
			function random_closer(that) {
				var effects = [ "blind" , "fold", "puff", "explode", "clip", "scale", "drop" ]; 
				var e = select_rand(effects);
				var o = {}; 
				switch(e) {
					case 'blind':
						o.direction = select_rand( new Array('horizontal', 'vertical') );
						break; 
					case 'fold':
						o = select_rand( new Array( true, false ) );
						break; 
					case 'clip':
						o.direction = select_rand( new Array('horizontal', 'vertical') );
						break; 
					
				}
				$(item).css({'z-index' : '0'});
				
				$(item).hide(e, o, 400).dequeue();
				$(item).data('title').hide(e, o, 400).dequeue();
				//$(item).remove();
				return true;
				
			}


			
		}); //End imagepulser
			

	}
})(jQuery); 


