/**
 * This file provides common functions and methods to extend the the standard Dom functionality.
 * - DOM-Tree load control
 * - DOM extensions for "String" and "Array"
 *
 * @author Dirk Franzky
 * @copyright 2005, KP3 Medien
 **/

	/**
	 * DOM Tree load Control
	 * this function checks if the DOM-Tree of the site has load succesfully
	 *
	 * @author Dirk Franzky
	 * @copyright 2005, KP3 Medien
	 **/
	function doIfDomReady(userFunction, obj_element) {

		var int_iterator = 0;
		var int_interval = setInterval( function() {
			var boo_tree = true;
			int_iterator++;
			if(typeof document.getElementsByTagName != 'undefined' && (document.getElementsByTagName('body')[0] != null || document.body != null)) {
				boo_tree = false;
				if(typeof obj_element == 'object') {
					for(var str_element in obj_element) {
						if ( (obj_element[str_element] == 'id' && document.getElementById(str_element) == null) || (obj_element[str_element] == 'name' && document.getElementsByName(str_element) == null) || (obj_element[str_element] == 'tag' && document.getElementsByTagName(str_element).length < 1) ) {
							boo_tree = true;
							break;
						}
					}
				}

				if(!boo_tree) { userFunction(); clearInterval(int_interval); }
			}

			if(int_iterator >= 60) {
				clearInterval(int_interval);
			}

		}, 250);
	};


	/**
	 * DOM prototyp Method
	 * this function provides a method for the following functions
	 *
	 * @author Dirk Franzky
	 * @copyright 2005, KP3 Medien
	 **/
	Function.prototype.method = function (name, func) {
	    this.prototype[name] = func;
	    return this;
	};

	/**
	 * DOM Function method "inherits"
	 * this function inherit the new methods
	 *
	 * @author Dirk Franzky
	 * @copyright 2005, KP3 Medien
	 **/
	Function.method('inherits', function (parent) {
	    var d = 0, p = (this.prototype = new parent());
	    this.method('uber', function uber(name) {
	        var f, r, t = d, v = parent.prototype;
	        if (t) {
	            while (t) {
	                v = v.constructor.prototype;
	                t -= 1;
	            }
	            f = v[name];
	        } else {
	            f = p[name];
	            if (f == this[name]) {
	                f = v[name];
	            }
	        }
	        d += 1;
	        r = f.apply(this, Array.prototype.slice.apply(arguments, [1]));
	        d -= 1;
	        return r;
	    });
	    return this;
	});

	/**
	 * DOM Function method "swiss"
	 * The swiss method loops through the arguments. For each name, it copies a member from the parent's prototype to the new class's prototype
	 *
	 * @author Dirk Franzky
	 * @copyright 2005, KP3 Medien
	 **/
	Function.method('swiss', function (parent) {
	    for (var i = 1; i < arguments.length; i += 1) {
	        var name = arguments[i];
	        this.prototype[name] = parent.prototype[name];
	    }
	    return this;
	});


	/**
	 * DOM Function "isAlien"
	 *
	 * @author Dirk Franzky
	 * @copyright 2005, KP3 Medien
	 **/
	function isAlien(a) {
	   return isObject(a) && typeof a.constructor != 'function';
	}

	/**
	 * DOM Function "isArray"
	 *
	 * @author Dirk Franzky
	 * @copyright 2005, KP3 Medien
	 **/
	function isArray(a) {
	    return isObject(a) && a.constructor == Array;
	}

	/**
	 * DOM Function "isBoolean"
	 *
	 * @author Dirk Franzky
	 * @copyright 2005, KP3 Medien
	 **/
	function isBoolean(a) {
	    return typeof a == 'boolean';
	}

	/**
	 * DOM Function "isEmpty"
	 *
	 * @author Dirk Franzky
	 * @copyright 2005, KP3 Medien
	 **/
	function isEmpty(o) {
	    var i, v;
	    if (isObject(o)) {
	        for (i in o) {
	            v = o[i];
	            if (isUndefined(v) && isFunction(v)) {
	                return false;
	            }
	        }
	    }
	    return true;
	}

	/**
	 * DOM Function "isFunction"
	 *
	 * @author Dirk Franzky
	 * @copyright 2005, KP3 Medien
	 **/
	function isFunction(a) {
	    return typeof a == 'function';
	}

	/**
	 * DOM Function "isNull"
	 *
	 * @author Dirk Franzky
	 * @copyright 2005, KP3 Medien
	 **/
	function isNull(a) {
	    return typeof a == 'object' && !a;
	}

	/**
	 * DOM Function "isNumber"
	 *
	 * @author Dirk Franzky
	 * @copyright 2005, KP3 Medien
	 **/
	function isNumber(a) {
	    return typeof a == 'number' && isFinite(a);
	}

	/**
	 * DOM Function "isObject"
	 *
	 * @author Dirk Franzky
	 * @copyright 2005, KP3 Medien
	 **/
	function isObject(a) {
	    return (a && typeof a == 'object') || isFunction(a);
	}

	/**
	 * DOM Function "isString"
	 *
	 * @author Dirk Franzky
	 * @copyright 2005, KP3 Medien
	 **/
	function isString(a) {
	    return typeof a == 'string';
	}

	/**
	 * DOM Function "isUndefinied"
	 *
	 * @author Dirk Franzky
	 * @copyright 2005, KP3 Medien
	 **/
	function isUndefined(a) {
	    return typeof a == 'undefined';
	}

	/**
	 * DOM Function "isset"
	 *
	 * @author Dirk Franzky
	 * @copyright 2005, KP3 Medien
	 **/
	function isset(a){
		if (typeof a == 'undefined'){
			return false;
		} else {
			return true;
		}
	}

	/**
	 * DOM extension of object "String"
	 * The method "entityify" extends the string object with the functionality of entityifing
	 * The method "quote" extends the string object with the functionality of masking escape sequences
	 * The method "supplant" extends the string object with the functionality of supplanting string elements
	 * The method "trim" cut the whitespaces at the beginning and at the end of a string
	 *
	 * @author Dirk Franzky
	 * @copyright 2005, KP3 Medien
	 **/
	String.
	    method('entityify', function () {
				return this.replace(/&/g, "&amp;").replace(/</g,"&lt;").replace(/>/g, "&gt;");
	    }).
			method('urlencode', function (s) {
				s= s.replace(/\//g, "%2F");
				s= s.replace(/\?/g, "%3F");
				s= s.replace(/=/g, "%3D");
				s= s.replace(/&/g, "%26");
				return s;
			}).
			method('urldecode', function (s) {
				s= s.replace(/%2F/g, "/");
				s= s.replace(/%3F/g, "?");
				s= s.replace(/%3D/g, "=");
				s= s.replace(/%26/g, "&");
				return s;
			}).
	    method('quote', function () {
	        var c, i, l = this.length, o = '"';
	        for (i = 0; i < l; i += 1) {
	            c = this.charAt(i);
	            if (c >= ' ') {
	                if (c == '\\' || c == '"') {
	                    o += '\\';
	                }
	                o += c;
	            } else {
	                switch (c) {
	                case '\b':
	                    o += '\\b';
	                    break;
	                case '\f':
	                    o += '\\f';
	                    break;
	                case '\n':
	                    o += '\\n';
	                    break;
	                case '\r':
	                    o += '\\r';
	                    break;
	                case '\t':
	                    o += '\\t';
	                    break;
	                default:
	                    c = c.charCodeAt();
	                    o += '\\u00' + Math.floor(c / 16).toString(16) + (c % 16).toString(16);
	                }
	            }
	        }
	        return o + '"';
	    }).
	    method('supplant', function (o) {
	        var i, j, s = this, v;
	        for (;;) {
	            i = s.lastIndexOf('{');
	            if (i < 0) {
	                break;
	            }
	            j = s.indexOf('}', i);
	            if (i + 1 >= j) {
	                break;
	            }
	            v = o[s.substring(i + 1, j)];
	            if (!isString(v) && !isNumber(v)) {
	                break;
	            }
	            s = s.substring(0, i) + v + s.substring(j + 1);
	        }
	        return s;
	    }).
	    method('trim', function () {
	        return this.replace(/^\s*(\S*(\s+\S+)*)\s*$/, "$1");
	    });


	/**
	 * DOM extension to applay arguments to a function
	 *
	 * @author Dirk Franzky
	 * @copyright 2005, KP3 Medien
	 **/
	if (!isFunction(Function.apply)) {
	    Function.method('apply', function (o, a) {
	        var r, x = '____apply';
	        if (!isObject(o)) {
	            o = {};
	        }
	        o[x] = this;
	        switch ((a && a.length) || 0) {
	        case 0:
	            r = o[x]();
	            break;
	        case 1:
	            r = o[x](a[0]);
	            break;
	        case 2:
	            r = o[x](a[0], a[1]);
	            break;
	        case 3:
	            r = o[x](a[0], a[1], a[2]);
	            break;
	        case 4:
	            r = o[x](a[0], a[1], a[2], a[3]);
	            break;
	        case 5:
	            r = o[x](a[0], a[1], a[2], a[3], a[4]);
	            break;
	        case 6:
	            r = o[x](a[0], a[1], a[2], a[3], a[4], a[5]);
	            break;
	        default:
						if ((boo_debug) && (boo_debug == true)) {
							alert('Too many arguments to apply.');
						}
	        }
	        delete o[x];
	        return r;
	    });
	}

	/**
	 * DOM extension for "Array"
	 * This method extension of "Array" provides the "pop" functionality from PHP
	 *
	 * @author Dirk Franzky
	 * @copyright 2005, KP3 Medien
	 **/
	if (!isFunction(Array.prototype.pop)) {
	    Array.method('pop', function () {
	        return this.splice(this.length - 1, 1)[0];
	    });
	}

	/**
	 * DOM extension for "Array"
	 * This method extension of "Array" provides the "push" functionality from PHP
	 *
	 * @author Dirk Franzky
	 * @copyright 2005, KP3 Medien
	 **/
	if (!isFunction(Array.prototype.push)) {
	    Array.method('push', function () {
	        this.splice.apply(this,
	            [this.length, 0].concat(Array.prototype.slice.apply(arguments)));
	        return this.length;
	    });
	}

	/**
	 * DOM extension for "Array"
	 * This method extension of "Array" provides the "shift" functionality from PHP
	 *
	 * @author Dirk Franzky
	 * @copyright 2005, KP3 Medien
	 **/
	if (!isFunction(Array.prototype.shift)) {
	    Array.method('shift', function () {
	        return this.splice(0, 1)[0];
	    });
	}

	/**
	 * DOM extension for "Array"
	 * This method extension of "Array" provides the "splice" functionality from PHP
	 *
	 * @author Dirk Franzky
	 * @copyright 2005, KP3 Medien
	 **/
	if (!isFunction(Array.prototype.splice)) {
	    Array.method('splice', function (s, d) {
	        var max = Math.max,
	            min = Math.min,
	            a = [], // The return value array
	            e,  // element
	            i = max(arguments.length - 2, 0),   // insert count
	            k = 0,
	            l = this.length,
	            n,  // new length
	            v,  // delta
	            x;  // shift count

	        s = s || 0;
	        if (s < 0) {
	            s += l;
	        }
	        s = max(min(s, l), 0);  // start point
	        d = max(min(isNumber(d) ? d : l, l - s), 0);    // delete count
	        v = i - d;
	        n = l + v;
	        while (k < d) {
	            e = this[s + k];
	            if (!isUndefined(e)) {
	                a[k] = e;
	            }
	            k += 1;
	        }
	        x = l - s - d;
	        if (v < 0) {
	            k = s + i;
	            while (x) {
	                this[k] = this[k - v];
	                k += 1;
	                x -= 1;
	            }
	            this.length = n;
	        } else if (v > 0) {
	            k = 1;
	            while (x) {
	                this[n - k] = this[l - k];
	                k += 1;
	                x -= 1;
	            }
	        }
	        for (k = 0; k < i; ++k) {
	            this[s + k] = arguments[k + 2];
	        }
	        return a;
	    });
	}

	/**
	 * DOM extension for "Array"
	 * This method extension of "Array" provides the "unshift" functionality from PHP
	 *
	 * @author Dirk Franzky
	 * @copyright 2005, KP3 Medien
	 **/
	if (!isFunction(Array.prototype.unshift)) {
	    Array.method('unshift', function () {
	        this.splice.apply(this,
	            [0, 0].concat(Array.prototype.slice.apply(arguments)));
	        return this.length;
	    });
	}



/**
*
* Ausgabe: Der schnelle<br> braune Fuchs<br> sprang über<br> den faulen<br> Hund.
* str = 'Der schnelle braune Fuchs sprang über den faulen Hund.' + newline;
* trace(str.wordwrap(10,"<br>"));
*
* Ausgabe: Der schnel<br>le braune <br>Fuchs spra<br>ng über de<br>n faulen H<br>und.
* str = 'Der schnelle braune Fuchs sprang über den faulen Hund.';
* trace(str.wordwrap(10,"<br>",1));
*
**/
//	String.prototype.wordWrap = function(m, b, c){
//	    var i, j, s, r = this.split("\n");
//	    if(m > 0) for(i in r){
//	        for(s = r[i], r[i] = ""; s.length > m;
//	            j = c ? m : (j = s.substr(0, m).match(/\S*$/)).input.length - j[0].length
//	            || m,
//	            r[i] += s.substr(0, j) + ((s = s.substr(j)).length ? b : "")
//	        );
//	        r[i] += s;
//	    }
//	    return r.join("\n");
//	};

//String.prototype.wordwrap = function(nr,br,cut) {
//    var i, l, nr=(!nr ? 75 : nr), temp="", laenge=Math.floor(this.length/nr), br=(br==undefined ? "\n" : br);
//    for(i=0;i<laenge;i++) {
//        if((l = nr + (cut==1 ? 0 : this.substr(nr).indexOf(" "))) >= nr) {
//            temp += this.substr(0,l)+br;
//            this = this.substr(l);
//        }
//    }
//    return temp+this;
//}


//window.prototyp.alert = function(str_message){
//	alert(
//		"Debugmessage:\n"+
//		str_message
//	);
//}

function encode_utf8(rohtext) {
	// dient der Normalisierung des Zeilenumbruchs
	rohtext = rohtext.replace(/\r\n/g,"\n");
	var utftext = "";
	for(var n=0; n<rohtext.length; n++){
		// ermitteln des Unicodes des  aktuellen Zeichens
		var c=rohtext.charCodeAt(n);
		// alle Zeichen von 0-127 => 1byte
		if (c<128) {
			utftext += String.fromCharCode(c);
		}
		// alle Zeichen von 127 bis 2047 => 2byte
		else if((c>127) && (c<2048)) {
			utftext += String.fromCharCode((c>>6)|192);
			utftext += String.fromCharCode((c&63)|128);
		}
		// alle Zeichen von 2048 bis 66536 => 3byte
		else {
			utftext += String.fromCharCode((c>>12)|224);
			utftext += String.fromCharCode(((c>>6)&63)|128);
			utftext += String.fromCharCode((c&63)|128);
		}
	}
	return utftext;
}

