/**
 * kValidator
 * 
 * Call it like that : $("yourNodeSelector").kValidator({type:""});
 * 
 * An event handler is bind to the node, and
 * 
 * All validator pattern are defined in the window scope. See them at the plugin's bottom
 */
(function($)
{	
    $.fn.kValidator = function(options)
    {
    	/**
    	 * Global var, pattern need to access it.
    	 */
    	kVal_opts = $.extend( {}, $.fn.kValidator.params, options );
        
        /**
         * Plugin core
         */
        return this.each(function(){
        	
        	var $t = $(this), 
        		name = $t.attr("name"),
        			 o = { "mode" : kVal_opts.mode, "name" : name };
        	
        	if( typeof kVal_opts.type === "object" || typeof kVal_opts.type === "array" )
        	{
        		$.each( kVal_opts.type, function(i, val)
        		{
        			args = extractParam(val);
        			if( ! $.isFunction( pattern[ args.cB ] ) ) return;
        			recordCallBack( args.cB, args.aArg, $t );
        		});
        	}
        	else if( kVal_opts.type === "string" && kVal_opts.type.length > 0 )
        	{
        		args = extractParam(val);
        		if( ! $.isFunction( pattern[ args.cB ] ) ) return;
        		recordCallBack( args.cB, args.aArg, $t );
        	}
        	else if( kVal_opts.type === "" )
        	{
        		return; 
        	}
        	else console.error( "kValidator jquery plugin can't read needed param TYPE, check node "+name+"." );
        	
        	$t.bind( "blur submit",{}, function(e)
        	{
        		var $tt = $(this),
        			d = $tt.data("validator"),
        				value = $tt.getValue();
        					
        		if( typeof d != "undefined" && d.length > 0 )
        		{
        			for( var i = 0, limit = d.length ; i < limit ; i++ )
        			{
        				var e = $.Event("failure"),
        					validator = d[i][0],
        						sParam = d[i][1];
        				e.pattern = validator;
        				//e.stopPropagation();
        				
        				o.val = value;
        				o.param = sParam;
        				
        				var test = pattern[ validator ]( o );
        				console.log(test + " : "+validator );
        				if ( test !== true && validator != "checkDistinct" ) $tt.trigger( e );
        			}
        		}
    		});
        	
        });//end each
        
        
        
    };
    
    /**
     * Defaults main plugin params
     */
    $.fn.kValidator.params = {
    	
         type : "",
         eventToCkeck: "blur,submit",
         mode:"strict",
         serveurUrl:window.location.pathname
        
    };

    var extractParam = function( sType ){
    	
    	var callBack,
    		param,
    			p = sType.match(/(\w+)\((\w+)\)$/);
    	
    	if( p !== null ) 
    	{
    		param = p[2];
    		callBack = "check"+kUCFirst( p[1] );
    	}
    	else callBack = "check"+kUCFirst( sType );
    	
    	return ( typeof param !== "undefined" ) ? { "cB" : callBack, "aArg" : param } : { "cB" : callBack, "aArg" : "" };
    };

    
    /**
     * Little helper function, like the PHP function
     */ 
    var kUCFirst = function(str){
    	   
    	firstChar = str.substring(0,1);
    	remainChar = str.substring(1);

    	firstChar = firstChar.toUpperCase(); 
    	remainChar = remainChar.toLowerCase();

    	return firstChar + remainChar;

    };
    
    var recordCallBack = function( cB, aArg, $t )
    {
    	if( typeof $t.data("validator") != "undefined" )
    		$t.data("validator").push( [cB, aArg ] );
    	else
    	{
    		$t.data("validator",[]);
    		$t.data("validator").push( [ cB, aArg ] );
    	}
    };

    
})(jQuery);



var pattern = {};

/**
 * @params val, the val to check
 */
pattern.checkObligatory = function( o ){
	
	if(  typeof o.val === "string" ) return ( o.val != "" ) ? true : false;
	
	else if( typeof o.val === "object" || typeof o.val === "array" ) return ( o.val.length > 0 ) ? true : false;
	
	else return false;
	
};

/**
 * @param options.toCheck
 * @param options.aArgs.authValue
 * @param options.mode
 */
pattern.checkEnum = function( o ){
	
	var aAuthVal = o.param.split("-");
	
	return in_array( o.val,aAuthVal);
};

/**
 * @param options.toCheck
 * @param options.aArgs.
 * @param options.mode
 */
pattern.checkAuthchar= function( o )
{	
	if( o.val === "" ) return ( o.mode === "strict" ) ? false : true;
	
	switch( o.param )
	{
		case "alpha":
			var testResult = o.val.match(/(a-zA-Z+)/);
			return ( testResult === null ) ? false : true;
			break;
			
		case "numeric" :
			var testResult = o.val.match(/(0-9+)/);
			return ( testResult === null ) ? false : true;
			break;
			
		case "alphanumeric":
			var testResult = o.val.match(/(a-zA-Z0-9+)/);
			return ( testResult === null ) ? false : true;
			break;
	}
};

/**
 * @param options.toCheck
 * @param options.aArgs.minLength
 */
pattern.checkMinlength= function( o )
{	
	return ( o.val.length >= parseInt( o.param ) ) ? true : false;
};

/**
 * @param options.toCheck
 * @param options.aArgs.maxLength
 */
pattern.checkMaxlength = function( o )
{	
	return ( o.val.length <= parseInt( o.param ) ) ? true : false;
};

/**
 * @param options.toCheck
 * @param options.aArgs.url
 * @param options.aArgs.dbFieldName
 * @param options.mode
 * 
 * La requete Ajax doit retourner "true" si c distinct
 */
pattern.checkDistinct = function( o )
{
	if( o.val == "" ) return ( o.mode === "strict" ) ? false : true;
	
	var dbName = ( typeof o.name != "undefined" ) ? o.name : kVal_opts.dbFieldName;
	
	$.ajax({
		type:"GET",
		url : kVal_opts.serveurUrl,
		data : "dbFieldName="+dbName+"&value="+o.val,
		async:false,
		timeout:10000,
		success:function(msg){
			var result = ( $.trim(msg) === "true" ) ? true : false;
			console.log(result);
			if( result === false ){
				var e = $.Event("failure");
				e.pattern = "checkDistinct";
				$tt.trigger( e );
			}	
	   	}
	});
};

/**
 * @param options.toCheck
 * @param options.mode
 */
pattern.checkEmail = function( o ){
	
	if( o.val == "" ) return ( o.mode === "strict" ) ? false : true;
	
	var pattern = /^([a-zA-Z0-9_.-])+@(([a-zA-Z0-9-])+.)+([a-zA-Z0-9]{2,4})+$/;
	
	return ( o.val.match(pattern) === null ) ? false : true;
};

/**
 * @param options.toCheck
 * @param options.aArgs.compareWith
 */
pattern.checkIdentity = function( o ){
	
	var toCompare = $("input[name='"+o.param+"']").getValue();
	
	return ( o.val == toCompare ) ? true : false;
};

/**
 * @param options.toCheck
 * @param options.aArgs.callback
 */
pattern.checkCallBack = function( o ){
	if( $.isFunction( o.param ) ){
		o.param.call( o.val );
	}
};

