// scrollbox.js

function max(num1, num2) { if (num1 > num2) {return num1;} else {return num2;} }
function min(num1, num2) { if (num1 < num2) {return num1;} else {return num2;} }
function abs(num) { if (num > 0) {return num;} else {return -num;} }

jQuery.fn.scrollbox = function(args){
	/* THESE PARAMETERS MUST BE SET */ 
	
	this.vertical;
	this.elemId;
	this.elemIdSub;
	this.itemSelector;
	this.nextSelector;
	this.prevSelector;
	this.numShown;
	this.fadeClass;
	this.size=1;
	
	/* THESE PARAMETERS ARE OPTIONAL */
	
	this.maxWidth = 10000000000000;
	this.minWidth = 0;
	this.maxHeight = 10000000000000;
	this.minHeight = 0;
	
	this.args = args;
	if (typeof(args) == typeof({})){ 
		for (var j in args){
			//alert(j+" => "+args[j]);
			this[j] = args[j];
		}
	}

	this.idCur = 0; 
	this.items = [];
	this.shown = [];
	this.items.length = this.size;
	this.shown.length = this.size;
	this.next = null; 
	this.prev = null;
	this.nextEnabled = true;
	this.prevEnabled = false;
	this.curOffset = 0;
	this.scrolling = false;
	
	this.enableNext = function(){
		// switch css class?
		//alert("enableNext / " + this.nextSelector + " / " + this.fadeClass);
		this.nextEnabled = true;
		var selfref = this;
		jQuery(selfref.nextSelector).removeClass(selfref.fadeClass);
	};
	this.disableNext = function(){
		//alert("disableNext");
		this.nextEnabled = false;
		var selfref = this;
		jQuery(selfref.nextSelector).addClass(selfref.fadeClass);
	};
	
	this.enablePrev = function(){
		
		this.prevEnabled = true;
		var selfref = this;
		jQuery(selfref.prevSelector).removeClass(selfref.fadeClass);
	};
	this.disablePrev = function(){
		
		this.prevEnabled = false;
		var selfref = this;
		jQuery(selfref.prevSelector).addClass(selfref.fadeClass);
	};
	
	this.alertArray = function(msg){ return;
		s = "[";
		for (var i in this.items){
			if (this.items[i] != null){
				s += this.items[i].find('.whitebox').html()+" ("+this.shown[i]+"), ";
			} else{
				s += this.items[i]+", ";
			}
		}
		s += "]";
		alert(msg+" "+s);
	};
	
	this.getItemByPos = function(pos){
		if (pos < 0 || pos >= this.items.length) { return null; }
		else if (this.items[pos] == null){
			return jQuery('<div id="'+this.itemPrefix+pos+'" class="sideitem greenbox" style="display:none;"><div class="whitebox">'+pos+'</div></div>').css('margin-top', 0);
		} else {
			return this.items[pos];
		}
	};
	
	this.preloadPrev = function (){
		if (this.idCur > 0){
			var pos = this.idCur - 1;
			this.items[pos] = this.getItemByPos(pos);
			
			if (this.prevEnabled == false){
				this.enablePrev();
			}
		} else {
			if (this.prevEnabled == true){
				this.disablePrev();
			}
		}
	};
	
	this.preloadNext = function(){
		if (this.idCur + this.numShown < this.items.length){
			var pos = this.idCur + this.numShown;
			this.items[pos] = this.getItemByPos(pos);
			
			if (this.nextEnabled == false){
				this.enableNext();
			}
		} else {
			if (this.nextEnabled == true){
				this.disableNext();
			}
		}
	};
	
	this.getNext = function(){
		if (this.idCur + this.numShown < this.items.length){
			var pos = this.idCur + this.numShown;
			return this.items[pos];
		} else {
			return null;
		}
	};
	
	this.getPrev = function(){
		if (this.idCur > 0){
			var pos = this.idCur - 1;
			return this.items[pos];
		} else {
			return null;
		}
	};
	
	this.fixSize = function(){ 
		var selfref = this;
		if (this.vertical){
			jQuery(function(){
				var i = selfref.idCur;
				var oldHeight = parseInt(selfref.items[i].height())+parseInt(selfref.items[i].css('margin-bottom'));
				var totHeight = oldHeight;
				var numOk = 1;
				i++;
				while (i < selfref.idCur + selfref.numShown){
					totHeight += parseInt(selfref.items[i].height())+parseInt(selfref.items[i].css('margin-bottom'));
					//alert('yo: '+totHeight);
					if (totHeight > selfref.maxHeight){
						//alert('go: '+min(oldHeight, selfref.maxHeight));
						jQuery(selfref.elemId).animate( {height:min(oldHeight, selfref.maxHeight)}, "fast");
						return numOk;
					}
					oldHeight = totHeight
					numOk++;
					i++;
				}
				var newHeight = max(selfref.minHeight, min(totHeight, selfref.maxHeight));
				//alert('go2: '+newHeight);
				jQuery(selfref.elemId).animate( {height:newHeight}, "fast" );
				return numOk;
			});
		} else {
			jQuery(function(){
				var i = selfref.idCur;
				var oldWidth = parseInt(selfref.items[i].width())+parseInt(selfref.items[i].css('margin-right'));
				var totWidth = oldWidth;
				var numOk = 1;
				i++;
				while (i < selfref.idCur + selfref.numShown){
					totWidth += parseInt(selfref.items[i].width())+parseInt(selfref.items[i].css('margin-right'));
					if (totWidth > selfref.maxWidth){
						jQuery(selfref.elemId).animate( {width:min(oldWidth, selfref.maxWidth)}, "fast" );
						return numOk;
					}
					oldWidth = totWidth
					numOk++;
					i++;
				}
				var newWidth = max(selfref.minWidth, min(totWidth, selfref.maxWidth));
				jQuery(selfref.elemId).animate( {width:newWidth}, "fast" );
				return numOk;
			});
		}
	};
	
	this.scrollPrev = function(){
		if (this.scrolling) {return;}
		if (this.idCur > 0){
			this.scrolling = true;
			this.alertArray("Before scrollPrev");
			var selfref = this;
			//var api = jQuery(selfref.elemId).scrollable();
			var prev = this.getPrev();
			this.idCur--; var pos = this.idCur;
			if (this.shown[pos] == false){
				this.shown[pos] = true;
				api.getItemWrap().prepend(prev);
			}
			this.fixSize();
			prev.fadeIn();
			//prev.css('opacity',0);
			//prev.css('display','inline');
			prev.animate({opacity: 1.0},"slow");
			if (this.idCur+this.numShown < this.items.length){
				this.items[this.idCur+this.numShown].animate({opacity: 0},"slow");
			}
			/*api.reload().prev();*/
			if (this.vertical){
				var targetOffset = this.items[this.idCur].offset().top - jQuery(selfref.elemId).offset().top;
				jQuery(selfref.elemId).animate({scrollTop: "+=" + targetOffset + "px"}, "fast", "swing", function(){
					selfref.scrolling = false;																				
				});				
			} else {
				var targetOffset = this.items[this.idCur].offset().left - jQuery(selfref.elemId).offset().left;
				jQuery(selfref.elemId).animate({scrollLeft: "+=" + targetOffset + "px"}, "fast", "swing", function(){
					selfref.scrolling = false;																				
				});	
			}
			this.preloadPrev();
			this.preloadNext();
			this.alertArray("After scrollPrev");
		}
	};
	
	this.scrollNext = function(){
		if (this.scrolling) {return;}
		if (this.idCur + this.numShown < this.items.length){
			this.scrolling = true;
			this.alertArray("Before scrollNext");
			var selfref = this;
			//var api = jQuery(selfref.elemId).scrollable();
			var next = this.getNext();
			this.idCur++; var pos = this.idCur + this.numShown - 1;
			if (this.shown[pos] == false){
				this.shown[pos] = true;
				api.getItemWrap().append(next);
			}
			this.fixSize();
			next.fadeIn();
			//next.css('opacity',0);
			//next.css('display','inline');
			next.animate({opacity: 1.0},"slow");
			if (this.idCur - 1 >= 0){
				this.items[this.idCur-1].animate({opacity: 0},"slow");
			}
			if (this.vertical){
				var targetOffset = this.items[this.idCur].offset().top - jQuery(selfref.elemId).offset().top;
				jQuery(selfref.elemId).animate({scrollTop: "+=" + targetOffset + "px"}, "fast", "swing", function(){
					selfref.scrolling = false;																				
				});					
			} else {
				var targetOffset = this.items[this.idCur].offset().left - jQuery(selfref.elemId).offset().left;
				jQuery(selfref.elemId).animate({scrollLeft: "+=" + targetOffset + "px"}, "fast", "swing", function(){
					selfref.scrolling = false;																				
				});	
			}
			this.preloadPrev();
			this.preloadNext();
			this.alertArray("After scrollNext");
		}
	};
	
	this.init = function(){
		var selfref = this;
				
		var i = 0;
		while (i < this.items.length){ this.items[i] = null; this.shown[i] = false; i++; }
		i = 0;
		jQuery(selfref.elemId+" "+selfref.itemSelector).each(function(){
			if (selfref.vertical) { jQuery(this).css('margin-top', 0); }
			else { jQuery(this).css('margin-left', 0); }
			selfref.items[i] = jQuery(this);
			selfref.shown[i] = true;
			i++;
		});
		jQuery(function(){
			/*jQuery(selfref.elemId).scrollable({
				size: selfref.numShown,
				items: selfref.elemIdSub,
				vertical: selfref.vertical
			});*/
			if (selfref.args){
				if (!selfref.args.maxHeight){
					
					selfref.maxHeight = parseInt(jQuery(selfref.elemId).css('height'));	
					//alert('set height '+selfref.maxHeight);
				}
				if (!selfref.args.maxWidth){
					selfref.maxWidth = parseInt(jQuery(selfref.elemId).css('width'));
				}
			}
			
			selfref.preloadPrev();
			selfref.preloadNext();
			
			jQuery(selfref.nextSelector).click(function(){selfref.scrollNext();});
			jQuery(selfref.prevSelector).click(function(){selfref.scrollPrev();});
			
		});
		this.fixSize();
		if (this.vertical){
				var targetOffset = this.items[this.idCur].offset().top - jQuery(selfref.elemId).offset().top;
				jQuery(selfref.elemId).animate({scrollTop: "+=" + targetOffset + "px"});				
		} else {
				var targetOffset = this.items[this.idCur].offset().left - jQuery(selfref.elemId).offset().left;
				jQuery(selfref.elemId).animate({scrollLeft: "+=" + targetOffset + "px"});
		}
		
		this.disablePrev();
	};
	
	// tells jQuery to call this.init() on document ready.
	// this is a scope/namespace hack
	(function(selfref){ jQuery(document).ready(function(){ selfref.init(); }); })(this);
}
