/**
 * Scroller, manipulates horizontally scrollable content
 * 
 * @param {Object} container
 * @param {Object} content
 * @param {Array} elements
 */
function Scroller ()
{
	this.container = null;					/* Container element */
	this.content = null;					/* Content, which will be moved */
	this.elements = null;					/* Content elements of the 'this.content' */
	this.widths = [];						/* Widths of the elements*/
	this.pos = 0;							/* Current content horizontal posittion */
	this.actual_pos = 0;					/* Actual scroller position */
	this.max_pos = 0;						/* Max position of the content */
	this.constantAnimationSpeed = false;	/* Animation time doesn't change */
	this.speedMultiplier = 1;

	/**
	 * Rereads information about scroller container, content and elements
	 * This function must be called before using scrollTo, setPos, scrollToElement
	 * 
	 * @param {Object} container
	 * @param {Object} content
	 * @param {Array} elements
	 */
	this.refresh = function (container, content, elements)
	{
		this.container = $(container);
		this.content = $(content);
		this.elements = elements;
		this.widths = [];
		this.pos = 0;
		this.actual_pos = 0;
		
		var sum = 0;
		var el = null;
		
		this.content.css({marginLeft: '0px'});		

		for(var i = 0, j = this.elements.length; i < j; i++)
		{
			el = $(this.elements[i]);
			this.widths[i] = el.width() + parseInt(el.css('paddingLeft')) + parseInt(el.css('paddingRight'));
			
			sum += this.widths[i];
		}
		
		sum = sum - this.container.width();
		if (sum < 0) sum = 0;
		
		this.max_pos = sum;
	};
	
	/**
	 * Set scroller position
	 * Pos is offset position in px
	 * 
	 * @param {Integer} pos
	 */
	this.setPos = function (pos)
	{
		pos = this._sanitizePos(pos);
		
		if (pos == this.pos) return;
		if (pos > this.max_pos) pos = this.max_pos;
		
		this.pos = pos;
		this.actual_pos = this.pos;
		this.content.css({marginLeft: - pos + 'px'});
	};
	
	/**
	 * Returns scroller offset position in px
	 * 
	 * @return {Integer}
	 */
	this.getPos = function ()
	{
		return this.pos;
	};

	/**
	 * Scrolls scroller to given position with animation
	 * 
	 * @param {Object} pos
	 */
	this.scrollTo = function (pos)
	{
		var _self = this;
		
		pos = this._sanitizePos(pos);
		if (pos == this.pos) return false;
		
		if (this.constantAnimationSpeed)
		{
			var speed = parseInt(this.constantAnimationSpeed) || 500;
		}
		else
		{
			var dif = Math.abs(this.pos - pos);
			var speed = Math.floor(dif * 2.5) * this.speedMultiplier;
		}
		
		this.content.stop();
		
		this.actual_pos = this.pos;
		this.pos = pos;
		
		this.content.animate({marginLeft: - pos + 'px'}, {duration: speed, complete: function () {
			_self.actual_pos = _self.pos;
		}});
		
		return true;
	};
	
	/**
	 * Scroll scroller to given element
	 * Argument 'element' is an index of the element to which content will be scrolled
	 *  
	 * @param {Object} element
	 */
	this.scrollToElement = function (element)
	{
		if (element > this.widths.length) element = this.widths.length;
		if (element < 0) element = 0;
		
		var sum = 0;
		
		for(var i = 0; i < element; i++)
		{
			sum += this.widths[i];
		}
		this.scrollTo(sum);
	};
	
	/**
	 * Filters position
	 * @param {Integer} pos
	 */
	this._sanitizePos = function (pos)
	{
		pos = parseInt(pos);
		if (pos < 0) pos = 0;
		if (pos > this.max_pos) pos = this.max_pos;
	
		return pos;
	};
};