// 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' );
		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' );
		if ( r = rgx.test(this)  ) {
			 return true;
		}
		return false;
	};
}

$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];
		}
	},
	parseInt : function (string)  { 
		var rgx = new RegExp('[0-9]+','g' );
		if ( r = rgx.exec(string)  ) {
			 return parseInt(r);
		}
		else {
			 return Number.NaN;
		}
	},
	skipCache : function () {
		//this.skipCache = 1;
		if ( $4p.glob('debug') > 2 ) { 
			return '?rand='+Math.random();
		}
		return '';
 	},
	tplLoad : function (tplUrl,data) { 
 		if ( typeof eval('this.tplCache["'+tplUrl+'"]') == "undefined"  ) {
				var r;
				$.ajax({
					  url: tplUrl+$4p.skipCache(),
					  dataType: 'text',
					  async: 0,
					  success: function (d) { 
					 	r = d;					 	
					  }
			     });
		}
 		else { 
 			r = $4p.tplCache[tplUrl];
 		}
 		return $4p.tplRender(tplUrl,r,data);
 	},
 	uniquId : function () {
 		if ( typeof $4p.incUniquid == 'undefined' )  { $4p.incUniquid = 1; };
 		$4p.incUniquid++; 
 		var d = new Date().getTime();
 		return d+''+$4p.incUniquid; 
 	},
 	
 	tplCache : {},
 	tplRender : function(tplUrl,str, 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 = "";
 		    try {
 		        var func;
 		        if ( typeof $4p.tplCache[tplUrl] != 'function' ) {
 		            var strFunc =
 		            "var p=[],print=function(){p.push.apply(p,arguments);};" +
 		                        "with(obj){p.push('" +
 		            str.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('');";

 		            //alert(strFunc);
 		            func = new Function("obj", strFunc);
 		            $4p.tplCache[tplUrl] = func;
 		        }
 		        else { 
 		        	func = $4p.tplCache[tplUrl];
 		        }
 		        return func(data);
 		    } catch (e) { err = e.message; }
 		    return "< # ERROR: " + err + " # >";
 	}, 	
	/**
	 * var callback = { success: function (ev) { o._uiWaitAction();
	 * o._uiAffiche(); }, error: function (ev,error) { alert('error: '+error); } };
	 * <form id="testl" enctype="multipart/form-data" accept-charset="utf-8">
	 * <input name="file[]" id="testla" type="file"
	 * onchange="gogane.uploadFile('testla','testl',url,callback)" /> <input
	 * type="submit" value="ok" /> </form>
	 */
	uploadFile : function (formId,url,method,data,callback) {
 			var callback;
			var d = new Date();
			var frameId = 'frame_'+d.getTime();
			// IE failed to set it after my input
			$('body').append($('<iframe src="about:blank" id="' + frameId + '" name="' + frameId + '" />').css({ height: '100px',visibility :'hidden'  }));
			if ( typeof method != 'undefined' ) {
				$('#'+formId).append('<input class="'+formId+'-method" type="hidden" name="method" value="'+method+'" />');
			}
			if ( typeof data != 'undefined' ) { 
				var x;
				for ( x in data ) { 				
					$('#'+formId).append('<input class="'+formId+'-'+x+'" type="hidden" name="params['+x+']" value="'+data[x]+'" />');
				} 
			}
			var o = this;
			$("#"+frameId).bind('load', function(ev){ 	
								var r = { 'error': null, 'result': null, 'id': null  };
								try	{
									if ( !$.browser.webkit || $(this.contentDocument).find('body').html() ) {																		
										try { 											
											var ct = $(this.contentDocument).find('body').html();
											//sanitize, remove firebug tags and others  
											ct = ct.striptags();
											r = eval('('+ct+')');											
										}catch (error) {
											r.error = "javascript error: "+error;
										}
										//document.getElementById(formId).removeAttribute('target'); 
									}
								} catch (error) {
									if (typeof console == "object") {
										r.error = 'upload error: '+error;									
									}
								}	
								
								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;
									}						
								}
								if ( typeof callback == "object" ) {	
									if (r.error && typeof callback.error == "function" ) { 	
										callback.error(ev,r);
									}
									else if ( typeof callback.success == "function") { 
										callback.success(ev,r);
									}
								}
								// fix some trouble (firefox)
							    setTimeout("$('#"+frameId+"').remove()",100);
						});  			
			// @todo verify
			document.getElementById(formId).setAttribute('target', name);// not work on opera ? 
			$('#'+formId).attr("target", frameId);// firefox doesn't want it without jquery !?
			$('#'+formId).attr("method","post"); // sometimes, it work on firefox  
			$('#'+formId).attr("enctype","multipart/form-data"); // it not work on IE7			
			$('#'+formId).attr("action", url );
			$('#'+formId).submit();
			$('#'+formId).find('[class|='+formId+']').remove();
	},
	msg : function (title,msg) {
		var id = 'dialog-msg-'+$4p.uniquId();
		var box = new Array(); 
		box[0] = '<div id="'+id+'" title="'+title+'">';
		box[1] = '		<p>'+msg+'</p>';
		box[2] = '	</div>';
		$('body').append(box.join(''));
		$('#'+id).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" );
						$('#'+id).remove();
					}
		});
	},
	msgPrompt : function (title,msg,data) {
		var id = 'dialog-prompt-'+$4p.uniquId();
		var box = new Array(); 
		box[0] = '<div id="'+id+'" title="'+title+'">';
		box[1] = '		<p>'+msg+'</p>';
		box[2] = '		<p><input type="text" /></p>';
		box[3] = '</div>';
		$('body').append(box.join(''));		
		$('#'+id).data(data);
		if ( typeof data != 'undefined' && typeof data.value != 'undefined' ) {
			$('#'+id).find('input').val($('#'+id).data('value'));
		}		
		$('#'+id).dialog({
					modal: true,
					buttons: {
						valider: function() {
							$('#'+id).data('value',$('#'+id).find('input').val());
							$(this).dialog('close');
						},
						annuler: function() {
							$('#'+id).data('value',false);
							$(this).dialog('close');
						}						
					},
					close: function(event, ui) {
						$(this).dialog( "destroy" );						
						if ( typeof $('#'+id).data('callback') == 'function' ) { 
							$('#'+id).data('callback')($('#'+id).data('value'),$('#'+id).data());	
						}
						$('#'+id).remove();
					}
		});
		this.addCallback = function (cb) { 
			$('#'+id).data("callback", cb);
    	};
    	return this;		
	},
	msgConfirm : function (title,msg,data) {
		var id = 'dialog-confirm-'+$4p.uniquId();
		var box = new Array(); 
		box[0] = '<div id="'+id+'" title="'+title+'">';
		box[1] = '		<p>'+msg+'</p>';
		box[2] = '</div>';
		$('body').append(box.join(''));
		$('#'+id).data(data);
		$('#'+id).dialog({
					modal: true,
					height: Math.round(screen.height*0.3),
					width:  Math.round(screen.width*0.35),
					buttons: {
						non: function() {
							$('#'+id).data('value',false);
							$(this).dialog('close');
						},
						oui: function() {
					    	$('#'+id).data('value',true);
							$(this).dialog('close');
						}
					},
					close: function(event, ui) {
						$(this).dialog( "destroy" );						
						if ( typeof $('#'+id).data('callback') == 'function' ) { 
							$('#'+id).data('callback')($('#'+id).data('value'),$('#'+id).data());	
						}
						$('#'+id).remove();
					}
		});
		this.addCallback = function (cb) { 
			$('#'+id).data("callback", cb);
    	};
    	return this;		
	},
	msgError : function (title,msg) { 
		var id = 'dialog-error-'+$4p.uniquId();
		var box = new Array(); 
		box[0] = '<div id="'+id+'" class="ui-state-error ui-corner-all" title="'+title+'">';
		box[1] = '	<div style="padding: 0.8em" class="ui-state-error ui-corner-all">'; 
		box[2] = '		<p><span style="float: left; margin-right: 0.3em;" class="ui-icon ui-icon-alert"></span>'+msg+'</p>';
		box[3] = '	</div>';
		box[4] = '</div>';
		$('body').append(box.join(''));
		$('#'+id).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" );
						$('#'+id).remove();
					}
		});
	},
	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_lib')+'/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' ) {
			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 o = function(url) { 
			this.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: 0,
				   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;
			};
			this.call = function (method,params) {	     
					   this.fxCallback  = function (req)  {
							if ( typeof(req.error) == 'undefined')  {
									req.error = null;
							}
							if ( typeof(req.result) == 'undefined')  {
									req.result = null;							
							}
							if ( typeof(req.id) == 'undefined')  {
									req.id = null;
							}						
					    	if ( typeof req.callback == 'function' ) { 
					    		req.callback(req);		
					    	}
					    }; 
					    
					    var request = {
					    	addCallback : function (cb) { 
						    	this.callback=cb;
						    	return this;
					    	},
					    	callback : null,
					    	method: method,
							params: params,
					 		id : new Date().getTime(),
					 		error: null,
					 		result: null,
					 		process:null
					    }; 
				    	var data = {
							"method": method,
							"params": params,
							"id": request.id
					    };
				    
				    	request.process = $.ajax({
						   type: "POST",
						   url: url,
						   data:  data,
						   request: request,
						   closure: this,
						   cache: false,
						   async: 1,
						   dataType: "json",	
						   success:	function(r, textStatus, XMLHttpRequest) {
							   request.result = r.result;
							   request.error  = r.error;
							   request.id  = r.id;							  
							   this.closure.fxCallback(request);
						   },
						   error: function (XMLHttpRequest, textStatus, errorThrown) {
							   request.result = null;			  
							   request.error  = textStatus+': '+errorThrown;
							   request.id  = request.id;
							   this.closure.fxCallback(request);
						   } 
						});
						return request;
				};
		};
		return new o(url);
	},
	redirect : function (url)  { 
		var url = '<script type="text/javascript">top.location.href = \''+url+'\';</script>';
		$('body').html(url);	
	}
};
