(function( $ ){
	
		/**
		 * Settings for use within the plugin
		 */
		var settings = {
			'pageClass' 	: '.tab-page',
			'linkClass' 	: '.tab-link',
			'activeClass'	: 'active',
			'fadeSpeed'		: 100
		};
		
		/**
		 * Public methods
		 */
		var methods = {
				
			/**
			 * Constructor function
			 * Merges user supplied options with default settings
			 * Collects, sets up links and tabs and binds them to the DOM object's data
			 */
			init : function( $this, options ) {

				// merge options
				$.extend( settings, options );
				
				// get the links and tabs
				if($this.data("tabs") === undefined) {
					
					tabs = {};

					// collect links and pages
					tabs.links 			= _collectLinks( $this );
					tabs.pages 			= _collectPages( $this );
					tabs.active			= 0;
					tabs.activeClass	= settings.activeClass;
					tabs.fadeSpeed		= settings.fadeSpeed;
				
                    console.log(tabs.links);
                
					// show the first page
					tabs.pages[0].show();
					//add active class to link
				    tabs.links[0].addClass(tabs.activeClass);	
					
					// bind to DOM object
					$this.data("tabs", tabs);
					
				}
								
				return $this;
				
		    },
		    
		    /**
		     * Hides active page and shows requested one
		     */
			show : function($this, arguments) {
		    	
		    	// get data for this DOM object's tab set
		    	tabs = $this.data("tabs");
		    	
		    	data = tabs;
		    	data.which = arguments[1];
		    	
		    	// if this page is not already active
		    	if(data.which != data.active) {
		    	
		    		_pageOut(tabs,tabs.active);

			    	setTimeout(function(){ 
			    		_pageIn(data); 
			    		
			    	}, tabs.fadeSpeed);
				    	
				    // set new active
				    tabs.active = arguments[1];
			    
		    	}
		    	
		    },
		    
		    /**
		     * Shows the next sequential page
		     */
		    next : function($this) {
		    	
		    	// get the data for this DOM object's tab set
		    	tabs = $this.data("tabs");
		    	
		    	// are we at the last page and therefore need to go back to the start?
		    	target = ( (tabs.active + 1) == Object.keys(tabs.pages).length ) ? 0 : tabs.active + 1;
		    	
		    	//show target
		    	$this.tabs("show", target);
		    	
		    },
		    
		    /**
		     * Shows the previous sequential page
		     */
		    previous : function($this) {
		    	
		    	// get the data for this DOM object's tab set
		    	tabs = $this.data("tabs");
		    	
		    	// are we at the first page and therefore need to the end?
		    	target = ( tabs.active == 0 ) ? Object.keys(tabs.pages).length - 1 : tabs.active - 1;
		    	
		    	//show target
		    	$this.tabs("show", target);
		    
		    }
		    
		};
		
		/**
		 * Private methods
		 */
		
		/**
		 * Collects the and returns an array of links to trigger the tabs
		 */
		function _collectLinks( $this ) {

			links = new Array();
			
			$this.find(settings.linkClass).each(function(i,e){
				
				link = $(e);
				link.click(function(){ $this.tabs("show", i); });
				
				links.push($(e));
			});
			
			return links
			
		}
		
		/**
		 * Collects and returns an array of pages which are triggered by the tabs
		 */
		function _collectPages( $this ) {
			
			pages = new Array();
			
			$this.find(settings.pageClass).each(function(i,e){
				$(e).hide();
				pages.push($(e));
			});
			
			return pages;
			
		}
		
		/**
		 * Animates a page out
		 */
		function _pageOut(tabs, which) {
			// hide active page
	    	tabs.pages[which].fadeOut(tabs.fadeSpeed);
	    		
		    // remove active class from link
		    tabs.links[which].removeClass(tabs.activeClass);
		}
		
		/** 
		 * Animates a page in
		 */
		function _pageIn(tabs) { 
			 // show new page
		    tabs.pages[tabs.which].fadeIn(tabs.fadeSpeed);
		    //add active class to link
		    tabs.links[tabs.which].addClass(tabs.activeClass);	
		}
		
		/**
		 * Plugin definition
		 * This function routes requests within the plugin
		 */
		$.fn.tabs = function( options_or_method ){
			      
			if ( methods[ options_or_method ] ) {
				return methods[ options_or_method ]( $( this ), arguments );
		    } else if ( typeof options_or_method === 'object' || ! options_or_method ) {
		    	return methods.init( $(this), options_or_method );
			} else {
				$.error( 'Method ' +  options_or_method + ' does not exist on jQuery.tabs' );
			} 
			  
		};
		
})( jQuery );	

  
