/**
 * SMCarousel, a home-made jQuery Plugin for carousel effects at home page of 
 * St. Michael's Public Website.
 * 
 * It follows best practices in "A Plugin Development Pattern" by Mike Alsup at
 * http://www.learningjquery.com/2007/10/a-plugin-development-pattern
 * 
 * jQeury v1.4.1 is required.
 * Includes jquery-1.4.1.min.js
 * http://jquery.com/
 * Dual licensed under the MIT or GPL Version 2 licenses.
 * 
 * @version 2010-02-04
 */
(function($) {
	/**
	 * plugin definition
	 */
	$.fn.SMCarousel = function(options) {
		//debug(this);
		
		/*** build main options before element iteration ***/
		var opts = $.extend( {}, $.fn.SMCarousel.defaults, options);
		/*** iterate and reformat each matched element ***/
		return this.each(function() {
			$this = $(this);
			
			/*** build element specific options ***/
			var o = $.meta ? $.extend( {}, opts, $this.data()) : opts;
			
			$this.o = o;
			
			/*** BEGIN CUSTOMIZED CODES HERE ***/
			var objPrev   = $this.find("#"+o.idPrev);/* the left arrow button */
			var objNext   = $this.find("#"+o.idNext); /*the right arrow button */
			var objScreen = $this.find("#"+o.idScreen); /* the screen show visible Carousel items, default you can only see 3 items */
			var objCarousel = objScreen.find("ul"); /* the carousel which contains all images, much wide the the visible screen */
			var countItems = objCarousel.find("li").length;
			var verticalSpace = parseInt(objCarousel.find("li:first").css("padding-right"));/* the vertical margin between two items. Should be 5px */
			var lines = Math.ceil(countItems / o.screenSize);/* calculate how many lines the carousel items takes before we do magic. */
			var itemWidth = parseInt(objScreen.css("width")) / o.screenSize; /* pixel width of each item, including margin. */

			/*** only if more than 1 line, we do the animation magic ***/
			if (lines > 1) {
				/*** begin CSS adjustment ***/
				objCarousel
					/* Widen carousel <ul> to fit all <li> items in ONE line */
					.css("width", itemWidth * countItems)
					/* Move carousel 1 item left, so that visible items move smoothly. */
					.css("margin-left", -itemWidth);

				objScreen
					/* Visible screen width 5px less, for a correct bleeding of right side */
					.css("width", parseInt(objScreen.css("width")) - verticalSpace);
				
				objNext
					/* The next button moves towards left after above codes, try move it back */
					.css("margin-left", parseInt(objNext.css("margin-left")) + verticalSpace); 
				/*** end CSS adjustment ***/
				
				/* Show Prev & Next arrows. Make them clickable and image-changable on hover */
				objPrev.find("img")
					.attr("src", $this.o.imagePrevOff)
					.show()
					.click(function(){
						pause($this);
						prev($this);
					 })
					.mouseover(function() { 
						$(this).attr("src", $this.o.imagePrevOn);
					 })
					.mouseout(function() {
						$(this).attr("src", $this.o.imagePrevOff);
					 });
				objNext.find("img")
					.attr("src", $this.o.imageNextOff)
					.show()
					.click(function(){
						pause($this);
						next($this);
	                 })
					.mouseover(function() { 
						$(this).attr("src", $this.o.imageNextOn);
					 })
					.mouseout(function() {
						$(this).attr("src", $this.o.imageNextOff);
					 });
				
				/* Quickly (must) shift right for one unit, so that first is visible */
				prev($this, 25);

				/* begin auto play */
				setTimeout(function(){play($this);}, $this.o.autoplayInterval);
			}
			return $this;

			/*** call public function
			 * $.fn.SMCarousel.myPublicFunc($this);
			 */

		});
	};
	
	
	/**
	 * private function for debugging
	 */
	function debug($obj) {
		if (window.console && window.console.log)
			window.console.log('SMCarousel selection count: ' + $obj.size());
	};
	
	
	/**
	 * private function for debugging
	 */
	function play($this) {
		var playing = $this.o.playing;
		/* shift to next ONLY when flag is true */
		if (playing) {
			next($this);
		}
		setTimeout(function(){play($this);}, $this.o.autoplayInterval);
	};
	
	
	/**
	 * private function for pause auto playing for a while
	 */
	function pause($this) {
		/* set the auto play flag to be false */
		$this.o.playing = false;
		/* clear previous pausePlaying timer, if any! */
		if ($this.o.replayTimer) {
			clearTimeout($this.o.replayTimer);
		}
		/* create a new timer which restore auto play from false to true */
		$this.o.replayTimer = setTimeout(function(){
			$this.o.playing = true;
		}, $this.o.autoplayRestore);
	};
		
	
	/**
	 * private function for showing next
	 */
	function next($this, speed) {
		/* prepare parameters */
		speed = typeof(speed) != 'undefined' ? speed : "normal";

		/* convenient references */
		var $objCarousel = $this.find("#"+$this.o.idScreen).find("ul");
		var first = $objCarousel.find("li:first");
		var last  = $objCarousel.find("li:last");
		first.hide(speed, function() {
			$(this).insertAfter(last).show(speed);
		});
	};
	

	/**
	 * private function for showing previous
	 */
	function prev($this, speed) {
		/* prepare parameters */
		speed = typeof(speed) != 'undefined' ? speed : "normal";

		/* convenient references */
		var $objCarousel = $this.find("#"+$this.o.idScreen).find("ul");
		var first = $objCarousel.find("li:first");
		var last  = $objCarousel.find("li:last");
		last.hide(speed, function() {
			$(this).insertBefore(first).show(speed);
		});
	};
	
	
	/**
	 * plugin defaults
	 */
	$.fn.SMCarousel.defaults = {
		playing: true,
		replayTimer: null,
		screenSize: 3, /* how many visible items at any time */
		autoplayRestore: 10000, /* how long to wait to resume autoplaying, if paused */
		autoplayInterval: 7500, /*  how quick to autoplay each image */
		idPrev: "homepage_carousel_left", /* <div id="homepage_carousel_left"><img/></div> */
		idScreen: "homepage_carousel_middle",/* <div id="homepage_carousel_middle"><ul></div> */
		idNext: "homepage_carousel_right", /* <div id="homepage_carousel_right"><img/></div> */
		imagePrevOn: "/images/btn_arrow_left_on.gif",
		imagePrevOff: "/images/btn_arrow_left_off.gif",
		imageNextOn: "/images/btn_arrow_right_on.gif",
		imageNextOff: "/images/btn_arrow_right_off.gif"
	};
	

	/*** end ***/
})(jQuery);
