/*jslint evil: true, forin: true */
/*global document, setTimeout */

function ById(id) { return document.getElementById(id); }
function IsNegative(i) { return i < 0; } 
function Slider()
{
	var self = this;
	var slideable = null;
	var itemWidth = 0;
	var target = 0;
	var speed = 0;
	var acceleration = 10;
	var lastDifference = 0;
	this.getSlideable = function() { return slideable; };
	this.getItemWidth = function() { return itemWidth; };
	this.getPosition = function() { var x = parseInt(slideable.style.left, 10); return isNaN(x) ? 0 : x; };
	this.getMaxItemPosition = function() { return parseInt(slideable.offsetWidth / itemWidth, 10); };
	this.getItemPosition = function() {
		var pos = this.getPosition();
		var next = pos % itemWidth > itemWidth / 2;
		return -1 * (next ? parseInt(pos / itemWidth, 10) + 1 : parseInt(pos / itemWidth, 10));
	};
	this.getItemsPerPage = function() { return slideable.parentNode.clientWidth / itemWidth; };
	this.setSlideable = function(value) { slideable = value; slideable.style.left = '0px'; };
	this.setItemWidth = function(value) { itemWidth = value; };
	this.setPosition = function(value) { if (this.getPosition() != value * itemWidth) { this.SlideTo(value, true); } };
	
	var Slide = function() {
		var position = self.getPosition();
		var difference = target - position;
		if (difference !== 0)
		{
			if (IsNegative(difference) !== IsNegative(lastDifference)) {
				speed = 0;
			}
			speed += parseInt(acceleration * (difference / itemWidth), 10);
			if (speed === 0) {
				speed += 1;
			}
			else if (Math.abs(speed) > Math.abs(difference)) {
				speed = difference;
			}
			slideable.style.left = (position + speed) + 'px';
			lastDifference = difference;
			setTimeout(function() { Slide(); }, 100);
		}
	};
	
	this.SlideTo = function(where, immediately) {
		var to = (-1 * (itemWidth * where));
		if (immediately) {
			slideable.left = to + 'px';
		} else {
			target = to;
			Slide();
		}
	};
	
	this.SlideBack = function() { var pos = self.getItemPosition(); if (pos !== 0) { self.SlideTo(self.getItemPosition() - 1); } };
	this.SlideNext = function() { var pos = self.getItemPosition(); if (1 <= self.getMaxItemPosition() - self.getItemsPerPage() - pos) { self.SlideTo(self.getItemPosition() + 1); } };
}


var Ext = {
		'initSlider' :
			function(id, iw) {
				var sl = ById(id);
				return Ext.Create('Slider', { 'slideable' : sl, 'itemWidth' : iw });
			},
		'capitalize' :
			function(str) {
				return str.replace(/\w+/g, function(a){ return a.charAt(0).toUpperCase() + a.substr(1); });
			},
		'Create' :
			function(className, params) {
				var obj = new Slider();
				if (params) {
					for (var prop in params) {
						eval("obj.set" + Ext.capitalize(prop) + "(params[prop]);");
					}
				}
				return obj;
			}
};
