var ViewSlider = new Class({

	Implements: [Events, Options],

	options: {/*
		onChange: $empty(intStep),
		onComplete: $empty(strStep),
		onNext: $empty(strStep),
		onPrevious: $emptu(strStep)
		*/
		dir: -1,
		initialStep: 0,
		offset: 0,
		offsetStep: 0,
		range: false,
		steps: 10,
		mode: 'horizontal',
		fxOptions: {
			duration: 750
		}
	},

	initialize: function(element, options){
		this.setOptions(options);
		this.element = document.id(element);
		this.previousChange = this.previousEnd = this.step = -1;
		var offset, limit = {}//, modifiers = {'x': false, 'y': false};
		switch (this.options.mode){
			case 'vertical':
				this.axis = 'y';
				this.property = 'top';
				offset = 'offsetHeight';
				break;
			case 'horizontal':
				this.axis = 'x';
				this.property = 'left';
				offset = 'offsetWidth';
		}
		this.element.get('tween', $merge(this.options.fxOptions, {property: this.property}));
		this.element.getParent().setStyle('overflow', 'hidden')
		this.element.getChildren().setStyle('float', 'left');
		this.full = this.element.measure(function(){ 
			return this.element[offset] + (this.options.offset * 2); 
		}.bind(this));
		
		this.min = $chk(this.options.range[0]) ? this.options.range[0] : 0;
		this.max = $chk(this.options.range[1]) ? this.options.range[1] : this.options.steps;
		this.range = this.max - this.min;
		this.steps = this.options.steps || this.full;
		this.stepSize = Math.abs(this.range) / this.steps;
		this.stepWidth = this.stepSize * this.full / Math.abs(this.range);
		this.max += this.options.offsetStep;
		
		this.setStep(this.options.initialStep).move(this.step);
	},

	setStep: function(step){
		if (!((this.range > 0) ^ (step < this.min))) step = this.min;
		if (!((this.range > 0) ^ (step > this.max))) step = this.max;

		this.step = Math.round(step);
		this.checkStep();
		this.end();
		return this;
	},
	
	set: function(step){
		this.setStep(step);
		this.move(this.step, true);
	},
	
	move: function(step, set){
		var position = this.toPosition(step);
		var fx = this.element.get('tween');
		(!$chk(set)) ? fx.start(this.options.dir * position) : fx.set(this.options.dir * position);
	},
	
	next: function(){
		this.setStep(this.step + 1);
		this.move(this.step);
		this.fireEvent('next', this.step);
	},
	
	previous: function(){
		this.setStep(this.step - 1);
		this.move(this.step);
		this.fireEvent('previous', this.step);
	},

	checkStep: function(){
		if (this.previousChange != this.step){
			this.previousChange = this.step;
			this.fireEvent('change', this.step);
		}
	},

	end: function(){
		if (this.previousEnd !== this.step){
			this.previousEnd = this.step;
			this.fireEvent('complete', this.step + '');
		}
	},

	toPosition: function(step){
		return (this.full * Math.abs(this.min - step)) / (this.steps * this.stepSize) - this.options.offset;
	}

});