// Generic JS Function

function ucfirst( str ) {
 str += '';
var f = str.charAt(0).toUpperCase();
 return f + str.substr(1);
}



function array_push ( array ) {	
 // *     example 1: array_push(['kevin','van'], 'zonneveld');	
 var i, argv = arguments, argc = argv.length;

  for (i=1; i < argc; i++)
  {
     array[array.length++] = argv[i];
   }
  return array.length;
}



function is_int (mixed_var) {
 
    if (typeof mixed_var !== 'number') {
        return false;
    }
 
    if (parseFloat(mixed_var) != parseInt(mixed_var, 10)) {
        return false;
    }
    
    return true;
}


function count (mixed_var, mode) {
    // *     example 1: count([[0,0],[0,-4]], 'COUNT_RECURSIVE');
    // *     returns 1: 6
    // *     example 2: count({'one' : [1,2,3,4,5]}, 'COUNT_RECURSIVE');
    // *     returns 2: 6
 
    var key, cnt = 0;
 
    if (mixed_var === null){
        return 0;
    } else if (mixed_var.constructor !== Array && mixed_var.constructor !== Object){
        return 1;
    }
 
    if (mode === 'COUNT_RECURSIVE') {
        mode = 1;
    }
    if (mode != 1) {
        mode = 0;
    }
 
    for (key in mixed_var){
        cnt++;
        if ( mode==1 && mixed_var[key] && (mixed_var[key].constructor === Array || mixed_var[key].constructor === Object) ){
            cnt += this.count(mixed_var[key], 1);
        }
    }
 
    return cnt;
}



// FUNC STR

function str_replace (search, replace, subject, count) {
 
    var i = 0, j = 0, temp = '', repl = '', sl = 0, fl = 0,
            f = [].concat(search),
            r = [].concat(replace),
            s = subject,
            ra = r instanceof Array, sa = s instanceof Array;
    s = [].concat(s);
    if (count) {
        this.window[count] = 0;
    }
 
    for (i=0, sl=s.length; i < sl; i++) {
        if (s[i] === '') {
            continue;
        }
        for (j=0, fl=f.length; j < fl; j++) {
            temp = s[i]+'';
            repl = ra ? (r[j] !== undefined ? r[j] : '') : r[0];
            s[i] = (temp).split(f[j]).join(repl);
            if (count && s[i] !== temp) {
                this.window[count] += (temp.length-s[i].length)/f[j].length;}
        }
    }
    return sa ? s : s[0];
}


function str_ireplace ( search, replace, subject ) { // insensitive case of str_replace
   
    var i, k = '';
    var searchl = 0;
    var reg;
 
    search += '';
    searchl = search.length;
    if (!(replace instanceof Array)) {
        replace = new Array(replace);
        if (search instanceof Array) {
            // If search is an array and replace is a string,
            // then this replacement string is used for every value of search
            while (searchl > replace.length) {
                replace[replace.length] = replace[0];
            }
        }
    }
 
    if (!(search instanceof Array)) {
        search = new Array(search);
    }
    while (search.length>replace.length) {
        // If replace has fewer values than search,
        // then an empty string is used for the rest of replacement values
        replace[replace.length] = '';
    }
 
    if (subject instanceof Array) {
        // If subject is an array, then the search and replace is performed
        // with every entry of subject , and the return value is an array as well.
        for (k in subject) {
            subject[k] = str_ireplace(search, replace, subject[k]);
        }
        return subject;
    }
 
    searchl = search.length;
    for (i = 0; i < searchl; i++) {
        reg = new RegExp(search[i], 'gi');
        subject = subject.replace(reg, replace[i]);
    }
 
    return subject;
}

