/* Expressions */
// Regex selector
jQuery.expr[':'].regex=function(elem, index, match){
	var matchParams = match[3].split(','), validLabels = /^(data|css):/, attr = {
			method : matchParams[0].match(validLabels) ? matchParams[0].split(':')[0] : 'attr',
			property : matchParams.shift().replace(validLabels, '')
		}, regexFlags = 'ig', regex = new RegExp(matchParams.join('').replace(/^\s+|\s+$/g, ''), regexFlags);
	return regex.test(jQuery(elem)[attr.method](attr.property));
};

/* Functions */
jQuery.fn.extend({
	/**
	 * Export form data to an object
	 * @returns Object
	 */
	formToJQueryAjax : function(){
		var result = {};
		$(this).find(':input').not(':checkbox:not(:checked),:button, :submit').each(function(){
			var tablereg = /\[\]/i;
			if(tablereg.test(this.name)){
				var key=this.name.replace(tablereg,'');
				if(typeof(result[key])!='object')
					result[key]= new Array();
				result[key].push(this.value);
			}else
				result[this.name]= this.value;
		});
		return result;
	},
	/**
	 * Get the value of an array input
	 * @returns Array
	 */
	arrayVal : function(){
		var ret = [];
		$(this).each(function(i){if(this.name.match(/\[([0-9]*)\]$/))ret[i]=$(this).val();});
		return ret;
	},
	/**
	 * Limit characters of an input
	 * @param n
	 * @returns jQuery
	 */
	limitChars : function(n){
		$(this).each(function(){
			if($(this).is('textarea,input')){
				if($('#count'+$(this).attr('id')).length==0)
					$(this).after('<span class="count" id="count'+$(this).attr('id')+'">'+(n-$(this).val().length)+'</span>');
				$(this).bind('keydown keyup change',function(){
					/*if($(this).val().length>n)
						$(this).val($(this).val().substring(0,n));*/
					$('#count'+$(this).attr('id')).html(n-$(this).val().length);
				});
				//$(this).change();
			}
		});
		return $(this);
	},
	/**
	 * Transform a basic table into a dynamic list
	 * @param editer
	 * @param deleter
	 * @param forcePagename
	 * @returns jQuery
	 */
	initRollOver : function(editer,deleter,forcePagename){
		var reg = /\/([a-zA-Z0-9\_\-\/]+)\/list/i;
		var pagename = false;
		if(forcePagename) pagename = forcePagename;
		else if(reg.test(document.URL)){
			pagename=reg.exec(document.URL);
			pagename=pagename[1];
		}
		if($(this).is('table')){
			var table = this;
			var hoverClass="ui-state-highlight";
			// Mouseover des lignes
			$(this).find('tr:has(td)')
			.live("mouseover",function(){
				$(this).addClass(hoverClass);
			})
			.live("mouseout",function(){
				$(this).removeClass(hoverClass);
			});
			// Définition des fonctions d'édition et de suppression en fonction des données de la ligne
			_editer = typeof(editer)=='function'?editer:!pagename?null:function(){
				core.goTo(pagename+'/edit-'+$(this).parents('tr').attr('id')+'.html');
			};
			_deleter = function(){
				var tmp = $(this).parents('tr');
				var btn = this;
				/*if($("#dialog").is('.ui-dialog'))
					$("#dialog").dialog('open');
				else{*/
					$("#dialog").dialog({
						resizable: false,
						modal: true,
						//draggable: false,
						width:350,
						buttons : {
							'Non':function(){$("#dialog").dialog('close');core.indicator('Suppression annulée.');},
							'Oui':function(){
								if(typeof(deleter)=='function'){
									deleter(btn);
								}else if(pagename&&$(tmp).attr('id')){
									$.post(pagename+'/remove.pop',{id:$(tmp).attr('id')},function(data){
										$('#indicator,#error').hide();
										if(data){
											$parent = $(tmp).parents('table');
											var c = $(tmp).siblings('tr').length;
											$(tmp).remove();
											core.indicator('Suppression réussie.');
											if(c<=2)
												$('#null').show();
											else
												$('#null').hide();
											$parent.find('tr:odd').removeClass('even').addClass('odd');
											$parent.find('tr:even').removeClass('odd').addClass('even');
										}else{
											core.error('Erreur lors de la suppression');
										}
									});
								}else{
									$(tmp).remove();
								}
								$(this).dialog('close');
							}
						}
					});
				//}
			};
			if(_editer) $(this).find('a[class*=edit]:not([href])').live('click',_editer);
			$(this).find('a[class*=delete]:not([href])').live('click',_deleter);
			// Cacher les lignes 
			$(this).find('.toggler').live('click',function(){
				$(this).parents('tr').nextUntil('tr:has(th)').not('#null').toggle();
			});
			// Redirection lors des cliks sur les lignes si la case ne contient ni un lien ou un bouton
			$(this).find('tr[href] td:not(:has(input,a))').css('cursor','pointer').click(function(){
				window.location.href=$(this).parent().attr('href');
			});
			$(this).find('tr th').each(function(){
				// Ranger les colonnes
				if($(this).is('[sort]')&&$(this).find('a.ui-icon-arrow-1-n').length<=0){
					$(this).append('<br/><span></span>');
					$(this).find('span:last')
					.append('<a class="ui-icon ui-icon-arrow-1-n tri" href="'+pagename+'/list/order-'+$(this).attr("sort")+'A.html">&nbsp;</a>')
					.append('<a class="ui-icon ui-icon-arrow-1-s tri" href="'+pagename+'/list/order-'+$(this).attr("sort")+'D.html">&nbsp;</a>');
				}
			});
		}
		return $(this);
	},
	setDeleteOnRollOver : function(deleter){
		if($(this).is('table') && typeof(deleter)=='function'){
			_deleter = function(){
				var tmp = $(this).parents('tr');
				var btn = this;
				$("#dialog").dialog({
					resizable: false,
					modal: true,
					//draggable: false,
					width:350,
					buttons : {
						'Non':function(){$("#dialog").dialog('close');core.indicator('Suppression annulée.');},
						'Oui':function(){
							deleter(btn);
							$(this).dialog('close');
						}
					}
				});
			};
			$(this).find('a[class*=delete]:not([href])').die('click').live('click',_deleter);
		}
	},
	/**
	 * Build the horizontal menu
	 * @returns jQuery
	 */
	horizontalMenu : function(){
		if($(this).is('ul')){
			$(this).find('> li').addClass('ui-corner-bottom');
			$(this).find('li:has(ul)').find('a:first').prepend('<span style="float:right;vertical-align:middle;width:14px;" class="ui-icon ui-icon-triangle-1-s"></span>');
			$(this).find('li ul').addClass('sublist')
			.find('li:last').addClass('ui-corner-bottom');
			$(this).find('li:has(ul)')
			.mouseover(function(){
				$(this).find('ul').stop().show();
				//$(this).find('ul').stop().fadeTo("fast",1);
			})
			.mouseout(function(){
				$(this).find('ul').stop().hide();
				//$(this).find('ul').stop().fadeTo("fast",0,function(){$(this).css('display','none');});
			});
		}
		return $(this);
	},
	/**
	 * Transform an input text into a datepicker
	 * @returns jQuery
	 */
	isDatepicker : function(){
		$(this).each(function(){
			var maxDate=null;
			var minDate=null;
			var nulls = ["",0,"N/A","0",false];
			if($(this).is('.to') && !$(this).data('from')){
				if($(this).prev('input.datepicker.from').length)
					$(this).data("from",$(this).prev('input.datepicker.from'));
				else if($("input.datepicker.from:eq("+$("input.datepicker.to").index(this)+")").length)
					$(this).data("from",$("input.datepicker.from:eq("+$("input.datepicker.to").index(this)+")"));
				else if($(this).prevAll('input.datepicker.from').length)
					$(this).data("from",$(this).prevAll('input.datepicker.from:first'));
			}else if($(this).is('.from') && !$(this).data('to')){
				if($(this).next('input.datepicker.to').length)
					$(this).data("to",$(this).next('input.datepicker.to'));
				else if($("input.datepicker.to:eq("+$("input.datepicker.from").index(this)+")").length)
					$(this).data("to",$("input.datepicker.to:eq("+$("input.datepicker.from").index(this)+")"));
				else if($(this).nextAll('input.datepicker.to').length)
					$(this).data("to",$(this).nextAll('input.datepicker.to:first'));
			}
			if($(this).data('to')){
				maxDate = core.trim($(this).data('to').val());
				maxDate = jQuery.inArray(maxDate, nulls)>-1?null:maxDate;
			}
			else if($(this).data('from')){
				minDate = core.trim($(this).data('from').val());
				minDate = jQuery.inArray(minDate, nulls)>-1?null:minDate;
			}
			if($(this).is('.hasDatepicker')){
				$(this).datepicker('option',{'maxDate':maxDate,'minDate':minDate});
			}else{
				$(this).css("width","100px")
				.datepicker({
					dateFormat:"dd/mm/yy",
					changeMonth: true,
					changeYear: true,
					showAnim: 'fadeIn',
					showOn:'button',
					maxDate:maxDate,
					minDate:minDate,
					onSelect:function(dateText,inst){
						this.fireEvent && this.fireEvent('onchange') || $(this).change();
						if($(this).is('.to')){
							$(this).data('from').isDatepicker();
						}else if($(this).is('.from')){
							$(this).data('to').isDatepicker();
						}
					}
				});
			}
			$(this).next('button').css({'width':'22px','height':'22px'}).button({
				icons: {primary: "ui-icon-calendar"},
				text: false
			}).removeClass("ui-corner-all")
			.addClass("ui-corner-right ui-button-icon");
			
			if($(this).is(':disabled')) $(this).next('button').button('disable');
			if($(this).css('display')=='none') $(this).next('button').hide();
		});
		return $(this);
	},
	/**
	 * Give autocompletion to an input text
	 * @param forcedSource
	 * @returns jQuery
	 */
	isAutocomplete : function(forcedSource){
		$(this).each(function(){
			if(!$(this).is('.nohidden')){
				$(this).after("<input type='hidden' name='"+$(this).attr('id')+"' value='' />");
				$(this).data("hiddenField",$(this).next());
			}else if($('input:hidden[name="'+$(this).attr('id')+'"]').length){
				$(this).data("hiddenField",$('input:hidden[name="'+$(this).attr('id')+'"]'));
			}else
				$(this).data("hiddenField",null);
			$("<button type='button' style='width:22px;height:22px;vertical-align:middle;margin-left:-1px;'>Voir la liste</button>")
				.attr("tabIndex", -1)
				.insertAfter(this)
				.button({
					icons: {primary: "ui-icon-search"},
					text: false
				}).removeClass("ui-corner-all")
				.addClass("ui-corner-right ui-button-icon")
				.click(function() {
					if ($(this).prev().autocomplete("widget").is(":visible")) {
						$(this).prev().autocomplete("close");
					}else{
						$(this).prev().autocomplete("search",$(this).prev().val()==""?" ":$(this).prev().val());
						$(this).prev().focus();
					}
			});
			if($(this).is(':disabled')) $(this).next('button').button('disable');
			if($(this).css('display')=='none') $(this).next('button').hide();
			$(this)
			//.removeAttr('name')
			.autocomplete({
				source:forcedSource?forcedSource:function(request, response){
					request.type=$(this.element[0]).attr('source');
					request.join=$(this.element[0]).attr('join');
					request.params=$(this.element[0]).attr('params');
					$.ajax({
						url: "/autocomplete.xhtml",
						type: "POST",
						dataType: "json",
						data: request,
						success: function(data){
							response(data);
						}
					});
				},
				select:function(event,ui){
					if($('input[name="'+$(this).attr("id")+'"]').length>0)
						$('input[name="'+$(this).attr("id")+'"]').val(ui.item?ui.item.id:'');
					else
						$(this).nextAll('input[type=hidden]:first').val(ui.item?ui.item.id:'');
				},
				open:function(){
					var width = parseInt($(this).width(),10)+parseInt($(this).css("padding-left"),10)+parseInt($(this).css("padding-right"),10);
					width -= parseInt($(this).autocomplete("widget").css("padding-left"),10)+parseInt($(this).autocomplete("widget").css("padding-right"),10);
					$(this).autocomplete("widget").width(width+'px');
				},
				disable:function(){alert('disabled');}
			}).dblclick(function(){
				if($(this).val().length<1&&!$(this).is('.nolimit'))
					core.error("Entrez au minimum 1 charactère",this);
				else
					$(this).autocomplete("search",$(this).val()==""?" ":$(this).val());
			}).data( "autocomplete" )._renderItem = function( ul, item ) {
				var t = item.label.replace(new RegExp("(?![^&;]+;)(?!<[^<>]*)(" + $.ui.autocomplete.escapeRegex(this.term) + ")(?![^<>]*>)(?![^&;]+;)", "gi"), "<strong>$1</strong>");
				return $( "<li></li>" )
					.data( "item.autocomplete", item )
					.append( "<a>" + (item.icon?"<span class='ui-icon ui-icon-" + item.icon + "' style='float:left;'>&nbsp;</span>":"") + t + "</a>" )
					.appendTo( ul );
			};
			$(this).autocomplete("widget").removeClass('ui-corner-all').addClass('ui-corner-bottom');
		});
		return $(this);
	},
	/**
	 * Allow only numbers in the selected inputs
	 * @returns jQuery
	 */
	isNumericInput : function() {
		$(this).each(function(){
			if($(this).is('input:text')){
				$(this).focus(function(){
					if(this.value==0)
						this.value='';
				})
				.blur(function(){
					if(this.value=='')
						this.value=0;
				})
				.numeric();
			}
		});
		return $(this);
	},
	/**
	 * Transform a button or input type button/submit
	 * @returns jQuery
	 */
	isButton : function(){
		$(this).each(function(){
			if($(this).is('.toggler')){
				$(this).button({icons:{primary:$(this).is('.closed')?'ui-icon-plus':'ui-icon-minus'},text:false}).click(function(){
					if($(this).find('span.ui-icon-plus').length)
						$(this).find('span.ui-icon-plus').removeClass('ui-icon-plus').addClass('ui-icon-minus');
					else
						$(this).find('span.ui-icon-minus').removeClass('ui-icon-minus').addClass('ui-icon-plus');
				});
			}else 
				if($(this).is('[class*="uiicon-"]')){
					var classToIcon = {
						"edit":"pencil",
						"delete":"trash",
						"add":"plus",
						"save":"disk",
						"next":"ui-icon-triangle-1-e",
						"prev":"ui-icon-triangle-1-w"
				};
				var o={};
				var tmp=RegExp(/uiicon-([a-zA-Z0-9\.\-\_]+)/).exec($(this).attr("class"));
				o.icons={primary:'ui-icon-'+(classToIcon[tmp[1]]!=undefined?classToIcon[tmp[1]]:tmp[1])};
				o.text=RegExp(/viewtext/).test($(this).attr("class"));
				//core.log(o)
				$(this).button(o);
			}else
				$(this).button();
		});
		return $(this);
	},
	/**
	 * Empty inputs, textareas, uncheck checkboxes and select first
	 * @returns jQuery
	 */
	emptyFields : function(){
		$(this).each(function(){
			$(this).find('input[type=text],input[type=password],input[type=text].autocomplete + button + input[type=hidden],input[type=hidden][name=offset]').val('');
			$(this).find('input[type=checkbox]').attr('checked',false);
			$(this).find('select option:first').attr("selected", "selected");
			$(this).find('[id^=checkAll]').attr('checked',true).click().attr('checked',true);
		});
		return $(this);
	},
	/**
	 * Check if there is at least one checkbox checked
	 * @returns Boolean
	 */
	atLeastOnSelected : function(){
		return ($(this).find('input[type=checkbox][name]:not(#checkAll):checked').length > 0);
	},
	/**
	 * Set all checkbox in container to the target state
	 * @param container
	 * @returns jQuery
	 */
	checkAll : function(container){
		if($(this).is(":checkbox")){
			$(this).click(function(){
				$(container).find('[type=checkbox][name]').attr('checked',$(this).attr('checked'));
			});
			//$(container).find('[type=checkbox][name]').not(this).attr('checked',$(this).attr('checked'));
			$(container).find('[type=checkbox][name]').data("checkerID",$(this).attr('id')).not(this).click(function(){
				$checkbox = $(container).find('[type=checkbox][name]:not('+$(this).data('checkerID')+')');
				if($checkbox.filter(':checked').length == $checkbox.length){
					$("#"+$(this).data('checkerID')).attr('checked','checked');
				}else{
					$("#"+$(this).data('checkerID')).removeAttr('checked');
				}
			});
		}
		return $(this);
	},
	/**
	 * Disable "Enter" validation in inputs
	 * @returns jQuery
	 */
	disableEnter : function(){
		$textboxes = $(this).is("input:text")?$(this):$(this).find("input:text");
		var evt = $.browser.mozilla?"keypress":"keydown";
		$textboxes.bind(evt,function(event) {
			if (event.keyCode == 13){
				event.preventDefault();
				return false;
			}
		});
		return $(this);
	},
	checkForm : function(){
		var submit = true;
		$(this).each(function(){
			if($(this).is('form')){
				var tocheck = '[name].tocheck:not(:disabled)';
				var space_reg = /(^\s*)|(\s*$)/g;
				var html_reg = /(<[^>]*>)|(&nbsp;)/g;
				var empty = ["",false,null,0,"0"];
				$(this).find('input').filter(tocheck).each(function(){
					var val = typeof(tinyMCE)!=undefined?$(this).val().replace(html_reg,""):$(this).val();
					val = core.trim(val);
					if(jQuery.inArray(val,empty)>-1){
						submit = false;
						$(this).addClass('alert');
						if($(this).is('.autocomplete,.datepicker')){
							$(this).next('button').addClass('ui-state-error');
						}else if($(this).is('input[type=hidden]')){
							$input = $("#"+$(this).attr('name')).length>0?$("#"+$(this).attr('name')):$(this).siblings('input[type=text].autocomplete');
							$($input).addClass('alert').next('button').addClass('ui-state-error');
						}
						
						if($(this).prev().is('label'))
							$(this).prev().addClass('alert');
						else if($(this).attr('id')!="")
							$('label[for="'+$(this).attr('id')+'"]').addClass('alert');
					}else{
						if($(this).is('.alert')) $(this).removeClass('alert');
						if($(this).is('.autocomplete,.datepicker') && $(this).next('button').is('.alert')){
							$(this).next('button').removeClass('ui-state-error');
						}else if($(this).is('input[type=hidden]')){
							$input = $("#"+$(this).attr('name')).length>0?$("#"+$(this).attr('name')):$(this).siblings('input[type=text].autocomplete');
							if($input.is('.alert'))
								$input.removeClass('alert').next('button').removeClass('ui-state-error');
						}
					
					if($(this).prev().is('label'))
						$(this).prev().removeClass('alert');
					else if($(this).attr('id')!="")
						$('label[for="'+$(this).attr('id')+'"]').removeClass('alert');
						
					}
				});
				$(this).find('textarea').filter(tocheck).each(function(){
					var val = $(this).val().replace(space_reg,"");
					if(jQuery.inArray(val,empty)>-1){
						submit = false;
						if($(this).prev().is('label'))
							$(this).prev().addClass('alert');
						else if($(this).attr('id')!="")
							$('label[for="'+$(this).attr('id')+'"]').addClass('alert');
					}else{
						if($(this).prev().is('label'))
							$(this).prev().removeClass('alert');
						else if($(this).attr('id')!="")
							$('label[for="'+$(this).attr('id')+'"]').removeClass('alert');
					}
				});
				$(this).find('select').filter(tocheck).each(function(){
					var val = val.replace($(this).find("option:selected").val(),"");
					if(jQuery.inArray(val,empty)>-1){
						submit = false;
						$(this).addClass('alert');
						if($(this).prev().is('label'))
							$(this).prev().addClass('alert');
						else if($(this).attr('id')!="")
							$('label[for="'+$(this).attr('id')+'"]').addClass('alert');
					}else{
						$(this).removeClass('alert');
						if($(this).prev().is('label'))
							$(this).prev().removeClass('alert');
						else if($(this).attr('id')!="")
							$('label[for="'+$(this).attr('id')+'"]').removeClass('alert');
					}
				});
			}
		});
		if(!submit) core.error('Le formulaire est incomplet !');
		return submit;
	}

});

