function Slider(_element, _class, _leftBut, _rightBut, _numVisible) {
	var ths = this, i = 0, tmp = null;  // helpers

	this.el = SJEL.$(_element);
	this.leftBut = SJEL.$(_leftBut);
	this.rightBut = SJEL.$(_rightBut);
	this.itemsTmp = SJEL.$A(this.el, "class", _class);
	this.items = new Array();
	this.step = 0;  // allowed values are just -1 or 1
	this.numVisible = _numVisible || 0;
	this.animationRuns = false;
	this.animationSpeed = 450;

	if (!this.el || !this.leftBut || !this.rightBut || !this.numVisible || (this.itemsTmp.length <= 0)) {
		alert('Could not initialize slider');
		return;
	}
	
	if (this.itemsTmp.length <= this.numVisible) {
		SJEL.SStyle(this.leftBut, {visibility: "hidden"});
		SJEL.SStyle(this.rightBut, {visibility: "hidden"});
		return;
	}
	
	/* items init */
	this.elWidth = parseInt(this.el.offsetWidth);
	this.itemWidth = parseInt(this.itemsTmp[0].offsetWidth);
	SJEL.SStyle(this.el, {position: "relative"});
	
	for (i = 0; i < this.itemsTmp.length; i++) {
		this.items.push(new Item(this.itemsTmp[i], i));
		//SJEL.SStyle(this.itemsTmp[i], {position: "absolute", top: "0px", left: (i * this.itemWidth) + "px"});
	}
	/* end items init */
	
	/* morph init */
	this.onMorph = function(_t) {
		var step = ths.step, items = ths.items, stw = step * ths.itemWidth, mo = ths.mo;
		for (i = 0; i < items.length; i++)
			SJEL.SStyle(items[i].el, {left: Math.round(mo.Inte(items[i].left, stw + items[i].left, _t)) + "px"});
	};

	this.onMorphFinished = function() {
		var items = ths.items;
		for (i = 0; i < items.length; i++)
			items[i].setLeft();
		
		// items swap
		if (ths.step < 0) {  // left direction
			ths.el.appendChild(items[0].el);
			items[0].setLeft(ths.itemWidth * (items.length - 1));
			items.push(items.shift());
		}

		ths.animationRuns = false;
	};
	
	this.mo = new SJEL.Morph();
	this.mo.Init(this.onMorph, null, this.animationSpeed, 40);
	this.mo.OnMorphFinished(this.onMorphFinished);
	/* end morph init */
	
	this.go = function(_step) {
		this.step = _step;
		this.animationRuns = true;
		this.mo.Morph();
	};
	
	/* buttons event bindings */
	this.leftBut.onclick = function() {
		if (ths.animationRuns)
			return false;

		var items = ths.items;
		// items swap
		ths.el.insertBefore(items[items.length - 1].el, items[0].el);
		items[items.length - 1].setLeft(- ths.itemWidth * (items.length - ths.numVisible));
		items.unshift(items.pop());

		ths.go(1);
		return false;
	};

	this.rightBut.onclick = function() {
		if (ths.animationRuns)
			return false;

		ths.go(-1);
		return false;
	};
	/* end buttons event bindings */
	
	function Item(_element, _id) {
		this.el = _element;
		this.id = _id;
		this.left = -100000;
		SJEL.SStyle(this.el, {position: "absolute", top: "0px", left: (this.id * ths.itemWidth) + "px"});
		
		this.setLeft = function(_left) {
			if (_left != undefined) {
				this.left = _left;
				return;
			}
			
			if (this.left == -100000)
				this.left = parseInt(SJEL.GStyle(this.el, "left"));
			else
				this.left = (ths.step * ths.itemWidth) + this.left;
			
		};
		
		this.setLeft();
	};	
};