function stripos ( f_haystack, f_needle, f_offset ){ // pour recherche strpos 
	
    var haystack = (f_haystack+'').toLowerCase();
    var needle = (f_needle+'').toLowerCase();
    var index = 0;
 
    if ((index = haystack.indexOf(needle, f_offset)) !== -1) {
        return index;
    }
    return false;
}

	


  function boldMe(string , txt_to_bold ) // return haystack avec needle en <strong></strong>, sympa pour autocomplete par exemple 
  {
	s_pos_to_bold = stripos(string ,txt_to_bold) ;
	length_to_bold = (txt_to_bold).length  ;
	string_to_bold = string.substr(s_pos_to_bold, length_to_bold) ;							
	return  str_ireplace(string_to_bold ,'<strong>'+string_to_bold+'</strong>', string) ;	
  }
  
  
  function trim (str, charlist) {
    // http://kevin.vanzonneveld.net
    // *     example 1: trim('    Kevin van Zonneveld    ');    *     returns 1: 'Kevin van Zonneveld'
    // *     example 2: trim('Hello World', 'Hdle');   *     returns 2: 'o Wor'
    // *     example 3: trim(16, 1);   *     returns 3: 6
 
    var whitespace, l = 0, i = 0;
    str += '';
    
    if (!charlist) {
        // default list
        whitespace = " \n\r\t\f\x0b\xa0\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u200b\u2028\u2029\u3000";
    } else {
        // preg_quote custom list
        charlist += '';
        whitespace = charlist.replace(/([\[\]\(\)\.\?\/\*\{\}\+\$\^\:])/g, '$1');
    }
    
    l = str.length;
    for (i = 0; i < l; i++) {
        if (whitespace.indexOf(str.charAt(i)) === -1) {
            str = str.substring(i);
            break;
        }
    }
    
    l = str.length;
    for (i = l - 1; i >= 0; i--) {
        if (whitespace.indexOf(str.charAt(i)) === -1) {
            str = str.substring(0, i + 1);
            break;
        }
    }
    
    return whitespace.indexOf(str.charAt(0)) === -1 ? str : '';
}








