/*
Slider pour Moto85
Copyright(c) 2009, Skalpel.

Author : Michael
michael@skalpel.fr

Note : 
	-
ToDo :
	- 
*/

/* 
Class : SKjs.Slider
	Gestion des Sliders
	
Arguments : 
	container {String} - Id du conteneur
	scrollbar {String} -
	knob {String} - Curseur
	maxknob {String} - 2e curseur
	options {object} - Objet Options
	
Options :
	offset {Integer} - 
	steps {Integer} -
*/
SKjs.Slider = new Class ({
	Implements: [Events, Options],
	options: {
		offset: 0,
		snap: false,
		numsteps: null,
		isinit: true,
		
		// Events
		onChange: $empty,
		onComplete : $empty,
		onTick: function(pos) {
			this.moveKnob.setStyle('left', pos);	
		}
	},
	
	/*
	Property :
		Initialisation de la Class
	*/
	initialize: function(container, scrollbar, knob, maxknob, options) {
		this.setOptions(options);
		
		// DOM
        if ($chk($(container))) {
            this.container = $(container);
            this.scrollbar = ($(scrollbar)) ? $(scrollbar) : this.container.getElement(scrollbar);
            this.knob = ($(knob)) ? $(knob) : this.container.getElement(knob);
            if(maxknob != null) this.maxknob = ($(maxknob)) ? $(maxknob) : this.container.getElement(maxknob);

            // Constantes
            this.previousChange = this.previousEnd = this.step = -1;
            if(this.options.steps == null) this.options.steps = this.options.end - this.options.start;

            this.min = 0;
            this.max = this.scrollbar.getSize().x - this.knob.getSize().x + (this.options.offset * 2);
            this.range = this.max - this.min;
            this.steps = this.options.steps || this.max;
            this.stepSize = Math.abs(this.range) / this.steps;
            this.stepWidth = this.stepSize * this.max / Math.abs(this.range);

            if(maxknob != null) {
                this.maxPreviousChange = this.maxPreviousEnd = -1;
                this.maxStep = this.options.end;
            }

            var lim = {};
            lim.x = [-this.options.offset, this.max - this.options.offset];

            // Reset
            this.knob.setStyle('left', -this.options.offset);
            if(maxknob != null) this.maxknob.setStyle('left', + this.max - this.options.offset);


            // Launch
            this.drag = new Drag(this.knob, {
                limit: lim,
                modifiers: {'x': 'left', 'y': false},
                snap: 0,
                onStart: function() {
                    this.draggedKnob();
                }.bind(this),
                onDrag: function() {
                    this.draggedKnob();
                }.bind(this),
                onComplete: function() {
                    this.draggedKnob();
                    this.end();
                }.bind(this)
            });
            if(maxknob != null) {
                this.maxdrag = new Drag(this.maxknob, {
                    limit: lim,
                    modifiers: {'x': 'left', 'y': false},
                    snap: 0,
                    onStart: function(){
                        this.draggedKnob(1);
                    }.bind(this),
                    onDrag: function(){
                        this.draggedKnob(1);
                    }.bind(this),
                    onComplete: function(){
                        this.draggedKnob(1);
                        this.end();
                    }.bind(this)
                });
            }

            if(this.options.snap) {
                this.drag.options.grid = (this.max) / this.options.numsteps ;
                this.drag.options.limit.x[1] = this.max;
            }
        }
	},
	
	/*
	Property :
	*/
	draggedKnob: function(mx) {
		if(mx == null) {
			this.step = this.toStep(this.drag.value.now.x);
			this.checkStep();
		} else {
			this.maxStep = this.toStep(this.maxdrag.value.now.x); 
			this.checkStep(1);	
		}
	},
	
	/* 
	Property :
	*/
	checkStep: function(mx) {
		var lim = {}, limm = {}; 
		var min, max;
		
		if(mx == null) {
			if(this.previousChange != this.step) this.previousChange = this.step;
		} else {
			if(this.maxPreviousChange != this.maxStep) this.maxPreviousChange = this.maxStep;
		}
		
		if(this.maxknob != null) {
			min = - this.options.offset;
			max = parseInt(this.maxknob.getStyle('left')) - this.options.offset;
			lim.x = [min, max];
			this.drag.options.limit = lim;
			
			min = parseInt(this.knob.getStyle('left')) - this.options.offset;
			max = this.max - this.options.offset;
			limm.x = [min, max];
			this.maxdrag.options.limit = limm;
			
			if(this.step < this.maxStep) this.fireEvent('change', {minpos: this.step, maxpos: this.maxStep});
			else this.fireEvent('change', {minpos: this.maxStep, maxpos: this.step});
			
		} else {
			this.fireEvent('change', this.step);
		}
	},
	
	/*
	Property :
	*/
	toStep: function(pos) {
		return Math.round((pos + this.options.offset) / this.max * this.options.steps) + this.options.start;
	},
	/* 
	Property :
	*/
	toPosition: function(step) {
		return (this.max * step / this.options.steps) - (this.max * this.options.start / this.options.steps) - this.options.offset;
	},
	
	/*
	Property :
	*/
	end: function() {
		if(this.previousEnd !== this.step || (this.maxknob != null && this.maxPreviousEnd != this.maxStep)) {
			this.previousEnd = this.step;
			if(this.maxknob != null) {
				this.maxPreviousEnd = this.maxStep;
				if(this.step < this.maxStep) this.fireEvent('onComplete', { minpos: this.step + '', maxpos: this.maxStep + '' });
				else this.fireEvent('onComplete', { minpos: this.maxStep + '', maxpos: this.step + '' });
			} else {  
				this.fireEvent('onComplete', this.step + '');
			}
		}
	},
	
	/*
	Property :
	*/
	setMin: function(step) {
		this.step = step.limit(this.options.start, this.options.end);
		this.checkStep();
		this.end();
		this.moveKnob = this.knob;
		this.fireEvent('tick', this.toPosition(this.step));
		return this;
	},
	/*
	Property :
	*/
	setMax: function(step) {
		this.maxStep = step.limit(this.options.start, this.options.end);
		this.checkStep(1);
		this.end();
		this.moveKnob = this.maxknob;
		this.fireEvent('tick', this.toPosition(this.maxStep));
		if(this.options.isinit) {
			var lim = {}; var mi,mx;
			min = -this.options.offset; 
			max= parseInt(this.maxknob.getStyle('left')) - this.options.offset;
			lim.x = [min, max];
			this.drag.options.limit = lim;
			this.options.isinit = false;
		}
		return this;
	}
});
