function trim(s){
	var l=0; var r=s.length -1;
	while(l < s.length && s[l] == ' '){
		l++;
	}
	while(r > l && s[r] == ' '){
		r-=1;
	}
	return s.substring(l, r+1);
}

//removes all null/empty elements from array
function trim_ary(ary,rekey){
	if(!rekey){
		var ret=ary;
		for(var i in ret){
			if(ret[i]=='' || !ret[i])
				ret.splice(i,1);
		}
	}else{ //rekeys the elements to be stored sequentially
		var ret=[];
		for(var i in ary){
			if(ary[i]!='' && ary[i]!==null && ary[i])
				ret.push(ary[i])
		}
	}
	
	return ret;
}

function dump(){
	var args=arguments;
	for(var i in args){
		if(!args[i]){
			args.slice(args[i],1);
		}
	}
	var separator="\n";
	var str=implode(separator,toArray(args));
	alert(str);
}

function dumpAry(){
	var str="";
	for(arg in arguments){
		str+=arg+"\n";
		for(a in arg){
			str+="\t"+a+"\n";
		}
	}
	alert(str);
}

function var_dump() {
    // Dumps a string representation of variable to output  
    // 
    // version: 906.801
    // discuss at: http://phpjs.org/functions/var_dump
    // +   original by: Brett Zamir (http://brett-zamir.me)
    // -    depends on: echo
    // *     example 1: var_dump(1);
    // *     returns 1: 'int(1)'

    var output = "", pad_char = " ", pad_val = 4, lgth = 0, i = 0, d = this.window.document;
    var getFuncName = function (fn) {
        var name = (/\W*function\s+([\w\$]+)\s*\(/).exec(fn);
        if(!name) {
            return '(Anonymous)';
        }
        return name[1];
    }

    var repeat_char = function (len, pad_char) {
        var str = "";
        for(var i=0; i < len; i++) {
            str += pad_char;
        }
        return str;
    }
    var getScalarVal = function (val) {
        var ret = '';
        if (val === null) {
            ret = 'NULL';
        }
        else if (typeof val === 'boolean') {
            ret = 'bool('+val+')';
        }
        else if (typeof val === 'string') {
            ret = 'string('+val.length+') "'+val+'"';
        }
        else if (typeof val === 'number') {
            if (parseFloat(val) == parseInt(val, 10)) {
                ret = 'int('+val+')';
            }
            else {
                ret = 'float('+val+')';
            }
        }
        else if (val === undefined) {
            ret = 'UNDEFINED'; // Not PHP behavior, but neither is undefined as value
        }
        else if (typeof val === 'function') {
//            ret = 'FUNCTION'; // Not PHP behavior, but neither is function as value
			ret = val.toString();
        }
        return ret;
    }

    var formatArray = function (obj, cur_depth, pad_val, pad_char) {
        var someProp = '';
        if (cur_depth > 0) {
            cur_depth++;
        }

        var base_pad = repeat_char(pad_val*(cur_depth-1), pad_char);
        var thick_pad = repeat_char(pad_val*(cur_depth+1), pad_char);
        var str = "";
        var val='';

        if (typeof obj === 'object' && obj !== null) {
            if (obj.constructor && getFuncName(obj.constructor) === 'PHPJS_Resource') {
                return obj.var_dump();
            }
            lgth = 0;
            for (someProp in obj) {
                lgth++;
            }
            str += "array("+lgth+") {\n";
            for (var key in obj) {
                if (typeof obj[key] === 'object' && obj[key] !== null) {
                    str += thick_pad + "["+key+"] =>\n"+thick_pad+formatArray(obj[key], cur_depth+1, pad_val, pad_char);
                } else {
                    val = getScalarVal(obj[key]);
                    str += thick_pad + "["+key+"] =>\n"+thick_pad + val + "\n";
                }
            }
            str += base_pad + "}\n";
        } else {
            str = getScalarVal(obj);
        }
        return str;
    }

    output = formatArray(arguments[0], 0, pad_val, pad_char);
    for (i=1; i < arguments.length; i++) {
        output += '\n'+formatArray(arguments[i], 0, pad_val, pad_char);
    }
    
    /*~EN: Revised to return string rather than printing */
    return output;

/*    if (d.body) {
        this.echo(output);
    }
    else {
        try {
            d = XULDocument; // We're in XUL, so appending as plain text won't work
            this.echo('<pre xmlns="http://www.w3.org/1999/xhtml" style="white-space:pre;">'+output+'</pre>');
        }
        catch(e) {
            this.echo(output); // Outputting as plain text may work in some plain XML
        }
    }*/
}

function implode(glue, pieces){
	return ((pieces instanceof Array) ? pieces.join(glue) : pieces);
}

function add_json(varName,data){
	return eval('('+data+')');
}

function toArray(args){
	return Array.prototype.slice.call(args);
}

function is_array(ary){
	return (typeof(ary)==='object' && ary!== null);
}

function is_object(o){
	return (typeof(o)==='object' && o!== null);
}

function is_string(str){
	return (typeof(str)==='string' && str!== null && str!=='');
}

function is_int(num){
	return (typeof(num)=='number' && parseInt(num)==num);
}

function includeCSS(src){
	var d=document.createElement("link");
	d.setAttribute("rel","stylesheet");
	d.setAttribute("type","text/css");
	d.setAttribute("href",src);

	var e=document.getElementsByTagName("head")[0];
	if(!e)
		return;
	e.appendChild(d);
}

function isShowing(ele){
	return (ele && ((ele.style.display.toString()!="" && ele.style.display.toString()!="none") || (ele.style.visibility.toString()!="" && ele.style.visibility.toString()!="hidden")));
}

function includeJS(src,force){
	if(!in_array(src,rtp.includedFiles) || force===true){
		var d=document.createElement("script");
		d.setAttribute("type","text/javascript");
		d.setAttribute("src",src);
	
		var e=document.getElementsByTagName("head").item(0);
		if(!e)
			return;
		e.appendChild(d);
		dump('incl',src,d);
		rtp.includedFiles.push(src);
	}
	return false;
}

function trim(s){
	var l=0; var r=s.length -1;
	while(l < s.length && s[l] == ' ')
	{	l++; }
	while(r > l && s[r] == ' ')
	{	r-=1;	}
	return s.substring(l, r+1);
}

function urlencode( str ) {
    // http://kevin.vanzonneveld.net
    // +   original by: Philip Peterson
    // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +      input by: AJ
    // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +   improved by: Brett Zamir (http://brettz9.blogspot.com)
    // +   bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +      input by: travc
    // +      input by: Brett Zamir (http://brettz9.blogspot.com)
    // +   bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // %          note 1: info on what encoding functions to use from: http://xkr.us/articles/javascript/encode-compare/
    // *     example 1: urlencode('Kevin van Zonneveld!');
    // *     returns 1: 'Kevin+van+Zonneveld%21'
    // *     example 2: urlencode('http://kevin.vanzonneveld.net/');
    // *     returns 2: 'http%3A%2F%2Fkevin.vanzonneveld.net%2F'
    // *     example 3: urlencode('http://www.google.nl/search?q=php.js&ie=utf-8&oe=utf-8&aq=t&rls=com.ubuntu:en-US:unofficial&client=firefox-a');
    // *     returns 3: 'http%3A%2F%2Fwww.google.nl%2Fsearch%3Fq%3Dphp.js%26ie%3Dutf-8%26oe%3Dutf-8%26aq%3Dt%26rls%3Dcom.ubuntu%3Aen-US%3Aunofficial%26client%3Dfirefox-a'
                             
    var histogram = {}, tmp_arr = [];
    var ret = (str+'').toString();
    
    var replacer = function(search, replace, str) {
        var tmp_arr = [];
        tmp_arr = str.split(search);
        return tmp_arr.join(replace);
    }
    
    // The histogram is identical to the one in urldecode.
    histogram["'"]   = '%27';
    histogram['(']   = '%28';
    histogram[')']   = '%29';
    histogram['*']   = '%2A';
    histogram['~']   = '%7E';
    histogram['!']   = '%21';
    histogram['%20'] = '+';
    histogram['\u20AC'] = '%80';
    histogram['\u0081'] = '%81';
    histogram['\u201A'] = '%82';
    histogram['\u0192'] = '%83';
    histogram['\u201E'] = '%84';
    histogram['\u2026'] = '%85';
    histogram['\u2020'] = '%86';
    histogram['\u2021'] = '%87';
    histogram['\u02C6'] = '%88';
    histogram['\u2030'] = '%89';
    histogram['\u0160'] = '%8A';
    histogram['\u2039'] = '%8B';
    histogram['\u0152'] = '%8C';
    histogram['\u008D'] = '%8D';
    histogram['\u017D'] = '%8E';
    histogram['\u008F'] = '%8F';
    histogram['\u0090'] = '%90';
    histogram['\u2018'] = '%91';
    histogram['\u2019'] = '%92';
    histogram['\u201C'] = '%93';
    histogram['\u201D'] = '%94';
    histogram['\u2022'] = '%95';
    histogram['\u2013'] = '%96';
    histogram['\u2014'] = '%97';
    histogram['\u02DC'] = '%98';
    histogram['\u2122'] = '%99';
    histogram['\u0161'] = '%9A';
    histogram['\u203A'] = '%9B';
    histogram['\u0153'] = '%9C';
    histogram['\u009D'] = '%9D';
    histogram['\u017E'] = '%9E';
    histogram['\u0178'] = '%9F';
    
    // Begin with encodeURIComponent, which most resembles PHP's encoding functions
    ret = encodeURIComponent(ret);
    
    for (search in histogram) {
        replace = histogram[search];
        ret = replacer(search, replace, ret) // Custom replace. No regexing
    }
    
    // Uppercase for full PHP compatibility
    return ret.replace(/(\%([a-z0-9]{2}))/g, function(full, m1, m2) {
        return "%"+m2.toUpperCase();
    });
    
    return ret;
}

function hide(id){
	var ele;
	if(typeof id === 'string'){
		if(document.getElementById(id))
			ele=document.getElementById(id);
//	alert("id: "+ele.id);
	}else if(id){ //passed an element
		ele=id;
	}
	if(ele)
		ele.style.display="none";
}

function show(id){
	var ele;
	if(typeof id === 'string'){
		if(document.getElementById(id))
			ele=document.getElementById(id);
	}else if(id){ //passed an element
		ele=id;
	}
	
	if(ele)
		ele.style.display="block";
}

function invisible(id){
	var ele;
	if(typeof id === 'string'){
		if(document.getElementById(id))
			ele=document.getElementById(id);
	}else if(id){ //passed an element
		ele=id;
	}

	if(ele)
		ele.style.visibility="hidden";
}

function visible(id){
	var ele;
	if(typeof id === 'string'){
		if(document.getElementById(id))
			ele=document.getElementById(id);
	}else if(id){ //passed an element
		ele=id;
	}

	if(ele)
		ele.style.visibility="visible";
}

function addClass(ele,name){
	if(!ele || ele.nodeType!=1)
		return;

	if(ele.className!=''){
		var parts=trim_ary(ele.className.split(' '));
		if(!in_array(name,parts))
			ele.className+=' '+name;
	}else
		ele.className=name;
	
	return ele;
}

function hasClass(ele,name){
	if(!ele || ele.nodeType!=1 || !ele.className || ele.className=='')
		return false;
	
	var cl=trim_ary(ele.className.split(' '));
	
	return in_array(name,cl);
}

function parentHasClass(ele,name){
	if(!ele || ele.nodeType!=1 || !ele.className || ele.className=='')
		return false;
	
	if(hasClass(ele,name))
		return ele;
	
	var par=ele.parentNode;
	while(par){
		if(par.className && par.className!=''){
			var cl=trim_ary(par.className.split(' '));	
			if(is_array(name)){
				for(var i in name){
					var ina=in_array(name[i],cl);
					if(ina)
						return par;				
				}
			}else{
				var cl=trim_ary(ele.className.split(' '));		
				var ina=in_array(name,cl);
				if(ina)
					return par;
			}
		}
		par=par.parentNode;
	}

	
	return false;
}

function hasSubclass(ele,name,separator){
	if(!separator)
		separator='_';
		
	if(!ele || ele.nodeType!=1 || !ele.className || ele.className=='')
		return false;
		
	var parts=ele.className.split(' ');
	for(var i in parts){
		var p=parts[i].split(separator);
		if(p[0]==name)
			return true;
	}
	return false;
}

function parentHasSubclass(ele,name,separator){
	if(!separator)
		separator='_';
		
	if(!ele || ele.nodeType!=1 || !ele.className || ele.className=='')
		return false;
	
	if(hasSubclass(ele,name))
		return ele;
	
	var par=ele.parentNode;
	while(par){
		if(par.className && par.className!=''){
			var cl=trim_ary(par.className.split(' '));	
			for(var i in cl){
				var part=cl[i].split(separator);
				if(part[0]==name)
					return par;
			}
		}
		par=par.parentNode;
	}
	
	return false;
}

function removeClass(ele,name){
	if(!ele || ele.nodeType!=1)
		return;
		
	var cl=trim_ary(ele.className.split(' '));
	for(var i in cl){
		if(name.toLowerCase()==cl[i].toLowerCase())
			cl.splice(i,1);
	}
	ele.className=cl.join(' ');
	
	return ele;
}

function getElementsByClassName(classname,node){
	if(!node)
		node=document.getElementsByTagName('body')[0];
	var a=[];
	var re=new RegExp('\\b'+classname+'\\b');
	var els=node.getElementsByTagName('*');
	var num=0;
	var classes="";
	for(var i=0,j=els.length; i<j; i++){
		if(els[i].className!='')
			classes+=els[i].className+"\n";
		if(re.test(els[i].className)){
			num++;
			a.push(els[i]);
		}
	}
	return a;
}

function in_array(needle, haystack, argStrict){
	//argStrict ~ strict comparison between elements
 
    var key = '', strict = !!argStrict;
 
    if (strict) {
        for (key in haystack) {
            if (haystack[key] === needle) {
                return true;
            }
        }
    } else {
        for (key in haystack) {
            if (haystack[key] == needle) {
                return true;
            }
        }
    }
 
    return false;
}

function defined(obj){
	return (typeof(obj)!="undefined" && obj!="undefined");
}
