/**
 * Declare ss object which encapsulates all utility methods.
 */
jQuery.ss = {

	preloadImages: function() {
		for (var i = 0; i < arguments.length; i++) {
			$("<img>").attr("src", arguments[i]);
		}
	},
	
	readCookie: function(name) {
		var nameEQ = name + "=";
		var ca = document.cookie.split(';');
		for (var i=0; i < ca.length; i++) {
			var c = ca[i];
			while (c.charAt(0) == ' ') { c = c.substring(1, c.length); }
			if (c.indexOf(nameEQ) == 0) {
				return c.substring(nameEQ.length, c.length);
			}
		}
		
		return null;
	},
	
	validEmail: function(str) {
		var emailFilter=/^.+@.+\..{2,3}$/;
		if (!(emailFilter.test(str))) { 
			return false;
		}

		var illegalChars=/[\(\)\<\>\,\;\:\\\/\"\[\]]/;
		if (str.match(illegalChars)) {
			return false;
		}

		return true;
	}
}

/**
 * This method toggles (show/hide) <span> elements under 
 * the element that invoked this method.
 */
$.fn.rotate = function() {
 	return this.each(function() {
		var $panel = $(this);
		$panel.find('span').hide().filter(":first").show();
		rotateNext();
		
		function rotateNext() {
			var $current = $panel.find('span:visible'),
				$next = $current.next();			
			if ($next.length == 0) {
				$next = $panel.find("span:first");
			}
			window.setTimeout(function() {
				$current.fadeOut(500, function() {
					$next.fadeIn(500, function() { rotateNext(); });	
				});
			}, 4000);
		}
	});
 }
 
 /**
  * Credit to: http://jqueryfordesigners.com/jquery-infinite-carousel/
  */
$.fn.infiniteCarousel = function () {

    function repeat(str, num) {
        return new Array( num + 1 ).join( str );
    }
  
    return this.each(function () {
        var $wrapper = $('> div', this).css('overflow', 'hidden'),
            $slider = $wrapper.find('> ul'),
            $items = $slider.find('> li'),
            $single = $items.filter(':first'),
            
            singleWidth = $single.outerWidth(), 
            visible = Math.ceil($wrapper.innerWidth() / singleWidth), // note: doesn't include padding or border
            currentPage = 1,
            pages = Math.ceil($items.length / visible);            


        // 1. Pad so that 'visible' number will always be seen, otherwise create empty items
        if (($items.length % visible) != 0) {
            $slider.append(repeat('<li class="empty" />', visible - ($items.length % visible)));
            $items = $slider.find('> li');
        }

        // 2. Top and tail the list with 'visible' number of items, top has the last section, and tail has the first
        $items.filter(':first').before($items.slice(- visible).clone().addClass('cloned'));
        $items.filter(':last').after($items.slice(0, visible).clone().addClass('cloned'));
        $items = $slider.find('> li'); // reselect
        
        // 3. Set the left position to the first 'real' item
        $wrapper.scrollLeft(singleWidth * visible);
        
        // 4. paging function
        function gotoPage(page) {
            var dir = page < currentPage ? -1 : 1,
                n = Math.abs(currentPage - page),
                left = singleWidth * dir * visible * n;
            
            $wrapper.filter(':not(:animated)').animate({
                scrollLeft : '+=' + left
            }, 500, function () {
                if (page == 0) {
                    $wrapper.scrollLeft(singleWidth * visible * pages);
                    page = pages;
                } else if (page > pages) {
                    $wrapper.scrollLeft(singleWidth * visible);
                    // reset back to start position
                    page = 1;
                } 

                currentPage = page;
            });                
            
            return false;
        }
        
        $wrapper.after('<a class="arrow back"></a><a class="arrow forward"></a>');
        
        // 5. Bind to the forward and back buttons
        $('a.back', this).click(function () {
            return gotoPage(currentPage - 1);                
        });
        
        $('a.forward', this).click(function () {
            return gotoPage(currentPage + 1);
        });
        
        // create a public interface to move to a specific page
        $(this).bind('goto', function (event, page) {
            gotoPage(page);
        });
    });  
};

/*
 * HTML construct:
 * 		<div id="">
 * 			<div class="a"></div>
 * 			<a class="a"></a>
 * 		</div>
 * 
 * Note(s):
 *   - <a> will toggle <div> with the same classname.
 */
$.fn.rotateBanner = function() {
	
	return this.each(function() {
		var $banners = $('.target', this).hide(),
			$firstBanner = $banners.filter(':first').show();
			
		// bind buttons/controls to banners
		$('.control', this).click(function() {
			$('.control.selected').removeClass('selected');
			$(this).addClass("selected");
			$banners.hide();
			var classNames = $(this).attr("class").split(" ");
			for (var i = 0; i < classNames.length; i++) {				
				$banners.filter("." + classNames[i]).show();
			}
		})
	});
}
