(function($) {
 
	$.fn.pannable = function(settings) {
		var config = { 
			'src':'', 
			'height':'320', 
			'width':'240', 
			'easing':0.25,
			'x':null,
			'y':null,
			'movement_x':true,
			'movement_y':true };
		
		if (settings) $.extend(config, settings);
		
		this.each(function() {
			if(config.src != '') {
				var container = $(this);
				
				container.css('position', "absolute");
				container.css('display', 'block');
				container.css('overflow', "hidden");
				container.css('width', config.width + "px");
				container.css('height', config.height + "px");
				container.html('<img class="pannable" width="'+config.width+'" src="' + config.src + '" />');
				
				config._img = container.children("img");
				config._img.bind("load", function(e) { 
					_pannable_init(); 
				});
				
				config._container = container;
				
				config._img.css('position', 'absolute');
				
				function _pannable_init() {
					var img = $(config._img);
					
					if(config.x == null) {
						img.css("left", ((config.width - img.width()) / 2) + "px");
					} else {
						img.css("left", -config.x + "px");
					}
					
					if(config.y == null) {
						img.css("top", ((config.height - img.height()) / 2) + "px");
					} else {
						img.css("top", -config.y + "px");
					}
					
					config.goal_left = parseInt(img.css("left"));
					config.goal_top = parseInt(img.css("top"));
					
					config.at_destination = false;
					config.animation_intv;
					config.is_animating = false;
				}
				
				function _frame_loop() {
					if(!config.at_destination) {
						var img = $(config._img);
						var limit = 2;
						
						var current_left = parseInt(img.css("left"));
						var current_top = parseInt(img.css("top"));
							
						var calc_left = Math.floor(current_left + (config.goal_left - current_left) * config.easing);
						var calc_top = Math.floor(current_top + (config.goal_top - current_top) * config.easing);
						
						if(Math.abs(calc_left - config.goal_left) < limit) {
							calc_left = config.goal_left;
							config.at_desination = true;
						} else {
							config.at_desination = false;
						}
						
						if(Math.abs(calc_top - config.goal_top) < limit) {
							calc_top = config.goal_top;
							
						} else {
							config.at_desination = false;
						}
												
						img.css("left", calc_left + "px");
						img.css("top", calc_top + "px");	
						
						if(config.at_destination) {
							
							clearInterval(config.animation_intv);
						}
					} else {
						
						config._container._stop_interval();
					}				
				}
				
				function _start_interval() {
					if(config.is_animating)
						return;
										
					config.no_work_count = 0;
					config.animation_intv = setInterval(_frame_loop, 40);
					config.is_animating = true;
				}
				
				function _stop_interval() {
					
					if(!config.is_animating)
						return;
					
					
					
					clearInterval(config.animation_intv);
					config.is_animating = false;
				}
				
				$(this).mousemove(function(event) {
					
					var img = $(event.target);
					
					var percent_x = Math.min(1, Math.max(0, event.clientX / config.width));
					var percent_y = Math.min(1, Math.max(0, event.clientY / config.height));
					
					if(config.movement_x)
						config.goal_left = -Math.floor((percent_x * (img.width() - config.width)));
					else
						config.goal_left = -Math.floor(((img.width() - config.width) / 2));
					
					if(config.movement_y)
						config.goal_top = -Math.floor((percent_y * (img.height() - config.height)));
					
					config.at_destination = false;
					
					_start_interval();
				});
				
				$(this).click(function(event) {
					window.top.closeOverlay();					
				});
			}
		});
		
		return this;
	
	};
 
 })(jQuery);
