/*
 *
 * mbFader v1.0 - for jQuery 1.4.2+
 *
 * Copyright 2010, Michael David Barrett
 * http://codecanyon.net/user/mike182uk
 *
 * You need to buy a license to use this script.
 * http://codecanyon.net/wiki/buying/howto-buying/licensing/
 *
 * Date: 30/10/2010
 *
 * For API documentation, FAQ's, Examples and other useful information visit http://www.mb-tools.co.uk/mbFader
 *
 */
(function($){
	
	//used to fix method calling issues on un-instantiated objects
	$.bind = function(object,method){
		var args = Array.prototype.slice.call(arguments,2);
		return function(){
			var args2 = [this].concat(args,$.makeArray(arguments));
			return method.apply(object,args2);
		};
	};
	
	//mbFader object
	var mbFader = function(){};
	
	//extend mbFader object prototype
	mbFader.prototype = {
		init:function(e,config)
		{
			var self = this,
				defaults = {
					autoplay: true,
					showControls: { 
						next: false, 
						prev: false, 
						play: false, 
						pause: false, 
						first: false, 
						last: false 
					},
					playPauseButtonSeperate: false,
					controlsText: {
						next: 'Next',
						prev: 'Previous',
						play: 'Play',
						pause: 'Pause',
						first: 'First',
						last: 'Last'
					},
					controlsLocation: 'external',
					slideDuration: 3000,
					fadeSpeed: 800,
					startSlide: 1,
					pagination: false,
					paginationLocation: 'external',
					pauseOnHover: true,
					playDirection: 'ltr',
					mousewheelsupport: true,
					callbacks : {
						movenext: false,
						moveprev: false,
						movefirst: false,
						movelast: false,
						play: false,
						pause: false,
						fadestart: false,
						fadeend: false,
						mousewheelup: false,
						mousewheeldown: false,
						hoveron: false,
						hoverout: false,
						controlsclick: false,
						controlshoveron: false,
						controlshoverout: false,
						paginationclick: false,
						paginationhoveron: false,
						paginationhoverout: false
					},
					fadeControlsHover:false,
					fadeControlsHoverSpeed: 200,
					fadePaginationHover: false,
					fadePaginationHoverSpeed: 200,
					randomizeOnInit:false,
					slideDurations: {},
					optomize: true
				}
			
			this.settings = $.extend(true,defaults,config);
			this.obj = e;
			this.e = $(e);
			this.id = this.obj.id;
			this.slides = this.e.find('ul:first');
			this.slides.find('li')
					   .addClass('mbFader_slide');
			this.numOfSlides = this.e.find('li').length;
			this.slideHeight = this.e.find('li').eq(0).height();
			this.slideWidth = this.e.find('li').eq(0).width();
			this.currentSlide = this.settings.startSlide;
			this.pausedByHover = 0;
			this.slides.css({
							'display':'none'
						})
						.addClass('mbFader_slides');
			this.e.css({
				'width':this.slideWidth,
				'height':this.slideHeight,
				'position':'relative'
			});
			this.e.append('<div id="mbFader_content_container_1"></div><div id="mbFader_content_container_2"></div>');
			this.contentContainer1 = this.e.find('#mbFader_content_container_1');
			this.contentContainer2 = this.e.find('#mbFader_content_container_2');
			
			var contentContainerCss = {
				'position':'absolute',
				'width': this.slideWidth,
				'height': this.slideHeight,
				'top':'0',
				'left':'0'
			}
			
			this.contentContainer1.css(contentContainerCss);
			this.contentContainer2.css(contentContainerCss);
			this.contentContainer1.css({
				'z-index':'399'
			});
			this.contentContainer2.css({
				'z-index':'398'
			});
			this.clickStatus = 1;
			this.hoverStatus = 1;
			this.playStatus = (this.settings.autoplay) ? 1 : 0;
			this.timer = 0;
			
			//init first slide
			this.activeContentContainer = 1;
			this.loadIntoContainer(this.currentSlide,1);
			
			//inject controls
			if(this.settings.showControls){ this.inject( this.settings.controlsLocation, this.generateControls() ); }
			
			//inject pagination
			if(this.settings.pagination){ this.inject( this.settings.paginationLocation, this.generatePagination() ); }
			
			//init randomize slides
			if(this.settings.randomizeOnInit){ this.randomizeSlides(); }
			
			//attach event bindings
			this.eventBindings();
			
			//init autoplay
			if(this.settings.autoplay){
				this.play(1);
			}
			else {
				this.e.addClass('mbFader_paused');	
			}
		},
		getSlideDuration:function()
		{
			return (this.settings.slideDurations['slide_' + this.currentSlide] !== undefined) ? this.settings.slideDurations['slide_' + this.currentSlide] : this.settings.slideDuration;
		},
		loadIntoContainer:function(slide,container,fade)
		{
			var slideObj = this.slides.find('li').eq(slide - 1);
				slideContents = slideObj.html(),
				containerObj = (container == 1) ? this.contentContainer1 : this.contentContainer2;
			
			if(this.settings.optomize){
				this.optomizeContainerLoad(slide,container);	
			}
			
			containerObj.html(slideContents);
			
			if(fade){
				this.fade(container);
			}
			else {
				this.activeContentContainer = container;
			}
		},
		optomizeContainerLoad:function(slide,container)
		{
			var content = (this.activeContentContainer == 1) ? this.contentContainer1.html() : this.contentContainer2.html();
			this.slides.find('li').eq(this.activeContentsBelongTo).html(content);
			this.activeContentsBelongTo = slide - 1;
			this.slides.find('li').eq(slide - 1).html('');
		},
		movenext:function()
		{
			var nextSlide = (this.currentSlide + 1 == this.numOfSlides + 1) ? 1 : this.currentSlide + 1;
			this.goto(nextSlide);
			if(this.settings.callbacks.moveprev !== false){ this.settings.callbacks.moveprev(this); }
		},
		moveprev:function()
		{
			var prevSlide = (this.currentSlide - 1 == 0) ? this.numOfSlides : this.currentSlide - 1;
			this.goto(prevSlide);
			if(this.settings.callbacks.movenext !== false){ this.settings.callbacks.movenext(this); }	
		},
		play:function(prepOnly)
		{
			var self = this;
			this.playStatus = 1;
			if(prepOnly !== 1){
				switch(this.settings.playDirection){
					case 'ltr':
						this.movenext();
					break;
					case 'rtl':
						this.moveprev();
					break;
				}
				clearInterval(this.timer);
			}
			this.e.addClass('mbFader_playing')
				  .removeClass('mbFader_paused');
			if(!this.settings.playPauseButtonSeperate){
				$('#'+this.id+'_playpause').text(this.settings.controlsText.pause)	
			}
			this.timer = setInterval(function(){ $.bind(self,self.play()) }, self.getSlideDuration() );
			if(this.settings.callbacks.play !== false){ this.settings.callbacks.play(this); }
		},
		pause:function()
		{
			if(this.playStatus == 1){
				clearInterval(this.timer);
				this.playStatus = 0;
				this.e.addClass('mbFader_paused')
					  .removeClass('mbFader_playing');
				if(!this.settings.playPauseButtonSeperate && !this.pausedByHover){
					$('#'+this.id+'_playpause').text(this.settings.controlsText.play);	
				}
				if(this.settings.callbacks.pause !== false){ this.settings.callbacks.pause(this); }
			}
		},
		movefirst:function()
		{
			this.goto(1);
			if(this.settings.callbacks.movefirst !== false){ this.settings.callbacks.movefirst(this); }
		},
		movelast:function()
		{
			this.goto(this.numOfSlides);
			if(this.settings.callbacks.movelast !== false){ this.settings.callbacks.movelast(this); }
		},
		goto:function(slide,container)
		{
			if(this.clickStatus == 1){
				this.clickStatus = 0;
				if(this.currentSlide == slide){
					this.clickStatus = 1;
					return false;
				}
				else {
					var container = (this.activeContentContainer == 1) ? 2 : 1;
					this.currentSlide = slide;
					this.loadIntoContainer(slide,container,1);
				}
			}
		},
		fade:function(container,fadeSpeed)
		{
			var self = this,
				opacity, 
				activeContainer
			
			if(self.settings.callbacks.fadestart !== false){ self.settings.callbacks.fadestart(this); }
			
			if(container == 1){
				opacity = 1;
				activeContainer = 1;
			}
			else {
				opacity = 0;
				activeContainer = 2;
			}
			
			if(opacity == 1){
				self.contentContainer1.css('display','block');	
			}
			
			self.contentContainer1.animate({
				'opacity':opacity
			},{
				duration: self.fadeSpeed,
				complete: function(){
					self.activeContentContainer = activeContainer;
					self.clickStatus = 1;
					if(self.settings.callbacks.fadeend !== false){ self.settings.callbacks.fadeend(self); }
					if(opacity == 0){
						self.contentContainer1.css('display','none');	
					}
				}
			});
		},
		inject:function(location,html)
		{
			if(location == 'internal'){
				this.e.append(html);
			}
			else {
				this.e.after(html);
			}
		},
		generateControls:function()
		{
			var controls = {
				next: {
					id: '_movenext',
					href: 'javascript:void(0)',
					label: this.settings.controlsText.next,
					show: this.settings.showControls.next
				},
				prev: {
					id: '_moveprev',
					href: 'javascript:void(0)',
					label: this.settings.controlsText.prev,
					show: this.settings.showControls.prev
				},
				play: {
					id: '_play',
					href: 'javascript:void(0)',
					label: this.settings.controlsText.play,
					show: this.settings.showControls.play
				},
				pause: {
					id: '_pause',
					href: 'javascript:void(0)',
					label: this.settings.controlsText.pause,
					show: this.settings.showControls.pause
				},
				first: {
					id: '_movefirst',
					href: 'javascript:void(0)',
					label: this.settings.controlsText.first,
					show: this.settings.showControls.first
				},
				last: {
					id: '_movelast',
					href: 'javascript:void(0)',
					label: this.settings.controlsText.last,
					show: this.settings.showControls.last
				}
			};
			
			var controlsStructure = '<div id="'+this.id+'_controls">';
			for(x in controls){
				var c = controls[x];
				if(c.show){
					controlsStructure += '<a href="'+c.href+'" id="'+this.id + c.id+'">'+c.label+'</a>';
				}
			}
			controlsStructure += "</div>";
			
			if(!this.settings.playPauseButtonSeperate){
				var playPauseLabel = (this.settings.autoplay) ? 'Pause' : 'Play';
				controlsStructure = $(controlsStructure);
				controlsStructure.find("a[id='"+this.id+"_pause']")
								 .after('<a id="'+this.id+'_playpause" href="javascript:void(0);">'+playPauseLabel+'</a>');
				controlsStructure.find("a[id='"+this.id+"_pause'], a[id='"+this.id+"_play']")
								 .remove();
			}		
			if(this.settings.fadeControlsHover){
				controlsStructure.hide();
			}
			return controlsStructure;
		},
		generatePagination:function()
		{
			var paginationStructure = '<div id="'+this.id+'_pagination">';
			for(var i=1; i<=this.numOfSlides; i++){
				var klass = (i==this.settings.startSlide) ? 'mbFader_current_slide' : '';
				paginationStructure += '<a href="javascript:void(0);" class="'+klass+'">'+i+'</a>';
			}
			paginationStructure += "</div>";
			if(this.settings.fadePaginationHover){
				paginationStructure = $(paginationStructure);
				paginationStructure.hide();
			}
			return paginationStructure;
		},
		randomizeSlides:function()
		{
			var slides = [];
			this.slides.find('li').each(function(){
				slides.push($(this));
				$(this).remove();
			});
			slides.sort(function(){ return Math.round(Math.random())-0.5; });
			for(x in slides){
				this.slides.append(slides[x]);	
			}
		},
		eventBindings:function()
		{
			var self = this;
				
			//controls / pagination
			$('#'+this.id+'_movenext, .'+this.id+'_movenext').bind('click',function(){ self.movenext(); });
			$('#'+this.id+'_moveprev, .'+this.id+'_moveprev').bind('click',function(){ self.moveprev(); });
			$('#'+this.id+'_movefirst, .'+this.id+'_movefirst').bind('click',function(){ self.movefirst(); });
			$('#'+this.id+'_movelast, .'+this.id+'_movelast').bind('click',function(){ self.movelast(); });
			$('#'+this.id+'_play, .'+this.id+'_play').bind('click',function(){ self.play(1); });
			$('#'+this.id+'_pause, .'+this.id+'_pause').bind('click',function(){ self.pause(); });
			$('#'+this.id+'_playpause').bind('click',function(){ 
				if(self.playStatus == 0){
					self.play(1);
				}
				else {
					self.pause();
				}
			});
			$('#'+this.id+'_pagination').find('a').bind('click',function(){
				self.goto(parseInt($(this).text()));
			});
			
			//controls callbacks
			$('#'+this.id+'_controls').bind('mouseover',function(){ 
									      if(self.settings.callbacks.controlshoveron !== false){ self.settings.callbacks.controlshoveron(self); } 
									  })
									  .bind('mouseout',function(){ 
									      if(self.settings.callbacks.controlshoverout !== false){ self.settings.callbacks.controlshoverout(self); }
									  })
									  .find('a')
									  .bind('click',function(){ 
									      if(self.settings.callbacks.controlsclick !== false){ self.settings.callbacks.controlsclick(self); }
									  });
			
			//pagination callbacks
			$('#'+this.id+'_pagination').bind('mouseover',function(){ 
											  if(self.settings.callbacks.paginationhoveron !== false){ self.settings.callbacks.paginationhoveron(self); }
										  })
										  .bind('mouseout',function(){ 
											  if(self.settings.callbacks.paginationhoverout !== false){ self.settings.callbacks.paginationhoverout(self);}
										  })
										  .find('a')
										  .bind('click',function(){ 
											  if(self.settings.callbacks.paginationclick !== false){ self.settings.callbacks.paginationclick(self); }
										  });
			
			//fader hover statuses
			this.e.bind('mouseover',function(){
							if(self.settings.callbacks.hoveron !== false){ self.settings.callbacks.hoveron(self); }
						}).bind('mouseout',function(){
							if(self.settings.callbacks.hoverout !== false){ self.settings.callbacks.hoverout(self); }
						});
				
			
			//user defined pagination
			$("[class*='"+self.id+"_gotoSlide']").bind('click',function(){
				var slide;
				var classes = $(this).attr('class').split(' ');
				for(c in classes){
					if(classes[c].search(self.id+"_gotoSlide") !== -1){
						slide = classes[c].substring(
							classes[c].indexOf("[")+1,
							classes[c].indexOf("]")
						);
					}
				}
				self.goto(slide);
			});	
			
			//fade controls in on hover
			if(this.settings.showControls && this.settings.fadeControlsHover){
				this.e.bind('mouseover',function(){
						$('#'+self.id+'_controls').fadeIn(self.settings.fadeControlsHoverSpeed);
					}).bind('mouseout',function(){
						$('#'+self.id+'_controls').fadeOut(self.settings.fadeControlsHoverSpeed);
					});
			}
			
			//fade pagination in on hover
			if(this.settings.pagination && this.settings.fadePaginationHover){
				this.e.bind('mouseover',function(){
						$('#'+self.id+'_pagination').fadeIn(self.settings.fadePaginationHoverSpeed);
					}).bind('mouseout',function(){
						$('#'+self.id+'_pagination').fadeOut(self.settings.fadePaginationHoverSpeed);
					});
			}
			
			//pause on hover
			if(this.settings.pauseOnHover){
				self.e.bind('mouseover',function(){
						 if(self.playStatus == 1 && self.pausedByHover == 0){
							 self.pausedByHover = 1;
							 self.pause();
						 }
					 })
					 .bind('mouseout',function(){
						  if(self.playStatus == 0  && self.pausedByHover == 1){
							  self.pausedByHover = 0;
							  self.play(1);
						  }
					 });
			}
			
			//mousewheel support
			if(this.settings.mousewheelsupport){
				this.e.mousewheel(function(event,delta){
					if(delta > 0){ 
						self.movenext(); 
						if(self.settings.callbacks.mousewheelup !== false){
							self.settings.callbacks.mousewheelup(); 
						}
					}
					if(delta < 0){ 
						self.moveprev(); 
						if(self.settings.callbacks.mousewheeldown !== false){
							self.settings.callbacks.mousewheeldown();  
						}
					}
					return false; 
				});
			}
		}
	};
	
	$.fn.mbFader = function(config){
		return this.each(function(){
			if(!this.mbFader){ 
				this.mbFader = new mbFader();
				this.mbFader.init(this,config);
			}
		});
	};
	
})(jQuery);