function tooltip( trigger , info, callback)
{
		if(typeof(info)!='object') {info = new Object(); }
		info.ask_for =  'tooltip'  ;
		
		if(typeof(info.type)=='undefined') {info.type = 1 ; }
		if(typeof(info.decal_x)=='undefined') {info.decal_x = 0 ; }
		if(typeof(info.decal_y)=='undefined') {info.decal_y = 0 ;}
		
		if(typeof(info.arrow)=='undefined') {info.arrow = '' ; } // add here decalage arrow
		if(typeof(info.arrow_decal_x)=='undefined') {info.arrow_decal_x = '' ;   }
		if(typeof(info.arrow_decal_y)=='undefined') {info.arrow_decal_y = '' ; }
		
		if(typeof(info.id_tooltip)=='undefined') {info.id_tooltip = 'my_tooltip' ; }
		if(typeof(info.tag_tooltip)=='undefined') {info.tag_tooltip = 'tag_tooltip' ; } // un tag dans class conteneur principal , pour appliquer ou detacher des behaviors
		if(typeof(info.color)=='undefined') {info.color = 'noir' ; }
		if(typeof(info.opacity)=='undefined') {info.opacity = 0.8 ; }
		if(typeof(info.pos)=='undefined') {info.pos = 'left,top' ; }
		if(typeof(info.show)=='undefined') {info.show = true ; }
		
		
		// Text
		// note : possible de passer directement html =>  info.text="<div class='etc..'> un text ou une image</div>" ;
		if(typeof(info.text)=='undefined') {info.text = 'type your text';}
		
		// Style Text
		// value par default mergées avec user , possibilité de rajouter des class suplémentaire , 
		// ex : 	info.text_class = new Object ({'padding_left' : 'mon_padding_left' , 'padding_right' : 'mon_padding_riiiiiiight'  , 'ma_class' : 'une_class' , 'des_class' : ' maclass1 , maclass2'}) ; 
		info.text_class_default = new Object() ;
		info.text_class_default.padding_left = 'pad_left_3' ;
		info.text_class_default.padding_right = 'pad_right_3' ;
		/* info.text_class_default.padding_top = 'pad_top_2' ; */ 
		info.text_class_default.float = 'float_left' ;
		info.text_class_default.font_size = 'fs_10' ;
		info.text_class_default.color = 'gris_1_text' ;
		
		if(typeof(info.text_class)!='object') {info.text_class = new Object(); } // comparaison text_class( user ) & text_class_default => merge
		
		for(prop in  info.text_class_default) {	 if( typeof(info.text_class[prop]) == 'undefined' )  { info.text_class[prop] = info.text_class_default[prop] }	} // Objects merging
		
		var text_class = ''; 
		for(prop in  info.text_class){	text_class +=  info.text_class[prop] + ' ' ; }
		
	    info.text_class = text_class ; // string  finale de class send to  _html_stuff pour class='text_class'

		// Ajax
		var page =   '/lab/ajax/_html_stuff' ; 					
		var result = $.ajax({ type:"POST", url: page, async: false , data: info, dataType: 'html' }).responseText; 
		
		// garde en memoire objet le text de base, peut servir à modifier ponctuellement le contenu et le retablir sur une autre interaction 
		 // result.data("content",info.text );
			
		if( info.show == true  )
		{
		$('body').prepend(result) ;
	    $("#" + info.id_tooltip).hide();
		$("#" + info.id_tooltip).data("content",info.text );
		} else {
		return result ; // renvoit juste le html sans action dom, rajouter eventuellement position si necessaire 
		}
		
		
		// calcul position

		trigger =  $(trigger) ;
		
		var offset = trigger.offset() ;
		
		// var offset = $(trigger).offset() ;
		
		
		info.pos = str_replace (' ', '', info.pos)
		position = info.pos.split(',') ;
		pos_x = position[0] ; // left , right  , center
		pos_y = position[1] ; // top,  bottom , center
		
		var trigger_width = trigger.outerWidth();
		var trigger_height = trigger.outerHeight();
				
		var tooltip_width = $("#" + info.id_tooltip).width()
		var tooltip_height = $("#" + info.id_tooltip).outerHeight();
		
	// debug
	/*
	var message_calcul = 'trigger_width = ' + trigger_width +  '<br/>trigger_height = ' + trigger_height +  '<br/>tooltip_width =' + tooltip_width +  '<br/> tooltip_height = ' +  tooltip_height ;
	message_calcul += '<br/>  offset.left = ' +  offset.left +  '<br/> offset.top = ' +  offset.top ;
	*/
	
		if(pos_x == 'left')  {tooltip_pos_x =  ( offset.left  - tooltip_width - info.decal_x);}
		if(pos_x == 'right') {tooltip_pos_x =  ( offset.left  +  trigger_width + info.decal_x);}
		if(pos_x == 'center'){ tooltip_pos_x = ( offset.left + (trigger_width/2) - (tooltip_width/2) + info.decal_x );}
		
		if(pos_y == 'top') {  tooltip_pos_y = (offset.top - trigger_height - info.decal_y); }
		if(pos_y == 'bottom'){ tooltip_pos_y = (offset.top + trigger_height + info.decal_y);}
		if(pos_y == 'center'){  tooltip_pos_y = (offset.top + info.decal_y);}


		if($.browser.msie == true)
		{
		 $("#" + info.id_tooltip).css( {'position':'absolute' , 'z-index':99 , 'left':tooltip_pos_x,'top':tooltip_pos_y } ) ;
		 $("#" + info.id_tooltip).show() ;
		} else {
		 $("#" + info.id_tooltip).css( {'position':'absolute' , 'z-index':99 , 'left':tooltip_pos_x,'top':tooltip_pos_y ,'opacity':info.opacity} ) ;
		 $("#" + info.id_tooltip).fadeIn(800) ; 
		}

		if(typeof(callback)=='function') callback();
} // end function tooltip






