

function UIScrollView(opts){
	this.$type = "UIScrollView";
	
	this.contentId = opts.contentId || "";
	this.btnUp = opts.btnUp || "";
	this.btnDown = opts.btnDown || "";
	this.btnLeft = opts.btnLeft || "";
	this.btnRight = opts.btnRight || "";
	this.speed = opts.speed || 10;
	this.step = opts.step || 100;
	
	
	this.isInfiniteLoop = opts.isInfiniteLoop || false;
	this.isInfiniteScroll = opts.isInfiniteScroll || false;
	this.autoHideControls = (opts.isInfiniteLoop === true) ? false : opts.autoHideControls || true;
	this.direction = (opts.isInfiniteLoop === true && (opts.direction == "vertical" || opts.direction == "horizontal")) ? opts.direction : opts.direction || "vertical";
	
	this.isScrolling = false;
	this.mouseDownTimer = null;
	this.mouseDownTimerIsRunning = false;
	this.autoScrollTimer = null;
	this.autoScrollTimerIsRunning = false;
	
	if(this.direction == "vertical"){
		this.initButtons("Up");
		this.initButtons("Down");
	} else if(this.direction == "horizontal"){
		this.initButtons("Left");
		this.initButtons("Right");
	} else if(this.direction == "both"){
		this.initButtons("Up");
		this.initButtons("Down");
		this.initButtons("Left");
		this.initButtons("Right");
	}
	
	
	if(this.isInfiniteLoop === true){
		this.itemsPerPage = opts.itemsPerPage || 1;
		this.interval = opts.interval || 1000;
		var _this = this;
		this.infiniteScrolling();
	}
	if(this.isInfiniteScroll === true){
		this.itemsPerPage = opts.itemsPerPage || 1;
	}
	
	this.reset();
	
}
UIScrollView.implement({
	initButtons : function(direction){
		var _this = this;
		if(this.isInfiniteLoop === true){
 			jQuery(this["btn"+direction]).click(function(){
				clearInterval(_this.infiniteTimer);
				_this.scrollTo({
					goingTo:_this.step,
					animated:true,
					callback:function(){
						_this.infiniteScrolling();
						var first = jQuery(_this.contentId).children(':lt('+_this.itemsPerPage+')').clone();
						jQuery(_this.contentId).append(first);
						jQuery(_this.contentId).children(':lt('+_this.itemsPerPage+')').remove();
						jQuery(_this.contentId).append(first);
						jQuery(_this.contentId).css('left','0');
					}
				});
			});
		} else if(this.isInfiniteScroll === true){
			jQuery(this["btn"+direction]).click(function(){
				console.info('clicked');
				_this.scrollTo({
					goingTo:_this.step,
					animated:true,
					callback:function(){
						var first = jQuery(_this.contentId).children(':lt('+_this.itemsPerPage+')').clone();
						jQuery(_this.contentId).append(first);
						jQuery(_this.contentId).children(':lt('+_this.itemsPerPage+')').remove();
						jQuery(_this.contentId).append(first);
						jQuery(_this.contentId).css('left','0');
					}
				});
			});
		} else {
			jQuery(this["btn"+direction]).mousedown(function(){
				_this.mouseDownTimer = setInterval(function(){
					if(_this.mouseDownTimer !== null){
						clearInterval(_this.mouseDownTimer);
						_this.mouseDownTimer = null;
						_this["autoScroll"+direction]();
					}
				},200);
			});
			jQuery(this["btn"+direction]).mouseup(function(){
				clearInterval(_this.mouseDownTimer);
				_this.mouseDownTimer = null;
				if(_this.autoScrollTimer === null){
					_this["scroll"+direction]();
				} else {
					clearInterval(_this.autoScrollTimer);
					_this.autoScrollTimer = null;
				}
			});
		}
	},
	infiniteScrolling:function(){
		var _this = this;
		this.infiniteTimer = setInterval(function(){
			_this.scrollTo({
				goingTo:_this.step,
				animated:true,
				callback:function(){
					var first = jQuery(_this.contentId).children(':lt('+_this.itemsPerPage+')').clone();
					jQuery(_this.contentId).append(first);
					jQuery(_this.contentId).children(':lt('+_this.itemsPerPage+')').remove();
					jQuery(_this.contentId).append(first);
					jQuery(_this.contentId).css('left','0');
				}
			});
		},this.interval);
		
	},
	reset:function(){
		jQuery(this.contentId).css('top','0');
		jQuery(this.contentId).css('left','0');
		if(this.autoHideControls === true){
			var enabled = this.scrollShouldBeEnabled();
			if(enabled === true){
				this.showControls(this.direction);
			} else if(enabled === false){
				this.hideControls(this.direction);
			} else {
				if(enabled.vertical === false){ this.hideControls('vertical'); }
				if(enabled.horizontal === false){ this.hideControls('horizontal'); }
			}
			
		}
	},
	scrollShouldBeEnabled : function(){
		var cont_s, s;
		switch(this.direction){
			case "vertical":
				cont_s = jQuery(this.contendId).parent().innerHeight();
				s = this.getHeight();
				if(s > cont_s){ return true; }
			break;
			case "horizontal":
				cont_s = jQuery(this.contendId).parent().innerWidth();
				s = this.getWidth();
				if(s > cont_s){ return true; }
			break;
			case "both":
				var enabled = {};
				cont_h = jQuery(this.contendId).parent().innerHeight();
				h = this.getHeight();
				enabled.vertical = (h > cont_h);
				
				cont_w = jQuery(this.contendId).parent().innerWidth();
				w = this.getWidth();
				enabled.horizontal = (w > cont_w);
				return enabled;
			break;
		}
		return false;
	},
	getScrollTop : function(){
		var t = jQuery(this.contentId).css('top');
		return parseInt(t,10);
	},
	getScrollLeft : function(){
		var t = jQuery(this.contentId).css('left');
		return parseInt(t,10);
	},
	getHeight : function(){
		return jQuery(this.contentId).outerHeight();
	},
	getWidth : function(){
		return jQuery(this.contentId).outerWidth();
	},
	/*
	 * Method scrollTo
	 *
	 * @param {Object} opts
	 * ********************
	 * 		{Integer} opts.goingTo   - where you want to scroll in pixels
	 *		{String}  opts.direction - up | down | left | right
	 *								   default : 'down' for vertical and 'right' for horizontal
	 *		{Boolean} opts.animated  - is the scrolling animated or not
	 *								   default : true
	 *		{Boolean} opts.absolute  - if you want to set an absolute position 
	 *								   for the scroller (doesn't take account of the current position)
	 *								   default:false
	 * 
	 * @Desc scrolls where you want to!
	 *
	*/
	scrollTo : function(opts){
		if(this.isScrolling === false){
			var _this = this;
			if(opts.direction == undefined){
				if(this.direction == "horizontal"){
					opts.direction = "right";
				} else {
					opts.direction = "down";
				}
			}
			
			callback = opts.callback || function(){};
			var cal;
			var pos = (opts.direction == "up" || opts.direction == "down") ? this.getScrollTop() : this.getScrollLeft();
			// if absolute is set, we don't take account of the current position
			pos = (opts.absolute === true) ? 0 : pos;
			if(opts.direction == "up" || opts.direction == "left"){
				cal = (pos + opts.goingTo > 0) ? 0 : pos + opts.goingTo;
			} else if(opts.direction == "down" || opts.direction == "right"){
				var size = (opts.direction == "down") ? this.getHeight() : this.getWidth();
				var cont_size = (opts.direction == "down") ? jQuery(this.contentId).parent().innerHeight() : jQuery(this.contentId).parent().innerWidth();
				cal = ((pos - opts.goingTo) < -(size - cont_size)) ? -(size - cont_size) : (pos - opts.goingTo);
			}
			var to = (opts.direction == "up" || opts.direction == "down") ? {"top":cal+"px"} : {"left":cal+"px"};
			if(opts.animated !== false){
				this.isScrolling = true;
				jQuery(this.contentId).animate(to,function(){
					_this.isScrolling = false;
					callback.call(this);
				});
			} else {
				jQuery(this.contentId).css(to);
				callback.call(this);
			}
		}
	},
	scrollUp : function(){
		this.scrollTo({goingTo:this.step,direction:"up"});				
	},
	scrollDown : function(){
		this.scrollTo({goingTo:this.step,direction:"down"});
	},
	scrollLeft : function(){
		this.scrollTo({goingTo:this.step,direction:"left"});
	},
	scrollRight : function(){
		this.scrollTo({goingTo:this.step,direction:"right"});
	},
	autoScrollUp : function(){
		var _this = this;
		this.autoScrollTimerIsRunning = true;
		this.autoScrollTimer = setInterval(function(){
			_this.scrollTo({goingTo:_this.speed,direction:"up",animated:false});
		},100);
	},
	autoScrollDown : function(){
		var _this = this;
		this.autoScrollTimerIsRunning = true;
		this.autoScrollTimer = setInterval(function(){
			_this.scrollTo({goingTo:_this.speed,direction:"down",animated:false});
		},100);
	},
	autoScrollLeft : function(){
		var _this = this;
		this.autoScrollTimerIsRunning = true;
		this.autoScrollTimer = setInterval(function(){
			_this.scrollTo({goingTo:_this.speed,direction:"left",animated:false});
		},100);
	},
	autoScrollRight : function(){
		var _this = this;
		this.autoScrollTimerIsRunning = true;
		this.autoScrollTimer = setInterval(function(){
			_this.scrollTo({goingTo:_this.speed,direction:"right",animated:false});
		},100);
	},
	hideControls : function(controls){
		var btns = (controls == "vertical") ? this.btnUp + "," + this.btnDown : this.btnLeft + "," + this.btnRight; 
		jQuery(btns).css('display','none');
	},
	showControls : function(controls){
		var btns = (controls == "vertical") ? this.btnUp + "," + this.btnDown : this.btnLeft + "," + this.btnRight; 
		jQuery(btns).css('display','block');
	}
});