/*
 * jQuery mSelect Plugin 1.4.3 (16 juillet 2011)
 * requires jQuery v1.4.2 or later
 *
 * Dual licensed under the MIT and GPL licenses:
 *   http://www.opensource.org/licenses/mit-license.php
 *   http://www.gnu.org/licenses/gpl.html
 *
 * Auteur : Samuel Mandonnaud <mandonnaud.s gmail com> http://www.le-pret-a-surfer.com
 */
(function($) {
  $.fn.mSelect = function(options,obj) {
		// Verification de l'option 'disable' ou 'activate'
		switch (options) {
			case 'activate':
				var $obj;
				$(this).each(function() {
					$obj=$(this);
					if (!$obj.hasClass('mSelect')) {
						$.fn.mSelect.debug('Seul les éléments mSelect sont accepté pour la méthode disable : '+this);
					} else {
						$obj.removeClass('mDisable');
					}
				});
			break;
			case 'disable':
				var $obj;
				$(this).each(function() {
					$obj=$(this);
					if (!$obj.hasClass('mSelect')) {
						$.fn.mSelect.debug('Seul les éléments mSelect sont accepté pour la méthode disable : '+this);
					} else {
						$obj.addClass('mDisable');
					}
				});
			break;
			case 'add':
			case 'options':
				var $obj;
				var attrName = '';
				var attrSelected = '';		
				var selected=null;
				$(this).each(function() {
					$obj=$(this);
					
					if (!$obj.hasClass('mSelect')) {
						$.fn.mSelect.debug('Seul les éléments mSelect sont accepté pour la méthode disable : '+this);
					} else {
						
						
						attrName = String($obj.children('.mOptions').children('.mOption').children('input[type=radio]').attr('name'));
						if (attrName == '' || attrName=='undefined') {
							attrName = 'mSelect'+Math.floor(Math.random()*100000);
						}
						
						if (options=='options') {
							$obj.children('.mOptions').html('');
						}
						
						for(var i=0; obj.length>i; i++) {			
							if (!obj[i].cssClass) {
								obj[i].cssClass='';							
							}
							attrSelected='';
							if (obj[i].selected) {
								$('.mCurrentTemp').removeClass('mCurrentTemp');
								obj[i].cssClass+=' mCurrentTemp';
							}
							$obj.children('.mOptions').append('<div class="mOption '+obj[i].cssClass+'"><input type="radio" value="'+obj[i].value+'" class="mRadio" name="'+attrName+'" />'+obj[i].html+'</div>');
							
						}
						$obj.children('.mSelected').html($('.mCurrentTemp').html()).children('.mRadio').remove();
						$obj.children('.mOptions').children('.mOption').css({cursor:'pointer'}).children('.mRadio').hide();
						if ($obj.children('.mOptions').children('.mCurrent').size()!=0) $obj.children('.mOptions').children('.mCurrent').removeClass('mCurrent').children('.mRadio')[0].checked=false;
						$obj.children('.mOptions').children('.mCurrentTemp').removeClass('mCurrentTemp').addClass('mCurrent').children('.mRadio')[0].checked=true;
						
					}
				});
			break;
			case 'selected':
				var $obj;
				$(this).each(function() {
					$obj=$(this);
					if (!$obj.hasClass('mSelect')) {
						$.fn.mSelect.debug('Seul les éléments mSelect sont accepté pour la méthode disable : '+this);
					} else {
						if ($obj.children('.mOptions').children('.mCurrent').size()!=0) $obj.children('.mOptions').children('.mCurrent').removeClass('mCurrent').children('.mRadio')[0].checked=false;
						$obj.children('.mSelected').html($obj.children('.mOptions').children('.mOption').eq(obj).html()).children('.mRadio').remove();
						$obj.children('.mOptions').children('.mOption').eq(obj).addClass('mCurrent').children('.mRadio')[0].checked=true;
					}
				});
			break;
			default:
				var opts = $.extend({}, $.fn.mSelect.defaults, options);
				var $obj;
				var objType='';
				var $objOpt;
				var $objOptRadio;
				var $objOptLabel;
				
				$(this).each(function() {	
					$obj=$(this);
					// Verification que l'ensemble du 
					if ($obj.is('select')) {
						objType='select';
					} else if ($obj.is('ul')) {
						objType='ul';
					} else {	 
						$.fn.mSelect.debug('Seul les éléments "select" et "ul" sont accepté : '+this);
						return;
					}
					
					// Recherche de l'attribut "name" des elements du fomrulaire 
					// pour le conserver au moment de l'envoi
					var attrName = '';
					if (objType=='select') {
						attrName = String($obj.attr('name'));
					} else {
						attrName = String($obj.children('li').children('input[type=radio]').attr('name'));
					}					
					if (attrName == '' || attrName=='undefined') {
						attrName = 'mSelect'+Math.floor(Math.random()*100000);
					}
				
					// Recherche de l'id pour le conserver
					var id='';
					if ($obj.attr('id')) {
						var id='id = "'+$obj.attr('id')+'" ';
					}
					// Creation du div conteneur general
					$obj.wrap('<div class="mSelect" '+id+' style="display:inline-block;" />');
					// Creation du div conteneur de l'option selectionné
					var $objMs=$obj.parent().append('<div class="mFleche"></div><div class="mSelected">'+opts.defaut+'</div><div class="mOptions"></div>');
					
					// Création des options
					if (objType=='select') {
						
						$obj.children('option').each(function() {
							$objOpt=$(this);					
							// Création de la valeur soit par l'ancien value soit par le contenu
							var attrValue='';
							if ($objOpt.attr('value')) {
								attrValue=$objOpt.attr('value');
							} else {
								attrValue=$objOpt.html();
							}
							 
							// verification de l'existance de "class" pour la garder
							var attrClass='';
							
							if ($objOpt.attr('class')) {
								attrClass+=' '+$objOpt.attr('class');
							}
							// on conserve l'element selectionné
							var attrSelected='';
							if ($objOpt.attr('selected')) {
								attrClass+=' mCurrent';
								attrSelected='checked="checked" ';
								$objMs.children('.mSelected').html($objOpt.html());
							}
							// on ajoute l'option 
							$objMs.children('.mOptions').append('<div class="mOption'+attrClass+'"><input type="radio" '+attrSelected+'value="'+attrValue+'" class="mRadio" name="'+attrName+'" />'+$objOpt.html()+'</div>');
							
							
			
						});
						$objOpt=null;
					} else {
						$obj.children('li').each(function() {
							$objOpt=$(this);
							$objOptRadio=$objOpt.children('input[type=radio]');
							$objOptLabel=$objOpt.children('label');
							
							// Chaque ligne doit contenir un element input radio
							if (!$objOptRadio) {
								$.fn.mSelect.debug('Input Radio manquand');
								return;
							}
							// Chaque ligne doit contenir un element label
							if (!$objOptLabel) {
								$.fn.mSelect.debug('Label manquand');
								return;
							}
							// Création de la valeur soit par l'ancien value soit par le contenu
							var attrValue=String($objOptRadio.attr('value'));
							if (
								attrValue == 'undefined'
								|| attrValue == 'on'
								|| attrValue == '' ) {
								attrValue=$objOptLabel.text();
							}
							// verification de l'existance de "class" pour la garder
							var attrClass='';
							if ($objOpt.attr('class')) {
								attrClass+=' '+$objOpt.attr('class');
							}
							
							// on conserve l'element selectionné
							var attrSelected='';
							if ($objOptRadio.attr('checked')) {
								attrClass+=' mCurrent';
								attrSelected='checked="checked" ';
								$objMs.children('.mSelected').html($objOptLabel.html());
							}
							
							// on ajoute l'option 
							$objMs.children('.mOptions').append('<div class="mOption'+attrClass+'"><input type="radio" '+attrSelected+'value="'+attrValue+'" class="mRadio" name="'+attrName+'" />'+$objOptLabel.html()+'</div>');
						});
						$objOpt=null;
						$objOptRadio=null;
						$objOptLabel=null;						
					}
					
					// On cache le champ radio
					var $objMsOpt=$objMs.children('.mOptions').children('.mOption');
					if (opts.radioHide) {
						$objMsOpt.children('.mRadio').hide();
					}
					
					opts.scrollBar=false;
					if (opts.nbVisible!=0 && $objMsOpt.size()>opts.nbVisible) {
						opts.scrollBar=true;						
						opts.hauteur=$.fn.mSelect.addEventScroll($objMs,$objMsOpt,opts);
					}
					
					$.fn.mSelect.addEvent($objMs,opts);
					// on supprime l'ancien element
					$obj.remove();
					$obj=null;
					objType=null;
				});
			break;
		}
	};
	$.fn.mSelect.addEventScroll = function($objMs,$objMsOpt,opts) {
		
		opts.hauteur=opts.nbVisible*$objMs.children('.mOptions').children('.mOption').outerHeight();
						
		if (opts.scrollBarMin>hauteurBar) {
			hauteurBar=opts.scrollBarMin;
		}
		$objMs.append('<div class="mScrallBar"><div class="mScrollHaut"></div><div class="mScrollZone"><div class="mBarre"></div></div><div class="mScrollBas"></div></div>')
			.children('.mOptions')
			.addClass('mScrollConteneur')
			.css({overflow:'auto'});
			//.height(opts.hauteur);

		var hauteurScroll=opts.hauteur-$objMs.children('.mScrallBar').children('.mScrollHaut').outerHeight()-$objMs.children('.mScrallBar').children('.mScrollBas').outerHeight();
		var hauteurGrand=$objMsOpt.size()*$objMs.children('.mOptions').children('.mOption').outerHeight();
		var hauteurBar=opts.hauteur*hauteurScroll/hauteurGrand;
		var hauteurCoefDrag=(hauteurGrand-opts.hauteur)/(hauteurScroll-hauteurBar);
		var hauteurCoefDrag2=(hauteurGrand-opts.hauteur)/(hauteurScroll);
	
		$objMs
		.children('.mScrallBar')
		.css({position:'absolute'}).hide()
		.unbind('click')
		.bind('click',function(event) { event.stopPropagation(); });
		$objMs
		.children('.mScrallBar')
		.children('.mScrollZone');
		//.height(hauteurScroll);
		$objMs
		.children('.mScrallBar')
		.children('.mScrollZone')
		.children('.mBarre')		
		.css({position:'absolute'});		
		//.height(hauteurBar);
		
		// Opera gere la scrollbar sans le script (grace à la scrollbar native cacher derriere)
		if (navigator.appName!='Opera') {
			$objMs
			.children('.mScrallBar')
			.children('.mScrollZone')
			.unbind('click')
			.bind('click',function(event) {
				var offset=$objMs.children('.mScrallBar').children('.mScrollZone').offset();
				$objMs.children('.mOptions').scrollTop((event.pageY-offset.top)*hauteurCoefDrag2);
			})
			.children('.mBarre')
			.unbind('mousedown')
			.bind('mousedown',function(event) {
				event.stopPropagation();
				var offset=$objMs.children('.mScrallBar').children('.mScrollZone').offset();
				offset=offset.top+event.layerY;
				$(document).bind('mousemove',function(event) {
					$objMs.children('.mOptions').scrollTop((event.pageY-offset)*hauteurCoefDrag);
				}).one('mouseup',function(event) {
					$(document).unbind('mousemove');
				});
			});
			
			
						
			 
			$objMs.children('.mScrallBar').children('.mScrollHaut').unbind('mousedown').bind('mousedown',function(event) {
				$objMs.children('.mOptions').scrollTop($objMs.children('.mOptions').scrollTop()-opts.scrollVitesse);
				$.fn.mSelect.$scrollEnCours=$objMs.children('.mOptions');
				window.setTimeout('$.fn.mSelect.scollAuto('+(-opts.scrollVitesse)+')',700);
				event.stopPropagation();

				$(document).one('mouseup',function(event) {
					$.fn.mSelect.$scrollEnCours=null;
				});
				
			});
			$objMs.children('.mScrallBar').children('.mScrollBas').unbind('mousedown').bind('mousedown',function(event) {
				$objMs.children('.mOptions').scrollTop($objMs.children('.mOptions').scrollTop()+opts.scrollVitesse);
				$.fn.mSelect.$scrollEnCours=$objMs.children('.mOptions');
				window.setTimeout('$.fn.mSelect.scollAuto('+opts.scrollVitesse+')',700);
				event.stopPropagation();

				$(document).one('mouseup',function(event) {
					$.fn.mSelect.$scrollEnCours=null;
				});
				
			});
		}
		$objMs.children('.mOptions').unbind('scroll').bind('scroll',function(e) {
			$objMs
			.children('.mScrallBar')
			.children('.mScrollZone')
			.children('.mBarre')
			.css({
				'top':$objMs.children('.mScrallBar').children('.mScrollHaut').outerHeight()+($objMs.children('.mOptions').scrollTop()/(hauteurGrand-opts.hauteur)*(hauteurScroll-hauteurBar))
			});
			

			
		});
		return opts.hauteur;
	}
	$.fn.mSelect.addEvent = function($objMs,opts) {
		// on passe en position 'absolute', on cache et on ajoute un ecouteur au click
		$objMs.children('.mOptions').hide().css({position:'absolute'}).children('.mOption').css({cursor:'pointer'});
		$objMs.children('.mOptions').click(function(e) {
			var $obj=$(e.target);
			if ($obj.is('.mOption')) {
				// on enleve tous les checkeds
				//~ if ($objMs.children('.mOptions').children('.mCurrent').size()!=0) $objMs.children('.mOptions').children('.mCurrent').removeClass('mCurrent').children('.mRadio')[0].checked='';
				if ($objMs.children('.mOptions').children('.mCurrent').size()!=0) $objMs.children('.mOptions').children('.mCurrent').removeClass('mCurrent').children('.mRadio').removeAttr('checked');
				// on passe celui en cours en checked
				$obj.addClass('mCurrent').children('.mRadio')[0].checked='checked';
				// on copie le contenu 
				$objMs.children('.mSelected').html($obj.html()).children('.mRadio').remove();
				if (opts.eventClick) {
					opts.eventClick.apply(e.target,[$obj.children('.mRadio').val(),$objMs.children('.mSelected').html()]);
				}
			}
		});
		// on ajoute un ecouteur d'evenement 'click' pour affiché la liste
		$objMs.one('click',function() {	
			$.fn.mSelect.clickOuvert($objMs,opts);
		});
	}
	$.fn.mSelect.$scrollEnCours=null;
	$.fn.mSelect.scollAuto = function(vitesse) {
		if ($.fn.mSelect.$scrollEnCours!=null) {
			$.fn.mSelect.$scrollEnCours.scrollTop($.fn.mSelect.$scrollEnCours.scrollTop()+vitesse);
			window.setTimeout('$.fn.mSelect.scollAuto('+vitesse+')',100);	
		}
	};
	$.fn.mSelect.clickOuvert = function($objMs,opts) {
		if ($objMs.hasClass('mDisable')) {
			$objMs.one('click',function() {	
				$.fn.mSelect.clickOuvert($objMs,opts);
			});
			return;
		}
		
		
		var info=$objMs.position();
		var x=info.left;
		var y=info.top+$objMs.outerHeight();
		var id='';
		
		
		
		$objMs.children('.mOptions').css({top:y,left:x}).slideDown(180);
		if (opts.scrollBar) {
			if (opts.nbVisible*$objMs.children('.mOptions').children('.mOption').outerHeight()!=opts.hauteur) {			
				opts.hauteur=$.fn.mSelect.addEventScroll($objMs,$objMs.children('.mOptions').children('.mOption'),opts);
			}
			$objMs.children('.mScrallBar').css({
				top:y,
				left:x+$objMs.children('.mOptions').outerWidth()-$objMs.children('.mScrallBar').outerWidth()
			}).slideDown(180);
			
			
		}
		$objMs.children('.mOptions').children('.mOption').each(function() {
			
			y+=$(this).outerHeight();
			if ($(this).children('input')[0].checked) {
				id=$(this).children('input').val();
			}
		});
		
		if (opts.eventOpen) {
			opts.eventOpen.apply($objMs[0],[id,$objMs.children('.mSelected').html()]);
		}
		
		
		
		$(document).delay(1).queue(function() {
			$(this).clearQueue();
			
			$(this).one('click',function() {
				var id='';
				$objMs.children('.mOptions').slideUp(180).children('.mOption').each(function() {
					if ($(this).children('input')[0].checked) {
						id=$(this).children('input').val();
					}
				});
				if (opts.scrollBar) {
					$objMs.children('.mScrallBar').slideUp(180);
				}
				if (opts.eventClose) {
					opts.eventClose.apply($objMs[0],[id,$objMs.children('.mSelected').html()]);
				}
				$objMs.one('click',function() {	
					$.fn.mSelect.clickOuvert($objMs,opts);
				});
			});
		});
		
	}
	$.fn.mSelect.debug = function(msg) {
		if (window.console && window.console.firebug) { 
			console.error('mSelect : '+msg);
		} else {
			alert('mSelect : '+msg);
		}
	};
	$.fn.mSelect.defaults = {
		defaut:'',
		radioHide:true,
		nbVisible:6,
		scrollBarMin:3,
		scrollVitesse:10,
		eventClick:null,
		eventOpen:null,
		eventClose:null
	};
})(jQuery);

