if (!$type(artpq)) var artpq = {};
if (!$type(artpq.Slider))
{
	artpq.Slider = new Class({
		Implements: [Events, Options],

		options: {
			interval: 1000,
			step: 1,
			limit: 1,
			fx: {duration: 1000, transition: Fx.Transitions.Sine.easeInOut, fps:80},
			slideClass: '',
			tableClass: ''
		},

		initialize: function(container, options) {
			this.setOptions(options);
			this.container = $(container);
			this.init();
			this.table = this.makeTable();
			this.table.inject(this.container);
			this.elements = [];
			this.current = 0;
			this.scroller = new Fx.Scroll(this.container, this.options.fx);
			this.scroller.set(0,0);
			this.timer = false;
			this.playing = false;
			return this;
		},
		init: function() {
			this.options.interval = this.options.interval + this.options.fx.duration;
			this.container.setStyle('overflow', 'hidden');
			if (!['relative', 'absolute'].contains(this.container.getStyle('position'))) this.container.setStyle('position', 'relative');

			this.container.addEvents({
				'mouseenter': this.pause.bindWithEvent(this),
				'mouseleave': this.resume.bindWithEvent(this)
			});

			this.fireEvent('onInit');
		},

		makeTable: function() {
			return new Element('table', {
				'border': 0, 'cellspacing': 0, 'cellpadding': 0,
				'class': this.options.tableClass,
				'styles': {
					'border-collapse': 'collapse',
					'table-layout': 'auto'
				}
			});
		},

		addByHTML: function(html) {
			this.addElement(new Element('div').addClass(this.options.slideClass).set('html', html));
			return this;
		},
		addByContainer: function(els) {
			var elements;
			if ($type(els) == 'element') elements = [els];
			else if ($type(element) == 'array') elements = element;
			else alert('require element or array in artpq.Slider.addByContainer');
			for (var i = 0, n = elements.length; i < n; i++) {
				this.addByHTML(elements[i].get('html'));
				elements[i].dispose();
			}
			return this;
		},
		addElement: function(element) {
			var elements;
			if ($type(element) == 'element') elements = [element];
			else if ($type(element) == 'array') elements = element;
			else alert('require element or array in artpq.Slider.addElement');
			for (var i = 0, n = elements.length; i < n; i++) this._addElement(elements[i]);
			return this;
		},
		addByElement: function(el) {
			el.inject(this.table);
		},
		_addElement: function(el) {
			if (this.table.rows.length == 0) this.table.insertRow(0);
			var row = this.table.rows[0];
			var newCell = row.insertCell(row.cells.length);
			newCell.appendChild(el);
			this.elements[this.elements.length] = el;
		},
		shift: function() {
			var initIndex = this.current - (this.options.limit * this.options.step);
			for (var i = 0; i < this.options.step; i++) this._addElement(this.elements[initIndex + i].clone());
		},

		play: function(){
			if (!this.timer) {
				this.go(1);
				this.timer = this.go.periodical(this.options.interval, this, 1);
			}
		},

		pause: function() {
			this.stop();
		},

		resume: function() {
			if (this.playing) this.play();
		},

		stop: function(){
			if (this.timer) {
				$clear(this.timer);
				this.timer = false;
			}
		},
		go: function(offset){
			offset *= this.options.step;
			var next = this.current + offset;
			if (next >= 0 && next < this.elements.length) {
				this.current = next;
				this.scroller.toElement(this.elements[this.current]);
				if (this.current >= (this.options.limit * this.options.step)) this.shift();
			}
		}
	});

	artpq.Slider.Up = new Class({
		Extends: artpq.Slider,
		_addElement: function(el){
			var row = this.table.insertRow(this.table.rows.length);
			var newCell = row.insertCell(0);
			newCell.appendChild(el);
			this.elements[this.elements.length] = el;
		}
	});

}