//external plugins - mousewheel support.
(function(){
		
	/*! Copyright (c) 2009 Brandon Aaron (http://brandonaaron.net)
	 * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
	 * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
	 * Thanks to: http://adomas.org/javascript-mouse-wheel/ for some pointers.
	 * Thanks to: Mathias Bank(http://www.mathias-bank.de) for a scope bug fix.
	 *
	 * Version: 3.0.2
	 * 
	 * Requires: 1.2.2+
	 */
	var types = ['DOMMouseScroll', 'mousewheel'];
	
	$.event.special.mousewheel = {
		setup: function() {
			if ( this.addEventListener )
				for ( var i=types.length; i; )
					this.addEventListener( types[--i], handler, false );
			else
				this.onmousewheel = handler;
		},
		
		teardown: function() {
			if ( this.removeEventListener )
				for ( var i=types.length; i; )
					this.removeEventListener( types[--i], handler, false );
			else
				this.onmousewheel = null;
		}
	};
	
	$.fn.extend({
		mousewheel: function(fn) {
			return fn ? this.bind("mousewheel", fn) : this.trigger("mousewheel");
		},
		
		unmousewheel: function(fn) {
			return this.unbind("mousewheel", fn);
		}
	});
	
	
	function handler(event) {
		var args = [].slice.call( arguments, 1 ), delta = 0, returnValue = true;
		
		event = $.event.fix(event || window.event);
		event.type = "mousewheel";
		
		if ( event.wheelDelta ) delta = event.wheelDelta/120;
		if ( event.detail     ) delta = -event.detail/3;
		
		// Add events and delta to the front of the arguments
		args.unshift(event, delta);
	
		return $.event.handle.apply(this, args);
	}
})(jQuery);