function strlen (string) {
  
    var str = string+'';
    var i = 0, chr = '', lgth = 0; 
    if (!this.php_js || !this.php_js.ini || !this.php_js.ini['unicode.semantics'] ||
            this.php_js.ini['unicode.semantics'].local_value.toLowerCase() !== 'on') {
        return string.length;
    } 
    var getWholeChar = function (str, i) {
        var code = str.charCodeAt(i);
        var next = '', prev = '';
        if (0xD800 <= code && code <= 0xDBFF) { // High surrogate (could change last hex to 0xDB7F to treat high private surrogates as single characters)          
				  if (str.length <= (i+1))  {
                throw 'High surrogate without following low surrogate';
            }
            next = str.charCodeAt(i+1);
            if (0xDC00 > next || next > 0xDFFF) {                
						throw 'High surrogate without following low surrogate';
            }
            return str.charAt(i)+str.charAt(i+1);
        } else if (0xDC00 <= code && code <= 0xDFFF) { // Low surrogate
            if (i === 0) {                
						 throw 'Low surrogate without preceding high surrogate';
            }
            prev = str.charCodeAt(i-1);
            if (0xD800 > prev || prev > 0xDBFF) { //(could change last hex to 0xDB7F to treat high private surrogates as single characters)
                throw 'Low surrogate without preceding high surrogate';            }
            return false; // We can pass over low surrogates now as the second component in a pair which we have already processed
        }
        return str.charAt(i);
    }; 
    for (i=0, lgth=0; i < str.length; i++) {
        if ((chr = getWholeChar(str, i)) === false) {
            continue;
        } // Adapt this line at the top of any loop, passing in the whole string and the current iteration and returning a variable to represent the individual character; purpose is to treat the first part of a surrogate pair as the whole character and then ignore the second part        lgth++;
    }
    return lgth;
}

function clone(srcInstance)
  {
	  if(typeof(srcInstance) != 'object' || srcInstance == null)
	  {
		  return srcInstance;
	  }
	  /*On appel le constructeur de l'instance source pour crée une nouvelle instance de la même classe*/
	  var newInstance = srcInstance.constructor();
	  /*On parcourt les propriétés de l'objet et on les recopies dans la nouvelle instance*/
	  for(var i in srcInstance)
	  {
		  newInstance[i] = clone(srcInstance[i]);
	  }
	  /*On retourne la nouvelle instance*/
	  return newInstance;
  }
	
/*---- debug ie ----*/
/*s => subject, v => value, m => mail*/	
var console_mail = function(s,v,m){
	if(typeof m=="undefined") m="henri@telemaque.fr";
	var d = new Date(); var time = d.getHours()+':'+d.getMinutes()+':'+d.getSeconds()+':'+d.getMilliseconds();
	var datas = {subject:s+' - '+time, mail:m, value:v, action:'mail'};
	$.ajax({
		type: "POST",
		url: "/lab/ajax/_console",
		data: datas
	});
};

var console_log = function(v){
	var datas = {value:v, action:'log'};
	$.ajax({
		type: "POST",
		url: "/lab/ajax/_console",
		data: datas
	});
};

JSON.stringify = JSON.stringify || function (obj) {
		var t = typeof (obj);
		if (t != "object" || obj === null) {
				// simple data type
				if (t == "string") obj = '"'+obj+'"';
				return String(obj);
		}
		else {
				// recurse array or object
				var n, v, json = [], arr = (obj && obj.constructor == Array);
				for (n in obj) {
						v = obj[n]; t = typeof(v);
						if (t == "string") v = '"'+v+'"';
						else if (t == "object" && v !== null) v = JSON.stringify(v);
						json.push((arr ? "" : '"' + n + '":') + String(v));
				}
				return (arr ? "[" : "{") + String(json) + (arr ? "]" : "}");
		}
};

