var Slider = Class.create({
	initialize: function(options) { 
		this.opts = { //default options
			'range': 435, // length of slider in px
			'mappedRange': 538,
			'tickSize': 0, // no ticks
			'minThumbDistance': 3, // distance the thumbs can be from one another
			'initValues': [235,434], // initial values for the thumbs
			'conversionFunction': function (val) {return Math.round(val);},
			'namespace': 'house',
			'segments': ['dem', 'rep', 'ind'],
			'hasGraph': true,
			'late-binding': false //this param calls this.createSlider immediately 
								  //rather than attaching it to a load event
		}
		$H(options).each(function(pair) { //override defaults
			this.opts[pair.key] = pair.value;
		}, this); 
		
		if (this.opts['late-binding'] === true) {
			this.createSlider();
			return;
		}
		
		if (!Object.isUndefined(document.observe)) {
			document.observe("dom:loaded", this.createSlider.bind(this));
		}
		else { 
			Event.observe(window, 'load', this.createSlider.bind(this));
		}

	},
	createSlider: function() {
		var segments = $A(this.opts.segments);
		var background = this.opts.namespace;
		this.DOMSegments = segments.map(function(seg){ return $(this.opts.namespace + "-" + seg);}, this);
		if (segments.length === 2) { //one thumb
			thumb = this.opts.namespace + "-thumb";
			this.slider = YAHOO.widget.Slider.getHorizSlider(background, 
				thumb, 
				0, 
				this.opts.range, 
				this.opts.tickSize);
				this.slider.setValue(this.opts.initValues[0])
		}
		else if (segments.length === 3) {
			minThumb = this.opts.namespace + "-min-thumb";
			maxThumb = this.opts.namespace + "-max-thumb";
			this.slider = YAHOO.widget.Slider.getHorizDualSlider(background, 
				minThumb, 
				maxThumb, 
				this.opts.range, 
				this.opts.tickSize,
				this.opts.initValues);		
		}
		this.slider.minRange = this.opts.minThumbDistance;
		this.slider.subscribe('ready', this.updateUI.bind(this));
		this.slider.subscribe('change', this.updateUI.bind(this));
		this.slider.subscribe('change', this.updateUI.bind(this));
		//$(this.opts.namespace + "-update").observe('click', this.updateSlider.bindAsEventListener(this));
		//this.DOMSegments.invoke('observe', 'blur', this.inputUpdated.bindAsEventListener(this));		
	},
	updateUI: function() {
		if (this.opts.segments.length === 3) {
			s1 = this.slider.minVal;
			s2 = this.slider.maxVal - this.slider.minVal;
			s3 = this.opts.range - this.slider.maxVal;
			segmentValues = $A([s1, s2, s3])
		}
		else {
			s1 = this.slider.getValue();
			s2 = this.opts.range - s1;
			segmentValues = $A([s1, s2])
		}
		mappedSegmentValues = segmentValues.map(this.opts.conversionFunction);
		var i = segmentValues.length -1;
		while(i >= 0) {
			this.DOMSegments[i].value = mappedSegmentValues[i];
			
			if (this.opts.hasGraph) {
				//handle offsets
				segmentValues[i] = (i === 0) ? segmentValues[i] + 5 : segmentValues[i]; //offset first segment by +5
				segmentValues[i] = (i === segmentValues.length -1) ? segmentValues[i] - 5 : segmentValues[i]; //offset last segment by -5
				$(this.opts.namespace + "-" + this.opts.segments[i] + "-chart").setStyle({
					'width': segmentValues[i] + "px"
				});
			}
			--i;		
		}
	},

	setSliders: function(minValue, maxValue){
		minValue = Math.min(minValue, maxValue);
		maxValue = Math.max(minValue, maxValue);
		
		minValue= this.opts.conversionFunction(minValue, true);
		maxValue= this.opts.conversionFunction(maxValue, true);
		this.slider.setValues(minValue,maxValue);
		
		
	}
	
	
	/*updateSlider: function(event) {
		event.stop();
		if (this.opts.segments.length === 3) {
			min = Math.abs(parseInt($F(this.DOMSegments[0]),10)|0),
			max = Math.abs(parseInt($F(this.DOMSegments[0]),10)|0);
			min = this.opts.conversionFunction(min, true);
			max = this.opts.conversionFunction(max, true)
			if (min > max) {
				var hold = min;
				min = max;
				max = hold;
			}
			min = Math.min(min,this.opts.range - 30);
			max = Math.max(Math.min(max, this.opts.range), min + 20 + this.opts.minThumbDistance);
			max = Math.max(Math.min(max, this.opts.range), min + this.opts.minThumbDistance);
			this.slider.setValues(min,max);
		}
		else {
			var pos = Math.abs(parseInt($F(this.DOMSegments[0]),10)|0);
			pos = this.opts.conversionFunction(pos, true);
			pos = Math.min(pos, this.opts.range);
			this.slider.setValue(pos);
			
		}
	}*/		
});

createMapper = function(range1, range2, keepDecimals) {
	//returns a 2-way mapping function that will map a value from one range to another
	// >>> mapper = createMapper([0,10], [0,100])
	// >>> mapper(5)
	// 50
	// >>> mapper(50, true)
	// 5
	var map = function(range1, range2, value) {
		if (arguments.length === 4 && arguments[3] === true) {
			var interim = range1;
			range1 = range2;
			range2 = interim;
			delete interim;
		}
		return (range2[0] + (range2[1] - range2[0]) * ((value - range1[0]) / (range1[1] - range1[0])));
	}
	map =  map.curry(range1, range2);
	if (keepDecimals !== true) {
		map = map.wrap(function(fn, arg, inv){
			val = fn(arg, inv);
			return Math.round(val);
		});
	}
	return map;	 
}