(function($){ 

$.fn.showSlides = function(options)
{
	var list = $(this);
  var cache = {};
  var imgId = 1;
  var currentImgId = 1;
	var lastTimeout;
	var slideShowPlaying = false;
	var imageCount = 0;
	
  var default_options = {
		container: $("#messageMainImage"),
     	slideDelay: 2500,
	  	preLoadInterval: 500,
		animationDuration: 500,
		updateHash: true,
	  	nextLink: $("a.next"),
	  	previousLink: $("a.previous"),
	  	imageChanged: function(img_num) { activeThumb(img_num); },
		onPause: function() { return true; },
		onPlay: function() { return true; },
		animation: 'fader',
		animate: function(newImg, forward) {
			switch(options.animation)
			{
			case 'fader':
			  fader(this, newImg); break;
			case 'slider':
			  slider(this, newImg, forward); break;
			case 'slideFade':
			  slideFade(this, newImg, forward); break;
			default:
			  fader(this, newImg);
			}
		}
  };

  for (attrname in options) {
      default_options[attrname] = options[attrname];
  }
  options = default_options;

	buildImageArray();
  showImage(self.document.location.hash);
	
	startCachingImages();
	bindEvents();
	if(options.autoPlay){ play(); }
	
	function play(dontDelay){
		//console.log('i want to play' + lastTimeout);
		slideShowPlaying = true;
		options.onPlay();
		//http://www.w3schools.com/jsref/met_win_cleartimeout.asp
		if(!lastTimeout){
			if(dontDelay)
				advanceSlideShow();
			else	
				lastTimeout = setTimeout(advanceSlideShow, options.slideDelay);
		}
	}
	function pause(){
		slideShowPlaying = false;
		options.onPause();
		
		if(lastTimeout){
			clearTimeout(lastTimeout);
			lastTimeout = undefined;
		}
	}
	function advanceSlideShow(){
		if (slideShowPlaying){
			showNext();
		}
	}
	function showNext() {
		if (currentImgId >= imgId - 1) {
          currentImgId = 0;
     }
		currentImgId = currentImgId - 0
		if(options.updateHash)
     		updateLocation(1+currentImgId);
		else
			showImage("#" + (1+currentImgId))
  }
  function showPrevious() {
      if (currentImgId == 1) {
          currentImgId = imgId;
      }
		if(options.updateHash)
     		updateLocation(currentImgId-1);
		else
			showImage("#" + (currentImgId-1))
  }
  function loadImage(id)
  {
     if (cache[id].image === undefined)
     {
         var img = document.createElement('img');
         img.src = cache[id].url;

         if (cache[id].additionalHref != null)
         {
             var link = document.createElement('a');
             link.href = cache[id].additionalHref;
             link.appendChild(img);
             img = link;
         }

         cache[id].image = img;
         return img;
     }
     else
     {
         return cache[id].image;
     }

  }
  function wrapWithLink(id) {
      if (cache[id].additionalHref != null)
      {
          var link = document.createElement('a');
          link.href = cache[id].additionalHref;
          link.appendChild();
          bigElement = link;
      }
  }
  function showImage(id) {
     if (id == '')
     {
         id = list.find('li:first a:first').attr('href').split("#")[1];
     }
     id = id.replace("#", "");
     var img = loadImage(id);

     options.animate.call(options.container, img, (currentImgId < id));

	 options.imageChanged(id, imageCount);
	   
     currentImgId = id;

		if (slideShowPlaying) {
			if (lastTimeout)
				clearTimeout(lastTimeout);

			lastTimeout = setTimeout(advanceSlideShow, options.slideDelay);
		}
  }
	function activeThumb(img_num){
		list.find('li a').removeClass("active");
		list.find('li a[href$="#' + img_num + '"]').attr("class", "active");

		  
	}
  function fader(caller, newImg){
		$(caller).attr("style", "opacity:0");
		$(caller).empty().append(newImg);
		$(caller).fadeTo(options.animationDuration, 1);
	}
	function slider(caller, newImg, forward){
		(forward) ? start = "1001px" : start = "-1001px";
		(forward) ? end = "-1001px"  :   end = "1001px";

		$(newImg).addClass('newbie').css("left",start);
	   
		$(caller).append(newImg).children(":not(.newbie)").stop().animate(
		  { left: end },
		  options.animationDuration, null,
		  function(){
		      $(this).remove();
		  });

		$(caller).children(".newbie").stop().animate(
	  		{ left: '0px' }, options.animationDuration).removeClass('newbie');

	}
	function slideFade(caller, newImg, forward){
		(forward) ? start = "1001px" : start = "-1001px";
		(forward) ? end = "-1001px"  :   end = "1001px";

		$(newImg).addClass('newbie').css("left",start);
	   
		$(caller).append(newImg).children(":not(.newbie)").css('opacity','1')
			.stop().animate(
		  { left: end, opacity: '0' },
		  null, null,
		  function(){
			   $(this).css('opacity','1');
		      $(this).remove();
		  });

		$(caller).children(".newbie").stop().animate(
	  		{ left: '0px' }).removeClass('newbie');
	}
  function updateLocation(id) {
      hash = self.document.location.hash ? self.document.location.hash: "#";
      new_location = document.location.toString().replace(hash, "");
      document.location = new_location + "#" + id;
  }
  function buildImageArray(){
	   list.children("li").each(function() {
	       a = $(this).children('a:first');
	       if (a.length == 1)
	       {
	           firstLink = $(a[0]);
	           link = {
	               id: imgId,
	               url: firstLink.attr("href"),
	               additionalHref: $(this).children(':nth-child(2)').attr("href")
	           };
	           a.attr("href", "#" + link.id);
	           cache[imgId] = link;
	           imgId++;
	       }
	   });
		imageCount = imgId - 1;
	}
	function startCachingImages(){
		//possibly a way to use say 'let i = 1' instead of closure.
	   for (i = 1; i < imgId; i++)
	   {
			(function (i){
				setTimeout(function(){loadImage(i)}, i * options.preLoadInterval);		
			})(i);
	   }
	}
	
	//function killSpaceBar(e)
	//{
  // var code;
  // e = e || window.event;
  // if (e.keyCode) {
  //     code = e.keyCode;
  // } else if (e.which) {
  //     code = e.which;
  // }
  // if (code == 32) {
  //     e.cancelBubble = true;
  //     e.returnValue = false;
  //
  //     if (e.stopPropagation) {
  //         e.stopPropagation();
  //         e.preventDefault();
  //     }
  //     return false;
  // }
	//}
	
	function bindEvents() {
		list.find("li a").click(function(){
			pause();
			return true;
		});
		
		options.nextLink.click(function() {
			  pause();
	        showNext();
	        return false;
	    });
	    options.previousLink.click(function() {
			  pause();
			  showPrevious();
	        return false;
	    });
	
	    $(window.location).bind(
	    	"change",
	    	function(objEvent, objData) {
	        	showImage(self.document.location.hash);
	    });
	
		 $(document).keyup(function(eh) {
			if (eh.keyCode == 32){
				if (slideShowPlaying){
					pause();
				}
				else
				{
					play(true);
				}
				return false; // killSpaceBar(eh);
			}
			if (eh.keyCode == 39){
				pause();
				showNext();
		   }

		   if (eh.keyCode == 37)
			{
				pause();
		      showPrevious();
			}
		 });
	    window.onunload = function() {};
	}
}
})(jQuery);
