(function($){
	$.fn.fadepics = function(options)
	{
		var self = this;
		var lastTransition = (new Date).getTime();
		var underTransition = false;
		var paused = false;
		var offset = 0;
		var pictures = [];
		var thumbnails = [];
		var callback = {};
		var toggleElement = null;
		
		var toggle = function(index)
		{
			if ( !underTransition )
			{
				underTransition = true;
				toggleElement = thumbnails[index];
				$(thumbnails[offset]).fadeTo(100,0.5);
				$(pictures[offset]).fadeOut('slow',function(){
					offset = index;
					$(thumbnails[offset]).fadeTo(100,1);
					$(pictures[offset]).fadeIn('slow',function(){
						lastTransition = (new Date).getTime();
						underTransition = false;
					});
				});
			}
		}
		callback.transit = function(e)
		{
			var prev = offset<=0 ? pictures.length-1 : offset-1;
			var next = offset>=pictures.length-1 ? 0 : offset+1;
			if ( !e )
			{
				toggle(next);
				return false;
			}
			var html = document.documentElement;
			var body = document.body;
			var rect = e.currentTarget.getBoundingClientRect();
			var left = rect.left - html.clientLeft + (body.scrollLeft || html.scrollLeft);
			var top = rect.top - html.clientTop + (body.scrollTop || html.scrollTop);
			var x = e.pageX - left;
			var y = e.pageY - top;
			if ( x < e.currentTarget.offsetWidth/2 )
			{
				toggle(prev);
			}
			else
			{
				toggle(next);
			}
		}
		callback.pause = function()
		{
			paused = true;
		}
		callback.unpause = function()
		{
			paused = false;
		}
		callback.checkTransition = function()
		{
			var diff = (new Date).getTime() - lastTransition;
			// stopped is global
			if ( !underTransition && !window.stopped && !paused && diff>options.transition_interval )
			{
				callback.transit();
			}
		}
		callback.fadeinThumbnail = function()
		{
			if ( toggleElement!=this )
			{
				$(this).fadeTo(300,1);
			}
		}
		callback.fadeoutThumbnail = function()
		{
			if ( toggleElement!=this )
			{
				$(this).fadeTo(300,0.5);
			}
		}
		callback.preventDefault = function(e){
			if (e.preventDefault)
			{
				e.preventDefault();
			}
			window.returnValue = false;
		}
		
		//
		// initialize
		//
		// thumbnail list
		var thumbnailInnerWrapper = document.createElement('span');
		thumbnailInnerWrapper['class'] = thumbnailInnerWrapper['className'] = 'thumbnail-inner-wrapper';
		var thumbnailWrapper = document.createElement('div');
		thumbnailWrapper['class'] = thumbnailWrapper['className'] = 'thumbnail-wrapper';
		thumbnailWrapper.style.whiteSpace = 'nowrap';
		thumbnailWrapper.style.overflow = 'hidden';
		$(thumbnailWrapper).append(thumbnailInnerWrapper);
		this.after(thumbnailWrapper);
		if ( options.files )
		{
			for ( var i=0; i<options.files.length; i++ )
			{
				var img = new Image();
				img.src = options.files[i];
				$(img)
					.mouseover(callback.pause)
					.mouseout(callback.unpause)
					.mousedown(callback.preventDefault)
					.mousemove(callback.showArrow)
					.bind('drag',callback.preventDefault)
					.click(callback.transit)
					.bind('contextmenu',function(){return false;})
					.bind('selectstart',function(){return false;});
				img.style.display = 'none';
				pictures.push(img);
				this.append(img);
				
				var thumb = new Image(75,50);
				thumb.src = options.files[i];
				thumb['class'] = thumb['className'] = 'thumbnail';
				thumb.onmouseover = callback.fadeinThumbnail;
				thumb.onmouseout = callback.fadeoutThumbnail;
				thumb.onclick = (function(i){
					return function(){
						toggle(i);
					}
				})(i);
				$(thumb)
					.mousedown(callback.preventDefault)
					.bind('drag',callback.preventDefault)
					.bind('contextmenu',function(){return false;})
					.bind('selectstart',function(){return false;})
					.fadeTo(1,0.5);
				thumbnails.push(thumb);
				$(thumbnailInnerWrapper).append(thumb);
			}
		}
		$(thumbnails[0]).fadeTo(1,1);
		//
		//
		//
		var ax;
		var ay;
		var x;
		var y;
		$(document).mousemove(function(e){
			var html = document.documentElement;
			var body = document.body;
			var rect = thumbnailWrapper.getBoundingClientRect();
			var left = rect.left - html.clientLeft + (body.scrollLeft || html.scrollLeft);
			var top = rect.top - html.clientTop + (body.scrollTop || html.scrollTop);
			x = e.pageX - left;
			y = e.pageY - top;
			
			var rect = self.getBoundingClientRect();
			var left = rect.left - html.clientLeft + (body.scrollLeft || html.scrollLeft);
			var top = rect.top - html.clientTop + (body.scrollTop || html.scrollTop);
			ax = e.pageX - left;
			ay = e.pageY - top;
		});
		$(thumbnailWrapper).mouseout(function(e){
			var rect = e.currentTarget.getClientRects()[0];
			if( e.clientX >= rect.left
			 && e.clientX <= rect.right
			 && e.clientY >= rect.top
			 && e.clientY <= rect.bottom
			)
			{
				return null;
			}
			$(thumbnailInnerWrapper).stop(true,false);
			clearTimeout(timerId);
		});
		//
		//
		//
		var arrowNext = new Image();
		var arrowPrev = new Image();
		arrowNext['class'] = arrowNext['className'] =
		arrowPrev['class'] = arrowPrev['className'] = 'arrow';
		arrowNext.src = 'images/next.png';
		arrowPrev.src = 'images/back.png';
		arrowNext.style.position =
		arrowPrev.style.position = 'absolute';
		arrowNext.style.top =
		arrowPrev.style.top = '210px';
		arrowNext.style.right = '2px';
		arrowPrev.style.left = '2px';
		var arrowNextBg = document.createElement('div');
		var arrowPrevBg = document.createElement('div');
		$(arrowNextBg)
			.fadeTo(1,0)
			.css('position','absolute')
			.css('top','0')
			.css('left','644px')
			.css('background','white')
			.css('width','20px')
			.css('height','423px')
			.append(arrowNext);
		$(arrowPrevBg)
			.fadeTo(1,0)
			.css('position','absolute')
			.css('top','0')
			.css('left','0')
			.css('background','white')
			.css('width','20px')
			.css('height','423px')
			.append(arrowPrev);
		arrowNextBg.onclick = function()
		{
			var next = offset>=pictures.length-1 ? 0 : offset+1;
			toggle(next);
		}
		arrowPrevBg.onclick = function()
		{
			var prev = offset<=0 ? pictures.length-1 : offset-1;
			toggle(prev);
		}
		this
			.append(arrowNextBg)
			.append(arrowPrevBg)
			.mouseover(function(e){
				$(arrowPrevBg)
					.fadeTo(100,0.5);
				$(arrowNextBg)
					.fadeTo(100,0.5);
				/*
				arrowNextBg.style.display =
				arrowPrevBg.style.display = 'inline';
				*/
			})
			.mouseleave(function(e){
				$(arrowPrevBg)
					.fadeTo(100,0);
				$(arrowNextBg)
					.fadeTo(100,0);
				/*
				arrowNextBg.style.display =
				arrowPrevBg.style.display = 'none';
				*/
			});
		//
		//
		//
		var duration = 1000;
		var easing = 'swing';
		var movement = 15;
		var marginLeft = 0;
		var timerId = null;
		var twStyle = thumbnailWrapper.currentStyle || document.defaultView.getComputedStyle(thumbnailWrapper,'');
		var tiwStyle = thumbnailInnerWrapper.currentStyle || document.defaultView.getComputedStyle(thumbnailInnerWrapper,'');
		callback.scrollThumbnails = function()
		{
			if ( !x || !y ){ return; }
			if ( y < 0 || thumbnailWrapper.offsetHeight < y )
			{
				return;
			}
			if ( thumbnailWrapper.offsetWidth > x && x > thumbnailWrapper.offsetWidth-128 )
			{
				if ( -marginLeft<thumbnailInnerWrapper.offsetWidth-thumbnailWrapper.offsetWidth )
				{
					marginLeft -= movement;
				}
				else
				{
					marginLeft = -(thumbnailInnerWrapper.offsetWidth-thumbnailWrapper.offsetWidth)
				}
				thumbnailInnerWrapper.style.marginLeft = marginLeft+'px';
			}
			else if ( 0 < x && x < 128 )
			{
				if ( marginLeft<0 )
				{
					marginLeft += movement;
				}
				else
				{
					marginLeft = 0;
				}
				thumbnailInnerWrapper.style.marginLeft = marginLeft+'px';
			}
		}
		setInterval(callback.scrollThumbnails,15);
		
		pictures[0].style.display = 'block';
		setInterval(callback.checkTransition,100);
	}
})(jQuery);
