function nonwrapInterval(min, x, max){
    if(x < min) x = min;
    else if(x > max) x = max;
    return x;
}

function Scrollable(element, width, height){

    var innerWrapper = $(element);
	var innerWidth = innerWrapper.innerWidth();
	var innerHeight = innerWrapper.innerHeight();
	
    var container = document.createElement("div");
    var containerWrapper = $(container);
    
    innerWrapper.replaceWith(container);
    container.appendChild(element);
    innerWrapper = $(element);
    
	if(!width) width = containerWrapper.width();
	if(!height) height = containerWrapper.height();
	
    containerWrapper
        .width(width)
        .height(height)
		.css("position", "relative")
        .css("overflow", "hidden")
        .addClass("scrollable");

    innerWrapper
        .css("position", "relative")
        .css("left", "0px")
        .css("top", "0px")
		.css("width", innerWidth + "px")
		.css("height", innerHeight + "px");
	
    var minTop = -(innerHeight - height);
    var minLeft = -(innerWidth - width);
	
    var left = 0;
    var top = 0;
    
    this.scrollBy = function(x, y){
		if(x != 0){
			left = nonwrapInterval(minLeft, left - x, 0);
			innerWrapper.css("left", left + "px");
		}
		if(y != 0){
			top = nonwrapInterval(minTop, top - y, 0);
			innerWrapper.css("top", top + "px");
		}
    }
	this.getScrollTopRemaining = function(){return top - minTop;}
	this.getScrollLeftRemaining = function(){return left - minLeft;}
	this.getScrollHeight = function(){return -minTop;}
	this.getScrollWidth = function(){return -minLeft;}
	this.setScrollPosition = function(x, y){
		left = nonwrapInterval(minLeft, x, 0);
		top = nonwrapInterval(minTop, y, 0);
		innerWrapper
			.css("left", x + "px")
			.css("top", y + "px");
	}
	this.scrollToBottom = function(){this.scrollBy(0, this.getScrollTopRemaining());}
	this.scrollToTop = function(){this.scrollBy(0, minTop);}
	this.sync = function(){
		left = element.clientLeft;
		top = element.clientTop;
	}
}

function Timer(delay, func){
	var started = false;
	var intervalId;
	this.start = function(){
		if(started) return;
		intervalId = window.setInterval(func, delay);
		started = true;
	}
	this.stop = function(){
		if(!started) return;
		window.clearInterval(intervalId);
		started = false;
	}
}

function scrollDownAnimation(scroller, jump, delay){
	var timer = new Timer(delay, function(){
		scroller.scrollBy(0, jump);
		if(!scroller.getScrollTopRemaining()) timer.stop();
	});
	timer.start();
	return function(){timer.stop();}
}

function makeUnselectable(element){
	if(typeof element.onselectstart != "undefined"){
		element.onselectstart = function(){return false;}
	}
	else if (typeof element.style.MozUserSelect!="undefined"){
		element.style.MozUserSelect = "none";
	}
	else{
		
	}
}
