/*
 * --------------------------------------------------------------------
 * jQuery-Plugin - accessibleUISlider - creates a UI slider component from a select element(s)
 * by Scott Jehl, scott@filamentgroup.com
 * http://www.filamentgroup.com
 * reference article: http://www.filamentgroup.com/lab/progressive_enhancement_convert_select_box_to_accessible_jquery_ui_slider
 * demo page: http://www.filamentgroup.com/examples/slider/demo.html
 * 
 * Copyright (c) 2008 Filament Group, Inc
 * Dual licensed under the MIT (filamentgroup.com/examples/mit-license.txt) and GPL (filamentgroup.com/examples/gpl-license.txt) licenses.
 *
 * Usage Notes: please refer to our article above for documentation
 *  
 * Version: 1.0, 08.12.08
 * Changelog: 
 * 	
 * --------------------------------------------------------------------
 */



jQuery.fn.accessibleUISlider = function(settings){
	var selects = jQuery(this);

	//id attrs - selects need ids for this feature to work - links handles to original select menus
	var elIds = (function(){
		var tempArr = [];
		selects.each(function(){
			tempArr.push(jQuery(this).attr('id'));
		});
		return tempArr;
	})();
	
	//array of all option elements in select element
	var options = (function(){
		var opts = [];
		selects.eq(0).find('option').each(function(i){
			opts.push({
				value: jQuery(this).attr('value'),
				text: jQuery(this).text(),
				className: jQuery(this).attr('class')
			});
		});
		return opts;
	})();
	
	//presets by selected indexes
	var presets = (function(){
		var indexes = [];
		selects.each(function(){
			var thisIndex = jQuery(this).find('option:selected').get(0).index;
			var thisPercentage = Math.round((thisIndex / (options.length-1)) *100);
			indexes.push(thisPercentage);
		});
		return indexes;
	})();
	
	//set up slider options API
	var sliderAPI = jQuery.extend({
		labels: 3,
		inject: true,
		rangeOpacity: 0.7,
		width: selects.parent().width(),
		range: selects.length > 1,//boolean for whether it's a range or not
		steps: options.length-1,
		stepping: 0,
		handles: function(){//set starting locations to selected index, if applicable
				var tempArr = [];
				selects.each(function(i){
					tempArr[i] = {
						start: presets[i],
						min: 0,
						max: 100,
						id: 'handle_'+i
					};
				});
				return tempArr;
			}(),
		change: function(e, ui) {//slide function
				var that = jQuery(this);
				var currValue = ui.value;
				var currIndex = Math.round(currValue / 100 * (options.length-1));
				var currValue = options[currIndex].value;
				var currText = options[currIndex].text;
				//handle feedback tooltip and aria attrs
				var feedback = ui.handle.find('.ui-slider-tooltip'); 
				feedback.html(currText).parent().attr('aria-valuetext', currValue).attr('aria-valuenow', currValue);
				//control original select menu
				var currSelect = jQuery('#'+ui.handle.attr('id').split('handle_')[1]);
				currSelect.find('option').eq(currIndex).attr('selected', 'selected');
			},
		// several section comment.
		partNum: 1,
		partWidth: "", /** format is part1:part2:part3:...**/
		sectionNum: "",  /** format is part1:part2:part3:...**/
		partClass: "" /** format is part1:part2:part3:...**/
	}, settings);
		
	selects.change(function(){
		var thisIndex = jQuery(this).find('option:selected').get(0).index;
		var thisLeft = Math.ceil((thisIndex / (options.length-1))* 100);
		var thisIndex = jQuery('#handle_'+ jQuery(this).attr('id')).parent().prev('a').size();
		jQuery('#handle_'+ jQuery(this).attr('id')).parents('.ui-slider:eq(0)').slider("moveTo", thisLeft,thisIndex);
	});
	
	//opt groups if present
	var groups = (function(){
		if(selects.eq(0).find('optgroup').size()>0){
			var groupedData = [];
			selects.eq(0).find('optgroup').each(function(i){
				groupedData[i] = {};
				groupedData[i].label = jQuery(this).attr('label');
				groupedData[i].options = [];
				jQuery(this).find('option').each(function(){
					groupedData[i].options.push({text: jQuery(this).text(), value: jQuery(this).attr('value')});
				});
			});
			return groupedData;
		}
		else return false;
	})();	

	//create slider component div
	var sliderComponent = jQuery('<div class="sliderComponent"></div>');
	
	//CREATE HANDLES
	selects.each(function(i){
		sliderComponent.append('<div id="handle_'+elIds[i]+'" tabindex="'+ i+1 +'" class="ui-slider-handle ui-default-state" role="slider" aria-valuemin="'+ sliderAPI.minValue +'" aria-valuemax="'+  sliderAPI.maxValue +'"><span class="ui-slider-tooltip ui-component-content"></span></div>');
	});
	
	//CREATE SCALE AND TICS
	sliderComponent.width(sliderAPI.width);
	
	//write dl if there are optgroups
	if(groups) {
		var scale = sliderComponent.append('<dl class="ui-slider-scale"></dl>').find('.ui-slider-scale:eq(0)');
		jQuery(groups).each(function(){
			scale.append('<dt><span>'+this.label+'</span></dt>');//class name becomes camelCased label
			var groupOpts = this.options;
			jQuery(this.options).each(function(i){
				scale.append('<dd><span class="ui-slider-label">'+ groupOpts[i].text +'</span><span class="ui-slider-tic ui-component-content"></span></dd>');
			});
		});
	}
	//write ol
	else {
		var scale = sliderComponent.append('<ol class="ui-slider-scale"></ol>').find('.ui-slider-scale:eq(0)');
		jQuery(options).each(function(){
			scale.append('<li><span class="ui-slider-label">'+this.text+'</span><span class="ui-slider-tic ui-component-content"></span></li>');
		});
	}
	var arrPartWidth = new Array();
	var arrPartNum = new Array();
	var arrPartClass = new Array();
	var sectionWidth = new Array();
	
	if ( sliderAPI.partWidth.indexOf(":") > -1 && sliderAPI.sectionNum.indexOf(":") > -1 && sliderAPI.partClass.indexOf(":") > -1 )
	{
		arrPartWidth = sliderAPI.partWidth.split(":");
		arrPartNum = sliderAPI.sectionNum.split(":");
		arrPartClass = sliderAPI.partClass.split(":");
	}
	
	if (arrPartNum.length > 0)
	{
		for (var k = 0; k < arrPartNum.length; k++)
		{
			sectionWidth[k] = parseFloat(arrPartWidth[k]) / parseInt(arrPartNum[k]);
		}
	}
	
	var index = 0;
	var k = 0;
	var lastWidth = 0;
	//style the li's or dd's
	sliderComponent.find('.ui-slider-scale li, .ui-slider-scale dd').each(function(i){
		if (sliderAPI.partNum > 1)
		{		
			if (arrPartNum.length > 0)
			{	
				if (index <= sliderAPI.partNum)
				{					
					k++;
					if (options[i].className.indexOf(arrPartClass[index]) > -1)
					{						
						if (index > 0)
							lastWidth += sectionWidth[index-1] * arrPartNum[index-1];
						k = 1;
						index++;
					}
					
					jQuery(this).css({
						'left': sectionWidth[index-1] * (k-1) + lastWidth 
					});
				}
			}
			else
				jQuery(this).css({
					'left': ((100 /( options.length-1))*i).toFixed(2) + '%'
				});	
		}
		else
			jQuery(this).css({
				'left': ((100 /( options.length-1))*i).toFixed(2) + '%'
			});
	});
	
	//first and last classes, and right align the last li/dd
	sliderComponent.find('.ui-slider-scale li:first, .ui-slider-scale dd:first').addClass('first');
	sliderComponent.find('.ui-slider-scale li:last, .ui-slider-scale dd:last').addClass('last').each(function(){ 
		jQuery(this).css({'right': 0, 'left':'auto'});
	});
	
	//show and hide labels depending on showLabels pref
	//show the last one if there are more than 1 specified
	/*if(sliderAPI.labels > 1) sliderComponent.find('.ui-slider-scale li:last span.ui-slider-label, .ui-slider-scale dd:last span.ui-slider-label').css('text-indent', 0).addClass('ui-slider-label-show');*/
	if(sliderAPI.labels > 1) sliderComponent.find('.ui-slider-scale li:last span.ui-slider-label, .ui-slider-scale dd:last span.ui-slider-label').css('text-indent', 0);
	//set increment
	var increm = Math.round(options.length / sliderAPI.labels);
	//show em based on inc
	for (var j=0; j<options.length; j++)
	{
		if (options[j].className.indexOf("per_show") > -1)
		{
			// Get end class name.
			var secClassName = "";
			secClassName = jQuery.trim(options[j].className.split(' ')[options[j].className.split(' ').length-1]);
			
			sliderComponent.find('.ui-slider-scale li:eq('+ j +') span.ui-slider-label, .ui-slider-scale dd:eq('+ j +') span.ui-slider-label').addClass('ui-slider-label-show' + ((secClassName) ? (' ' + secClassName) : ''));
		}
	}
	/*for(var j=0; j<options.length; j+=increm){
		if((options.length - j) > increm){//don't show if it's too close to the end label
			sliderComponent.find('.ui-slider-scale li:eq('+ j +') span.ui-slider-label, .ui-slider-scale dd:eq('+ j +') span.ui-slider-label').addClass('ui-slider-label-show');
		}
	}*/

	//style the dt's
	sliderComponent.find('.ui-slider-scale dt').each(function(i){
		var aPixel = ((3 / sliderAPI.width) * 100).toFixed(2);
		jQuery(this).css({
			'left': ((100 /( groups.length))*i).toFixed(2) + '%',
			'width': (((sliderAPI.width / groups.length) / sliderAPI.width) * 100).toFixed(2)- aPixel +'%'
		});
	});
	
	sliderAPI.markup = sliderComponent;
	
	//port slider function to pass api in.
	sliderAPI.markup.slider = function(settings){
		var sliderAPI_port = jQuery.extend(sliderAPI, settings);		
		jQuery(this).slider(sliderAPI_port).find('.ui-slider-range').css('opacity', sliderAPI_port.rangeOpacity);
		return this;
	}
	
	//if inject is true, inject slider after last select element and init, otherwise return api including markup
	if(sliderAPI.inject){
		sliderAPI.markup.insertAfter(jQuery(this).eq(this.length-1)).slider(sliderAPI).find('.ui-slider-range').css('opacity', sliderAPI.rangeOpacity);
		return this;
	}
	else{
		return sliderAPI;
	}

}


