var RangeSlider = new Class({

	options: {
		onChange: Class.empty,
		onComplete: Class.empty,
		onTick: function(pos){
			this.position = pos;
			this.knobLeft.setStyle(this.p, pos.from);
			this.knobRight.setStyle(this.p, pos.to);
		},
		mode: 'horizontal',
		minValue: 0,
		maxValue: 100,
		steps: 100,
		offset: 0
	},

	initialize: function(el, knobLeft, knobRight, options){
		this.element = $(el);
		this.knobLeft = $(knobLeft);
		this.knobRight = $(knobRight);
		this.setOptions(options);
		this.previousChange = {};
		this.previousEnd = {};
		this.step = {};
		//this.element.addEvent('mousedown', this.clickedElement.bindWithEvent(this));
		var mod, offset;
		switch(this.options.mode){
			case 'horizontal':
				this.z = 'x';
				this.p = 'left';
				mod = {'x': 'left', 'y': false};
				this.offset = 'offsetWidth';
				break;
			case 'vertical':
				this.z = 'y';
				this.p = 'top';
				mod = {'x': false, 'y': 'top'};
				this.offset = 'offsetHeight';
		}
		this.max = this.element[this.offset] - this.knobRight[this.offset] + (this.options.offset * 2);
		this.half = this.knobLeft[this.offset]/2;
		this.getPos = this.element['get' + this.p.capitalize()].bind(this.element);
		this.knobLeft.setStyles({'position':'relative','float':'left'}).setStyle(this.p, - this.options.offset);
		this.knobRight.setStyles({'position':'relative','float':'left'}).setStyle(this.p, - this.options.offset);
		this.knobRight.setStyle('margin-left', - this.knobLeft[this.offset]);
		var lim = {};
		var limRight = {};
		lim[this.z] = [- this.options.offset, this.max - this.options.offset];
		this.dragLeft = new Drag.Base(this.knobLeft, {
			limit: lim,
			modifiers: mod,
			snap: 0,
			onStart: function(){
				this.draggedKnob('left');
			}.bind(this),
			onDrag: function(){
				this.draggedKnob('left');
			}.bind(this),
			onComplete: function(){
				this.draggedKnob('left');
				this.end();
			}.bind(this)
		});
		this.dragRight = new Drag.Base(this.knobRight, {
			limit: lim,
			modifiers: mod,
			snap: 0,
			onStart: function(){
				this.draggedKnob('right');
			}.bind(this),
			onDrag: function(){
				this.draggedKnob('right');
			}.bind(this),
			onComplete: function(){
				this.draggedKnob('right');
				this.end();
			}.bind(this)
		});
		if (this.options.initialize) this.options.initialize.call(this);
	},

	set: function(step){
		this.step = { 'from': step.from.limit(this.options.minValue, this.options.maxValue), 'to': step.to.limit(this.options.minValue, this.options.maxValue) };
		this.checkStep(this.step);
		this.end();
		this.fireEvent('onTick', { 'from': this.toPosition(this.step.from), 'to': this.toPosition(this.step.to) });
		return this;
	},
	
	setFrom: function(from){
		this.set( {'from': from, 'to':this.step.to} );
	},
	setTo: function(to){
		this.set( {'from': this.step.from, 'to':to} );
	},
	
	setLimits: function(){
		var limitLeft = [- this.options.offset, this.position.to - this.knobRight[this.offset] ];
		var limitRight = [this.position.from + this.knobLeft[this.offset], this.element[this.offset] - this.knobRight[this.offset] ];
		if ($defined(this.dragLeft.limit))
			this.dragLeft.limit[this.z] = limitLeft;
		else
			this.dragLeft.options.limit[this.z] = limitLeft;
		if ($defined(this.dragRight.limit))
			this.dragRight.limit[this.z] = limitRight;
		else
			this.dragRight.options.limit[this.z] = limitRight;
	},

	/*clickedElement: function(event){
		var position = event.page[this.z] - this.getPos() - this.half;
		position = position.limit(-this.options.offset, this.max -this.options.offset);
		this.step = this.toStep(position);
		this.checkStep();
		this.end();
		this.fireEvent('onTick', position);
	},*/

	draggedKnob: function( knob ){
		this.setLimits();
		switch (knob)
		{
			case 'left':
				this.step.from = this.toStep(this.dragLeft.value.now[this.z]);
				this.position.from = this.dragLeft.value.now[this.z];
			break;
			case 'right':
				this.step.to = this.toStep(this.dragRight.value.now[this.z]);
				this.position.to = this.dragRight.value.now[this.z];
			break;
		}
		this.checkStep(this.step);
	},

	checkStep: function(step){
		if ( (this.previousChange.from != step.from) || (this.previousChange.to != step.to) ){
			this.previousChange.from = step.from;
			this.previousChange.to = step.to;
			this.fireEvent('onChange', step);
		}
	},

	end: function(){
		if ( (this.previousEnd.from != this.step.from) || (this.previousEnd.to != this.step.to) ){
			this.previousEnd = this.step;
			this.fireEvent('onComplete', this.step + '');
		}
	},

	toStep: function(position){
		var pixelValue = this.pixelValue();
		return Math.round( ( position / pixelValue ) / ((this.options.maxValue - this.options.minValue) / this.options.steps)) * Math.round((this.options.maxValue - this.options.minValue) / this.options.steps) +  this.options.minValue;
	},

	toPosition: function(step){
		var pixelValue = this.pixelValue();
		return (step - this.options.minValue) * pixelValue;
	},
	
	pixelValue: function( ) {
		return ( this.element[this.offset] - this.knobRight[this.offset] ) / ( this.options.maxValue - this.options.minValue );
	}

});

RangeSlider.implement(new Events);
RangeSlider.implement(new Options);


var Thumbchange = new Class ({
	
	options: {
		proto: '',
		total: 1
	},
	
	initialize: function(element, options) {
		this.element  	= element;
		this.origsrc  	= element.src;
		this.running  	= false;
		this.runnable 	= true;
		this.images   	= new Array();
		this.setOptions(options);
	},
	
	start: function () {
		this.element.addClass('highlight-on');
		if (this.runnable) {
			this.running = true;
			this.preload();
			this.animate(1);
		}
	},
	
	stop: function () {
		this.element.removeClass('highlight-on');
		if (this.runnable) {
			this.element.src = this.origsrc;
			this.running = false;
		}
	},
	
	preload: function () {
		for (var i=1; i<=this.options.total; i++) {
			this.images[i] = new Image();
		}
		
		this.load(1);
		for (var i=2; i<=this.options.total; i++) {
			setTimeout((function(obj, j) { 
				return function() { obj.load(j); }
			})(this, i), i*100);
		}
	},
	
	load: function (num) {
		if (this.running) {
			this.images[num].src = this.options.proto.replace('[num]', num);
		}
	},
	
	animate: function (num) {
		if (this.running) {
			if (this.images[num].complete) {
				this.element.src = this.images[num].src;
				
				var next = (num == this.options.total) ? 1 : num + 1;
				setTimeout((function(obj, i) { 
					return function() { obj.animate(i); }
				})(this, next), 1025);			
			} else {
				setTimeout((function(obj, i) { 
					return function() { obj.animate(i); }
				})(this, num), 25);
			}
		}
	}
});

Thumbchange.implement(new Events);
Thumbchange.implement(new Options);