"use strict";
// trim()
if(typeof String.prototype.trim !== 'function') {
	String.prototype.trim = function() {
			return this.replace(/^\s+|\s+$/, '')+'';
	};
}
// addslashes()
if(typeof String.prototype.addslashes !== 'function') {
	String.prototype.addslashes = function() {
		return this.replace(/[\\"']/g, '\\$&').replace(/\u0000/g, '\\0')+'';
	};
}
// striptags
if(typeof String.prototype.striptags != 'function' ) { 
	String.prototype.striptags = function () { 
		return this.replace(/(<([^>]+)>)/gi, "");
	};
}
// getInt()
if(typeof String.prototype.getInt !== 'function') {
	String.prototype.getInt = function() {
		var rgx = new RegExp('[0-9]+','g' ),r;
		if ( r = rgx.exec(this)  )  return parseInt(r);
		else  return Number.NaN;
	};
}
//isAlphaNumeric
if(typeof String.prototype.isAlphaNumeric !== 'function') {
	String.prototype.isAlphaNumeric = function() {
		var rgx = new RegExp('^[a-z0-9_-]+$','gi' ),r;
		if ( r = rgx.test(this)  )  return true;
		return false;
	};
}
//date 
if(typeof Date.prototype.toMysqlDate !== 'function') {
	Date.prototype.toMysqlDate = function() {
		  return this.getFullYear() + '-' +
			    (this.getMonth() < 9 ? '0' : '') + (this.getMonth()+1) + '-' +
			    (this.getDate() < 10 ? '0' : '') + this.getDate();		
	};
}
if(typeof String.prototype.formatNumber !== 'function') {
	// french version of http://phpjs.org/functions/this_format:481
	String.prototype.formatNumber = function (decimals, dec_point, thousands_sep) {
	    var number = this.replace(/[^0-9+\-Ee.]/g, '');
	    var n = !isFinite(+number) ? 0 : +number,
	        prec = !isFinite(+decimals) ? 0 : Math.abs(decimals),
	        sep = (typeof thousands_sep === 'undefined') ? ' ' : thousands_sep,
	        dec = (typeof dec_point === 'undefined') ? ',' : dec_point,
	        s = '',
	        toFixedFix = function (n, prec) {
	            var k = Math.pow(10, prec);
	            return '' + Math.round(n * k) / k;
	        };
	    // Fix for IE parseFloat(0.55).toFixed(0) = 0;
	    s = (prec ? toFixedFix(n, prec) : '' + Math.round(n)).split('.');
	    if (s[0].length > 3) s[0] = s[0].replace(/\B(?=(?:\d{3})+(?!\d))/g, sep);
	    if ((s[1] || '').length < prec) {
	        s[1] = s[1] || '';
	        s[1] += new Array(prec - s[1].length + 1).join('0');
	    }
	    return s.join(dec);
	};
}

var $4p = { 
	globals: {},
	glob: function (name,val) {
		if ( typeof val != 'undefined') return $4p.globals[name] = val;
		if ( typeof $4p.globals[name] != 'undefined' ) 	return $4p.globals[name];
	},
	log : function (msg) {
		if (typeof console == "object") console.log(msg);
	},
	pageLock : function (unlock) { 
		if ( unlock )  $(window).unbind('beforeunload');
		else $(window).bind('beforeunload', function() { return true; });
	},
	parseInt : function (string)  { 
		return string.getInt();		
	},
	uniquId : function () {
 		if ( typeof $4p.incUniquid == 'undefined' )  { $4p.incUniquid = 1; };
 		$4p.incUniquid++; 
 		var d = new Date().getTime();
 		return d+''+$4p.incUniquid; 
 	},
	skipCache : function () {
		if ( $4p.glob('debug') > 2 ) return '?rand='+Math.random();
		return '';
 	},/*
 	tplNode: function (sel, context) {
 		var c,el = $(sel, context);
 		c = el.html();
 		$4p.log(sel);
 		el.empty();
 		el.data('tpl',$4p.tpl(c)); 		
 		el.render = function (data) {
 			el.html(el.data.tpl.render(data));
 		};
 		return el;
 	},*/
	tpl: function (tpl) { 
 		var f = {};
 		if ( typeof tpl == 'string' ) {
 			if ( tpl.substring(0,4) == 'http') { 
				$.ajax({
					  url: tpl+$4p.skipCache(),
					  dataType: 'text',
					  async: false,
					  success: function (d) { 
						f.tpl = d;	
					  }
			     });
 			}
 			else f.tpl = tpl;
 		} 		
 		else {$4p.log('unknow tpl type '+typeof tpl);return;}
		f.cache = null; 		
 		f.render = function(data) {
 			///http://www.west-wind.com/weblog/posts/509108.aspx
 		    /// <summary>
 		    /// Client side template parser that uses ~#= #~ and ~# code #~ expressions.
 		    /// and # # code blocks for template expansion.
 		    /// NOTE: chokes on single quotes in the document in some situations
 		    ///       use &amp;rsquo; for literals in text and avoid any single quote
 		    ///       attribute delimiters.
 		    /// </summary>    
 		    /// <param name="str" type="string">The text of the template to expand</param>    
 		    /// <param name="data" type="var">
 		    /// Any data that is to be merged. Pass an object and
 		    /// that object's properties are visible as variables.
 		    /// </param>    
 		    /// <returns type="string" />  
 		    var err = "", func;
 		    try {
  		        if ( typeof f.cache != 'function' ) {
 		            var strFunc = "var p=[],print=function(){p.push.apply(p,arguments);};" +
				 		            "with(obj){p.push('" +
				 		            f.tpl.replace(/[\r\t\n]/g, " ")
				 		               .replace(/'(?=[^#]*#~)/g, "\t")
				 		               .split("'").join("\\'")
				 		               .split("\t").join("'")
				 		               .replace(/~#=(.+?)#~/g, "',$1,'")
				 		               .split("~#").join("');")
				 		               .split("#~").join("p.push('")
				 		               + "');}return p.join('');";
 		           f.cache = new Function("obj", strFunc);
 		        }
 		        return f.cache(data);
 		    } catch (e) { err = e.message; }
 		    return "< # ERROR: " + err + " # >";
 		};
 		return f;
 	}, 	
	rpcWait : function (start) {
		if ( typeof this.counter == 'undefined' ) this.counter = 0;			
		if( start ) { 			
			this.counter++;
			var box = new Array(); 
			box[0] = '<div id="rpcWait" class="ui-state-highlight ui-corner-all" style="display:none;position:fixed;top:0px;right:0px;margin:6px;padding:6px;">';
			box[1] = '	<img style="vertical-align:middle;" src="'+$4p.glob('url_static_core')+'/4p/styles/img/ajax-loader.gif" />';
			box[2] = '  traitement en cours';
			box[3] = '</div>';
			$('body').append(box.join(''));
			$('#rpcWait').fadeIn(80);
		}
		else {
			this.counter = this.counter- 1;
			if(!this.counter) { 
				this.counter = 0;
				$('#rpcWait').fadeOut(900,function () { $(this).remove(); });
			} 
		}	
	},
	cssLoad : function (url,media) {
		media = ( typeof media != 'undefined' ) ? ' media="'+media+'" ' : ' media="all"  '; 		
		$("head").append($("<link rel='stylesheet' href='"+url+$4p.skipCache()+"' type='text/css' />"));
	},
	cacheScript : [],
	scriptLoad : function (url,callback) {		
		if ( typeof $4p.cacheScript[url] != 'undefined' ) {
			if ( typeof callback == 'function' ) callback();	
			return true;
		}
		return $.ajax({
			  url: url+$4p.skipCache(),
			  dataType: 'script',
			  async: false,
			  success : function (script) { 
					$4p.cacheScript[url] = 1;
					try { 
						//eval(script);
						if ( typeof callback == 'function' ) callback();	
					} catch (error) { 
						alert("scriptLoad error: "+error.message+' '+error.toSource());
					}
			  }
	     });
	 },	
	 jsonRpc : function (url) {			
			var t={};
			t.callSync = function (method,params) {	
		 		var d = new Date();
			    var id    =  d.getTime();
			    var r = { 'error': null, 'result': null, 'id': null  };		   
			    var data = {"method": method,"params": params,"id": id };	   
				$.ajax({
				   type: "POST",
				   url: url,
				   data:  data,
				   cache: false,
				   async: false,
				   dataType: "json",			
				   success:	function(resp, textStatus, XMLHttpRequest) {
					   r = resp;
				   },
				   error: function (XMLHttpRequest, textStatus, errorThrown) {
					   r =  { 'error': textStatus, 'result': null, 'id': null  };
				   }
				 });
					if ( r == null  )  r = { 'error': null, 'result': null, 'id': null  };
					else { 
						if ( typeof(r.error) == 'undefined')   r.error = null;
						if ( typeof(r.result) == 'undefined')  r.result = null;							
						if ( typeof(r.id) == 'undefined')  	   r.id = null;					
					}					
					return r;
			};			
			t.call = function (method,params) {	   
						var req = {};
						req.addCallback = function (cb) { 
					    	req.callback=cb;
					    	return req;
				    	};
				    	req.callback = null;
				    	req.data   = {
					    		method : method,
						    	params : params,
						    	id : new Date().getTime()
					    }; 
				    	req.error = req.result = req.process = null;				    	
					    req.doCallback  = function (r)  {
							if ( typeof(r.error)   == 'undefined') req.error = null;
							if ( typeof(r.result)  == 'undefined') req.result = null;							
							if ( typeof(r.id)      == 'undefined') req.id = null;						
					    	if ( typeof r.callback == 'function' ) req.callback(req);		
					    }; 
    
				    	req.process = $.ajax({
						   type: "POST",
						   url: url,
						   data:  req.data,
						   cache: false,
						   async: true,
						   dataType: "json",	
						   success:	function(r, textStatus, XMLHttpRequest) {
							   req.result = r.result;
							   req.error  = r.error;
							   req.id     = r.id;							  
							   req.doCallback(req);
						   },
						   error: function (XMLHttpRequest, textStatus, errorThrown) {
							   req.result = null;			  
							   req.error  = textStatus+': '+errorThrown;
							   req.id     = req.id;
							   req.doCallback(req);
						   } 
						});
						return req;
				};
		return t;
	},
	redirect : function (url)  { 
		var url = '<script type="text/javascript">top.location.href = \''+url+'\';</script>';
		$('body').html(url);	
	},
	levenshtein : function (a, b) {
	    if (a == b) return 0;
	    var a_len = a.length, b_len = b.length;
	    if (a_len === 0) return b_len;  
	    if (b_len === 0) return a_len;

	    var c = new Array(a_len + 1);
	    var d = new Array(a_len + 1); 
	    var s = false,a_idx = 0,b_idx = 0,cost = 0, char_a = '',char_b = '',m_min,g,h,v_tmp;
	    
	    try {s = !('0')[0];} catch (e) {split = true;}
	    if (s) {
	        a = a.split('');
	        b = b.split('');
	    }	    
	    for (a_idx = 0; a_idx < a_len + 1; a_idx++) c[a_idx] = a_idx; 
	    for (b_idx = 1; b_idx <= b_len; b_idx++) {   
	    	d[0] = b_idx;
	        char_b = b[b_idx - 1];	 
	        for (a_idx = 0; a_idx < a_len; a_idx++) {
	            char_a = a[a_idx];        
	            cost = (char_a == char_b) ? 0 : 1;
	            m_min = c[a_idx + 1] + 1;
	            g = d[a_idx] + 1;
	            h = c[a_idx] + cost;
	            if (g < m_min) m_min = g;
	            if (h < m_min) m_min = h;
	            d[a_idx + 1] = m_min;
	        }
	        v_tmp = c;
	        c = d;
	        d = v_tmp; 
	    }
	    return c[a_len];
	},

	msg : function (title,msg) {
		var d = { title : title, msg : msg };
		var r = $4p.tpl('<div title="~#= title #~"><p>~#= msg #~</p></div>').render(d);				
		$(r).dialog({
					modal: true,
					height: Math.round(screen.height*0.3),
					width:  Math.round(screen.width*0.35),					
					buttons: {
						Fermer: function() { $(this).dialog('close');  }
					},					
					close: function(event, ui) {
						$(this).dialog( "destroy" );
						$(this).remove();
					}
		});
	},
	msgPrompt : function (title,msg,data) {	
		var d = { title : title, msg : msg };
		var r = $4p.tpl('<div title="~#= title #~"><p>~#= msg #~</p><p><input type="text" /></p></div>').render(d);
		var dial = $(r).dialog({
					modal: true,
					open: function() {							
						$(this).data(data);
						if ( typeof data != 'undefined' && typeof data.value != 'undefined' ) {
							$(this).find('input').val(data.value);
						}		
					},
					buttons: {
						valider: function() {
							$(this).data('value',$(this).find('input').val());
							$(this).dialog('close');
						},
						annuler: function() {
							$(this).data('value',false);
							$(this).dialog('close');
						}						
					},
					close: function(event, ui) {
						$(this).dialog( "destroy" );						
						if ( typeof $(this).data('callback') == 'function' ) { 
							$(this).data('callback')($(this).data('value'),$(this).data());	
						}
						$(this).remove();
					}
		});
		dial.addCallback = function (cb) { 
			$(dial).data("callback", cb);
    	};
    	return dial;		
	},
	msgConfirm : function (title,msg,data) {
		var d = { title : title, msg : msg };
		var r = $4p.tpl('<div title="~#= title #~"><p>~#= msg #~</p></div>').render(d);		
		var dial = $(r).dialog({
					modal: true,
					height: Math.round(screen.height*0.3),
					width:  Math.round(screen.width*0.35),
					
					open: function() {							
						$(this).data(data);
					},
					
					buttons: {
						non: function() {
							$(this).data('value',false);
							$(this).dialog('close');
						},
						oui: function() {
					    	$(this).data('value',true);
							$(this).dialog('close');
						}
					},
					close: function(event, ui) {
						$(this).dialog( "destroy" );						
						if ( typeof $(this).data('callback') == 'function' ) { 
							$(this).data('callback')($(this).data('value'),$(this).data());	
						}
						$(this).remove();
					}
		});
		dial.addCallback = function (cb) { 
			$(dial).data("callback", cb);
    	};
    	return dial;		
	},
	msgError : function (title,msg) { 
		var d = { title : title, msg : msg };
		var s = '<div class="ui-state-error ui-corner-all" title="~#= title #~"><div style="padding: 0.8em" class="ui-state-error ui-corner-all"><p><span style="float: left; margin-right: 0.3em;" class="ui-icon ui-icon-alert"></span>~#= msg #~</p></div></div>';
		var r = $4p.tpl(s).render(d);			
		$(r).dialog({
					modal: false,
					height: Math.round(screen.height*0.3),
					width:  Math.round(screen.width*0.35),					
					buttons: {
						Fermer: function() {
							$(this).dialog('close');
						}
					},
					close: function(event, ui) {
						$(this).dialog( "destroy" );
						$(this).remove();
					}
		});
	}
};
