(function($){
	// Image preloader function
	var cache = [];
    $.preLoadImages = function() {
        var a = arguments, l = a.length;
        for (var i=l; i>=0; i--) {
          if(a[i] != '') cache.push( $('<img>').attr('src', a[i]) );
        }
    }
	// Math Limit function Min - Max
	Number.prototype.limit = function(B,A){
		return Math.min(A,Math.max(B,this));
	}
	// Filestrim Carousel Object
	$.jqSlideshow = {
		defaults:{
			element: null,
			items: 'li',
			speed: 30,
			width: null,
			height: null,
            itemWidth: 10,
            itemHeight: 10,
			dir: 'x',
			onScroll: function(ui){},
			onStart: function(ui){},
			onEnd: function(ui){}
		},
		scroll: {x:'scrollLeft', y:'scrollTop'},
		axis: {x:'left',  y:'top'},
		size: {x:'width', y:'height'},
		mouse: {x:0, y:0},
		carousel: null,
		timer: null,
		velocity: 1,
		
		setOptions: function(options){
			var opts = this.defaults;
			for(var x in options){
				if(typeof opts[x] === 'undefined') alert('Invalid option '+x);
				else opts[x] = (opts[x] != null && opts[x].constructor == Object)? this.setOptions(options[x], opts[x]) : options[x];
			}
			return opts;
		},
		initVars: function(obj){
			var self = this;
            var pos = obj.element.css('position');
			var o = obj.options;
			pos = (pos != 'relative' && pos != 'absolute')? 'relative' : pos;
			if(!o.width) o.width = obj.element.width();
			if(!o.height) o.height = obj.element.height();
			obj.content = $('<div class="galleryContent" />');
			obj.mainImage = $('<div class="galleryImage" ><img class="galleryImagePreview" /></div>').appendTo(obj.content);
			obj.thumbnails = $('<div class="galleryThumbs" />').appendTo(obj.content);
			obj.mainText = $('<div class="galleryText" />').appendTo(obj.content);	
			obj.wrapper = $('<div class="carouselWrap" />').css({width:o.width, height:o.height, position:pos, overflow:'hidden'}).appendTo(obj.thumbnails);
			obj.element.before(obj.content);
			obj.element.after(obj.next);
			obj.element.after(obj.prev);
			obj.element.appendTo( obj.wrapper ).css({position:pos});
			obj.items = $(o.items, obj.element).css({width:o.itemWidth, height:o.itemHeight});
			obj.area  = o[this.size[o.dir]]/3;
			o.dir = o.dir=='y'? 'y' : 'x';
            if(o.dir == 'x'){
                self.updateCarouselWidth(obj);
                if(o.itemWidth == 'auto'){
                    $('img', obj.items).bind('load', function(){
                        self.updateCarouselWidth(obj);
                        $(this).unbind('load');
                    });
                }
            }
			if($.isFunction(o.onStart)) o.onStart.apply(this,[obj]);
		},
		initEvents: function(obj){
			var self = this;
			$('.carouselWrap').bind('mousemove',function(e){
				var off = $(this).offset();
				self.mouse.x = e.pageX - off.left;
				self.mouse.y = e.pageY - off.top;
			}).bind('mouseleave',function(e){
				clearTimeout(self.timer);
				self.carousel = null;
			}).bind('mouseenter', function(e){
				clearTimeout(self.timer);
				self.carousel = obj;
				self.timer = setTimeout(function(){self.scrollSlideshow(self)}, 10);
		  });
		  $('.next, .prev', obj).bind('mousemove', function (e) {
		    var off = $(this).offset();
		    self.mouse.x = e.pageX - off.left;
		    self.mouse.y = e.pageY - off.top;
		  }).bind('mouseleave', function (e) {
		    clearTimeout(self.timer);
		    self.carousel = null;
		  }).bind('mouseenter', function (e) {
		    clearTimeout(self.timer);
		    self.carousel = obj;
		    self.timer = setTimeout(function () { self.scrollSlideshow(self) }, 10);
		  });
		},
		scrollSlideshow: function(self){
			var o = self.carousel.options;
			var bound = self.carousel.area*2;
			if(self.mouse[o.dir] < self.carousel.area){
				var val = ((bound / self.mouse[o.dir] ) * self.velocity) * -1;
			}else if(self.mouse[o.dir] > bound){
				var val = (bound / ((self.carousel.area*3) - self.mouse[o.dir])) * self.velocity;
			}
			if(val){
				var css = $('.carouselWrap')[self.scroll[o.dir]]();
				var pos = css + val.limit(-115,115);
				$('.carouselWrap')[self.scroll[o.dir]](pos);
			}
			clearTimeout(self.timer);
			self.timer = setTimeout(function(){self.scrollSlideshow(self)}, o.speed);
		},
        updateCarouselWidth: function(obj){
            var total = 0;
            obj.items.each(function(i,item){
                var w = $('img', item).width();
                if(w) $(item).width(w);
                total+= parseInt( $(item).outerWidth(true) );
            }).css({float:'left'});
            obj.element.css('width',total);
        }
		
	}
	// Filestrip Carousel Function
	$.fn.jqSlideshow = function(options){
		return this.each(function(i){
			var carousel = {
			  options: $.jqSlideshow.setOptions(options),
			  next: $('<div class="next" title="next">&raquo;</div>'),
			  prev: $('<div class="prev" title="prev">&laquo;</div>'),
				element: $(this),
				items: [],
				wrapper: null,
				area: 0
			}
			$.jqSlideshow.initVars(carousel);
			$.jqSlideshow.initEvents(carousel);
		});
	}
	
})(jQuery);
