/* 

Author: Kevin O'Brien
Email: kevin@clockwork.net
Company: Clockwork Acive Media Systems
Last Modified: 11.15.09

*/

jQuery(document).ready(function() {
	var params = {'width': 697, 'height': 412, "continuous": true }
	jQuery('#imageSlider').tentcarousel(params);
});

(function($) {

	$.fn.tentcarousel = function(params) {
		return this.each(function() {
			new $.tentcarousel(jQuery(this), params);
		});
	};

	$.tentcarousel = function(e, params) {
	
		//Config variables
		this.target = $tc = jQuery(e);
		this.current = 0;
		this.last_current = 0
		this.doubleClicks = 0;
		this.doubleClicksp = 0;
		if(params.width) { this.carousel_width = params.width }else { alert("Carousel: 'height' & 'width' are required"); return false; }
		if(params.height) { this.carousel_height = params.height }else { alert("Carousel: 'height' & 'width' are required"); return false; }
		this.carousel_height = params.height || this.fail();
		this.continuous = params.continuous === undefined ? false : params.continuous;
		this.loop = params.loop === undefined ? true : params.loop;
		this.speed = params.speed === undefined ? 800 : params.speed;
		this.interval = params.interval === undefined ? 4000 : params.interval;
		this.indicator = params.indicator === undefined ? true : params.indicator;
		this.indicator_numbered = params.indicator_numbered === undefined ? false : params.indicator_numbered;
		this.transition = params.transition || 'slide'
		//Class Names
		this.carousel_clip_class = params.carousel_clip_class || 'carousel_page_clip';
		this.carousel_contain_class = params.carousel_contain_class || 'carousel_page_contain';
		this.carousel_page_class = params.carousel_page_class || 'carousel_page';
		this.previous_class = params.previous_class || 'carousel_prev';
		this.next_class = params.next_class || 'carousel_next';
		this.page_count = this.target.find('.'+this.carousel_page_class).length;
		//Callbacks
		this.previous_callback_done = params.previous_callback_done || null;
		this.next_callback_done = params.next_callback_done || null;
		this.previous_callback_start = params.previous_callback_start || null;
		this.next_callback_start = params.next_callback_start || null;
		this.carousel_active = params.carousel_active || null;
		
		//Setup Carousel
		this.config_carousel();
		this.apply_css();
		this.apply_listeners();
		this.update_indicator();
		
		try { this.carousel_active(this.target); }catch(e) {}
		
	}

	$.tentcarousel.prototype = {
	
		config_carousel: function() {
		
   			this.target.addClass('sliderActivated');
			this.target.wrapInner('<div class="'+this.carousel_contain_class+'"></div>');
			this.target.wrapInner('<div class="'+this.carousel_clip_class+'"></div>');
			this.page_contain = this.target.find('.'+this.carousel_contain_class);
			this.clip = this.target.find('.'+this.carousel_clip_class);
			this.pages = this.target.find('.'+this.carousel_page_class);
			this.target.append('<a href="#" class="'+this.previous_class+'" title="Previous">&lt</a><a href="#" class="'+this.next_class+'" title="Next">&gt</a>');
			this.prev = this.target.find('.'+this.previous_class);
			this.next = this.target.find('.'+this.next_class);
			if(this.indicator || this.indicator_numbered) this.make_indicator();
			if(this.transition == 'fade') this.continuous = false;
				
		},
		
		apply_css: function() {
		
			this.target.css({ 'width': this.carousel_width+'px', 'height': this.carousel_height+'px', 'overflow': 'hidden' })
			this.clip.css({'width':this.carousel_width+'px', 'height':this.carousel_height+'px', 'overflow':'hidden', 'position':'relative'});
			this.page_contain.css({'width':(this.page_count*this.carousel_width)+'px', 'position':'absolute'});
			this.pages.css({'width':this.carousel_width+'px', 'height':this.carousel_height+'px', 'overflow':'hidden', 'position':'relative', 'float':'left'});
			if(this.continuous) this.make_continuous();
			if(!this.loop) this.prev.addClass('disabled');
			if(this.transition == 'fade') {
				this.pages.css({'position': 'absolute', 'left': 0, 'top': 0, 'z-index': 1});
				this.target.find('.'+this.carousel_page_class+':first').css({'z-index': 2});
			}
		
		},
		
		apply_listeners: function() {

			var target = this;

			//Listeners
			this.prev.click(function(){ target.go_prev(); return false; });
			this.next.click(function(){ target.go_next(); return false; });
			if(this.interval) {
				this.timer = setInterval(function(){ target.go_next(); return false; }, this.interval);
				this.prev.click(function(){ target.stop_auto_slide(); });
				this.next.click(function(){ target.stop_auto_slide(); });
			}
		
		},
		
		go_next: function(jumped_from) {
		
			var o = this;
		
			try { this.next_callback_start(this); }catch(e) {}
		
			//Calculating current page
			if(!this.loop) this.prev.removeClass('disabled');
			this.last_current = jumped_from === undefined ? this.current : jumped_from;
			this.current++;
			this.jumpped_by = this.current - this.last_current;
			var hit_end = false;
			if(this.current >= this.page_count) {
				if(this.loop) {
					if(!this.continuous) this.current = 0;
				}else {
					if(this.current > this.page_count-1) {
						hit_end = true;
					}
					this.current--;
				}
			}
			if( !this.loop && ((this.current + 1) >= this.page_count)) {
				this.next.addClass('disabled');
			}
			
			if(!hit_end) {
				//Animate
				switch(this.transition) {
				
					case 'fade':
						this.target.find('.'+this.carousel_page_class+':eq('+this.last_current+')').stop();
						this.target.find('.'+this.carousel_page_class+':eq('+this.last_current+')').css('z-index','3').animate({'opacity': 0}, this.speed);
						this.target.find('.'+this.carousel_page_class+':eq('+this.actual_page()+')').stop();
						this.target.find('.'+this.carousel_page_class+':eq('+this.actual_page()+')').css('z-index','2').css('opacity',1);
						break;

					default:
						this.page_contain.stop();
						this.page_contain.animate({left:-(this.current * this.carousel_width) +"px"}, this.speed, function(){ o.callback_next(); });

				}

				if(this.continuous) {
					for(var i=0; i<this.jumpped_by; i++ ) {
						var farthestRight = parseInt(this.target.find('.'+this.carousel_page_class+':last').css('left').replace('px','')) + this.carousel_width;
						this.target.find('.'+this.carousel_page_class+':eq('+(this.doubleClicks + i + this.doubleClicksp)+')').clone().appendTo(this.page_contain);
						this.target.find('.'+this.carousel_page_class+':last').css('left',farthestRight);
					}
					this.doubleClicks += this.jumpped_by - 1;
				}
				
				this.update_indicator();
				this.doubleClicks++;
			}
		},
		
		go_prev: function(jumped_from) {
		
			var o = this;
		
			try { this.previous_callback_start(this); }catch(e) {}
		
			//Calculating current page
			if(!this.loop) this.next.removeClass('disabled');
			this.last_current = jumped_from === undefined ? this.current : jumped_from;
			this.current--;
			this.jumpped_by = this.last_current - this.current;
			var hit_end = false;
			if(this.current < 0) {
				if(this.loop) {
					if(!this.continuous) this.current = this.page_count - 1;
				}else {
					if(this.current < 0) {
						hit_end = true;
					}
					this.current++;
				}
			}
			if( !this.loop && ((this.current - 1) <= this.page_count)) {
				this.prev.addClass('disabled');
			}
			
			if(!hit_end) {
				//Animate
				switch(this.transition) {
				
					case 'fade':
						this.target.find('.'+this.carousel_page_class+':eq('+this.last_current+')').stop();
						this.target.find('.'+this.carousel_page_class+':eq('+this.last_current+')').css('z-index','3').animate({'opacity': 0});
						this.target.find('.'+this.carousel_page_class+':eq('+this.actual_page()+')').stop()
						this.target.find('.'+this.carousel_page_class+':eq('+this.actual_page()+')').css('z-index','2').css('opacity',1);
						break;

					default:
						this.page_contain.stop();
						this.page_contain.animate({left:-(this.current * this.carousel_width) +"px"}, this.speed, function(){ o.callback_prev(); });

				}
				
				if(this.continuous) {
					for(var i=0; i<this.jumpped_by; i++ ) {
						var farthestLeft = parseInt(this.target.find('.'+this.carousel_page_class+':first').css('left').replace('px','')) - this.carousel_width;
						this.target.find('.'+this.carousel_page_class+':eq('+(this.target.find('.'+this.carousel_page_class).length - 1 - this.doubleClicksp - i - this.doubleClicks)+')').clone().prependTo(this.page_contain);
						this.target.find('.'+this.carousel_page_class+':first').css('left',farthestLeft);
					}
					this.doubleClicksp += this.jumpped_by - 1;
				}
				this.update_indicator();
				this.doubleClicksp++;
			}
		
		},
		
		jump_to: function(index) {
		
			this.stop_auto_slide();
			
			if(index < this.actual_page()) {
			
				var jumped_from = this.current;
				this.current = this.current - (this.actual_page() - index) + 1;
				this.go_prev(jumped_from);
				
			}else {
				
				var jumped_from = this.current;
				this.current = this.current + (index - this.actual_page()) - 1;
				this.go_next(jumped_from);
				
			}
			
		},
		
		callback_next: function() {
			this.clear_continuous();
			
			try { this.next_callback_done(this); }catch(e) {}
		},
		
		callback_prev: function() {
			this.clear_continuous();
			
			try { this.previous_callback_done(this); }catch(e) {}
		},
		
		clear_continuous: function() {
			if(this.continuous) {
				for(var i=0; i<this.doubleClicks; i++) {
					this.target.find('.'+this.carousel_page_class+':first').remove();
				}
				this.doubleClicks = 0;
				for(var i=0; i<this.doubleClicksp; i++) {
					this.target.find('.'+this.carousel_page_class+':last').remove();
				}
				this.doubleClicksp = 0;
			}
		},
		
		stop_auto_slide: function() {
			clearInterval(this.timer);
		},
		
		make_continuous: function() {
		
			var o = this;
		
			this.pages.each(function(i, val) {
				jQuery(this).css({'position':'absolute', 'left': (o.carousel_width * i) + 'px'})
			});
			this.target.find('.'+this.carousel_page_class+':last').prependTo(this.page_contain).css('left',-this.carousel_width + 'px');
		
		},
		
		make_indicator: function() {
		
			var o = this;
		
			this.target.append('<div class="carousel_indicator"></div>');
			var indicator = this.indicator = this.target.find('.carousel_indicator');
			
			this.pages.each(function(i, val){
				var content = o.indicator_numbered ? i + 1 : '&middot;';
				indicator.append('<div class="carousel_inicator_page carousel_inicator_page_'+i+'"><a href="#page_'+i+'">'+content+'</a></div>');
				indicator.find('.carousel_inicator_page:last').click(function(){ o.jump_to(i); return false; })
			})
			
			this.indicator.find('.carousel_inicator_page:first').addClass('current')
		},
		
		update_indicator: function() {
			
			this.target.find('.carousel_indicator .carousel_inicator_page').removeClass('current');
			this.target.find('.carousel_indicator .carousel_inicator_page:eq('+this.actual_page()+')').addClass('current');
			
		},
		
		actual_page: function(last) {
		
			var actual_page = last ? last : this.current;
			
			while((actual_page < 0) || (actual_page > (this.page_count-1))){
				actual_page = (actual_page < 0) ? actual_page + this.page_count : actual_page - this.page_count;
			}
			
			return actual_page;
		
		}
		
	}
	
})(jQuery);
