////////////////////////////////////////////////////////////////////////////////
function isOpera()	{ return navigator.userAgent.toLowerCase().indexOf("opera") != -1; }
function isIE()		{ return (document.all && !isOpera()) ? true : false; }
function isIE6()	{ return (isIE() && !window.XMLHttpRequest) ? true : false; }
function isIE7()	{ return (isIE() && window.XMLHttpRequest) ? true : false; }
function isIE8()	{ return (isIE() && navigator.userAgent.toLowerCase().indexOf("msie 8") > -1); }
function isMozilla()    { return !isIE() && !isOpera() && !isWebkit(); }
function isWebkit()     { return navigator.userAgent.toLowerCase().indexOf("webkit") > -1; }

////////////////////////////////////////////////////////////////////////////////
var vbKeyBack 		= 8;
var vbKeyTab		= 9;
var vbKeyReturn 	= 13;
var vbKeyShift		= 16;
var vbKeyControl 	= 17;
var vbKeyEscape 	= 27;
var vbKeySpace		= 32;
var vbKeyPageUp 	= 33;
var vbKeyPageDown	= 34;
var vbKeyEnd 		= 35;
var vbKeyHome 		= 36;
var vbKeyLeft 		= 37;
var vbKeyUp 		= 38;
var vbKeyRight		= 39;
var vbKeyDown 		= 40;
var vbKeyInsert 	= 45;
var vbKeyDelete 	= 46;
var vbKeyA		= 65;
var vbKeyB		= 66;
var vbKeyC		= 67;
var vbKeyD		= 68;
var vbKeyE		= 69;
var vbKeyF		= 70;
var vbKeyG		= 71;
var vbKeyH		= 72;
var vbKeyI		= 73;
var vbKeyJ		= 74;
var vbKeyK		= 75;
var vbKeyL		= 76;
var vbKeyM		= 77;
var vbKeyN		= 78;
var vbKeyO		= 79;
var vbKeyP		= 80;
var vbKeyQ		= 81;
var vbKeyR		= 82;
var vbKeyS		= 83;
var vbKeyT		= 84;
var vbKeyU		= 85;
var vbKeyV		= 86;
var vbKeyW		= 87;
var vbKeyX		= 88;
var vbKeyY		= 89;
var vbKeyZ		= 90;
var vbKeyF1		= 112;
var vbKeyF2		= 113;
var vbKeyF3		= 114;
var vbKeyF4		= 115;
var vbKeyF5		= 116;
var vbKeyF6		= 117;
var vbKeyF7		= 118;
var vbKeyF8		= 119;
var vbKeyF9		= 120;
var vbKeyF10		= 121;
var vbKeyF11		= 122;
var vbKeyF12		= 123;
var vbKeyNumlock	= 144;
var vbKeyScrolllock	= 145;

////////////////////////////////////////////////////////////////////////////////
// nodeTypes vom Javascript
// Quelle: http://de.selfhtml.org/javascript/objekte/node.htm#node_type
var nodeTypes = {
    Element         :  1,   // Elementknoten
    Attribute       :  2,   // Attributknoten
    Text            :  3,   // Textknoten
    CDATA           :  4,   // Knoten fuer CDATA - Bereich
    EntityRef       :  5,   // Knoten fuer Entity-Referenz
    Entity          :  6,   // Knoten fuer Entity
    Directive       :  7,   // Knoten fuer Verarbeitungsanweisung
    Comment         :  8,   // Kommentar
    Document        :  9,   // Dokumentknoten document
    DocumentType    : 10,   // Dokumenttypknoten <= ist wohl der DOCTYPE ganz oben
    DocumentFragment: 11,   // Dokumentfragmentknoten
    Notation        : 12    // Knoten fuer Notation
};

////////////////////////////////////////////////////////////////////////////////
function CenterDialogFeatures(params) {
    var openp = params;
    var re = /width( *)=( *)(\d+)/;
    re.exec(openp);
    var w = RegExp.$3;
    var re = /height( *)=( *)(\d+)/;
    re.exec(openp);
    var h = RegExp.$3;
    if (w && h && params.indexOf("left") < 0)  {
	var left = parseInt((screen.availWidth - w) / 2);
	var top = parseInt((screen.availHeight - h) / 2);
	openp += ", left=" + left + ", top=" + top;
    }
    return openp;
}

////////////////////////////////////////////////////////////////////////////////
// params.no_reload = true:
//      Es wird versucht das Popup-Fenster nicht erneut zu laden, sondern nur in den Vordergrund zu bringen.
//      Dies wird erreicht, in dem eine leere URL an 'window.open' übergeben wird.
//      Danach wird getestet, ob eine Seiten-Location vorhanden ist. Falls nicht, wird die geforderte URL geladen.
//      Zu dem wird popupwin.opener gesetzt, da der bisherige 'opener' geschlossen worden sein könnte.
var params_per_popup = [];
function Popup(url, name, features, replace, params) {
    if (features == undefined) {
	features = "scrollbars=yes, resizable=yes, status=yes";
    }
    var features_centered = CenterDialogFeatures(features);
    var no_reload = params ? params.no_reload : false;
    try {
        var win = window.open(no_reload ? "" : url, name, features_centered, replace);
        if (no_reload) {
            if (win.location.href == "about:blank" || !win.location.href) {
                win.location.href = url;
            }
            try {
                win.opener = window;
            }
            catch (e) {
                alert("Popup (1): set-opener-win failed: " + e.description);
            }
        }
        params_per_popup.push({ popupwindow : win, params : params});

        try {
            win.focus();
        }
	catch (e) {
            alert("Popup (2): kann den Focus nicht auf Popup setzen");
        }
        return win;
    }
    catch (e) {
        alert("Popup (3): Kann Popup nicht öffnen: " + e.description + "\nurl=" + url + "\nname=" + name + "\nfeatures=" + features_centered + "\nreplace=" + replace + "\nno_reload=" + no_reload);
        return null;
    }
}

////////////////////////////////////////////////////////////////////////////////
function GetPopupParams() {
    if (window.opener && window.opener.params_per_popup) {
        for (var idx = 0; idx < window.opener.params_per_popup.length; idx++) {
            if (window.opener.params_per_popup[idx]["popupwindow"] == window) {
                //alert(Dump(window.opener.params_per_popup));
                return window.opener.params_per_popup.splice(idx, 1)[0]["params"];
            }
        }
    }
    return null;
}

////////////////////////////////////////////////////////////////////////////////
// fokusiert das nächste Element vom Typ 'tagName' ausgehend vom angegebenen 'el'
function FocusNextTab(el, tagName) {
    if (el.tabIndex) {
	var btns = document.getElementsByTagName(tagName);
	for (var idx = 0; idx < btns.length; idx++) {
	    var btn = btns[idx];
	    if (btn.tabIndex == el.tabIndex + 1) {
		btn.focus();
		break;
	    }
	}
    }
}

////////////////////////////////////////////////////////////////////////////////
function FlatProps(obj) {
    var str = "";
    for (var prop in obj)
    {
	try {
	    var value = String(obj[prop]);
	    if (value.indexOf("function") < 0)
	    {
		str += prop + " (" + typeof(obj[prop]) + ") = " + value + "\n";
	    }
	}
	catch (e) {}
    }
    alert(str);
}

////////////////////////////////////////////////////////////////////////////////
function getOffsetParent(element) {
    if (isIE()) {
	if (element.navigator) {
	    var parent = element.parent;
	    var els = [];

	    var els1 = parent.document.getElementsByTagName("IFRAME");
	    for (var idx = 0; idx < els1.length; idx++) { els.push(els1[idx]); }

	    var els2 = parent.document.getElementsByTagName("FRAME");
	    for (var idx = 0; idx < els2.length; idx++) { els.push(els2[idx]); }

	    for (var idx = 0; idx < els.length; idx++) {
		var el = els[idx];
		if (parent.frames[idx] == element) {
		    return el;
		    break;
		}
	    }
	}
       if (element.nodeName == "BODY") { return element.parentNode; }
       if (element.nodeName == "HTML") { return element.document.parentWindow; }
       return element.offsetParent;
    }
    if (isMozilla() || isOpera()) {
	if (element.navigator)	        { return element.frameElement; }
	if (element.nodeName == "BODY") { return element.parentNode; }
	if (element.nodeName == "HTML") { return element.parentNode.defaultView; }
	return element.offsetParent;
    }
    return null;
}

////////////////////////////////////////////////////////////////////////////////
function getOffsetCoords(element, onlyThisWindow) {
    var ot = 0;
    var ol = 0;
    while (element) {
	if (!isNaN(element.offsetTop)) {
	    ot = ot + element.offsetTop;
	    ol = ol + element.offsetLeft;
	}
	element = getOffsetParent(element);
	if (onlyThisWindow && element.tagName == "HTML") {
	    break;
	}
    }
    return { left: ol, top: ot };
}

////////////////////////////////////////////////////////////////////////////////
function getCSSRule(selectorText) {
    for (var i = 0; i < document.styleSheets.length; i++ ) {
	var ss = document.styleSheets[i];
	var rules = ss.rules || ss.cssRules;
	for (var y = 0; y < rules.length; y++) {
	    var sr = rules[y];
	    if (sr.selectorText == selectorText) { return sr; }
	}
    }
    return null;
}

////////////////////////////////////////////////////////////////////////////////
// sucht ein Element mit einer bestimmten id unterhalb eines containers
function getElementById(container, id) {
    if (!id) {
        id = container;
        container = document;
        return container.getElementById(id);
    }
    if (isIE()) { return container.all(id); }
    if (isMozilla()) {
        var els = container.getElementsByTagName("*");
        for (var idx = 0; idx < els.length; idx++) {
	    if (els[idx].id == id) { return els[idx]; }
	}
    }
    return null;
}

////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// Mozilla / IE - Crossbrowser-Junk
////////////////////////////////////////////////////////////////////////////////
// abbrev: document.getElementById
function gid(id) {
    return document.getElementById(id);
}

////////////////////////////////////////////////////////////////////////////////
// abbrev: document.getElementsByTagName
function gtag(tag_name) {
    return document.getElementsByTagName(tag_name);
}

////////////////////////////////////////////////////////////////////////////////
function innerText(el) {
    if (!el) 	      { return null; }
    if (isIE())       { return el.innerText; }
    if (isMozilla())  { return el.textContent; }
    return null;
}

////////////////////////////////////////////////////////////////////////////////
function setInnerText(el, txt) {
    if (isIE())       { el.innerText = txt; }
    if (isMozilla())  { el.textContent = txt; }
}

function clearKey(event) {
    if (isIE()) {
        try { event.keyCode = 0; }
        catch (e) {}
    } else {
        event.stopPropagation();
        event.preventDefault();
    }
}

// bringt dem Mozilla paar doofe IE-Funktionen bei
if (isMozilla() || isWebkit()) {
    HTMLElement.prototype.insertAdjacentElement = function(where,parsedNode) {
	switch (where.toLowerCase()) {
	    case "beforebegin":
		this.parentNode.insertBefore(parsedNode,this);
		break;
	    case "afterbegin":
		this.insertBefore(parsedNode,this.firstChild);
		break;
	    case "beforeend":
		this.appendChild(parsedNode);
		break;
	    case "afterend":
		if (this.nextSibling) {
                    this.parentNode.insertBefore(parsedNode,this.nextSibling);
                } else {
                    this.parentNode.appendChild(parsedNode);
                }
		break;
            default:
                alert("insertAdjacentElement: dont know where to put the node");
	}
    };

    HTMLElement.prototype.insertAdjacentHTML = function(where,htmlStr) {
	var r = this.ownerDocument.createRange();
	r.setStartBefore(this);
	var parsedHTML = r.createContextualFragment(htmlStr);
	this.insertAdjacentElement(where,parsedHTML)
    };

    HTMLElement.prototype.insertAdjacentText = function(where,txtStr) {
	var parsedText = document.createTextNode(txtStr);
	this.insertAdjacentElement(where,parsedText);
    };
}

////////////////////////////////////////////////////////////////////////////////
function hex_dump(str) {
    str = String(str);
    var res = "";
    for (var idx = 0; idx < str.length; idx++) { res += " " + String(str.charCodeAt(idx)); }
    return res;
}

////////////////////////////////////////////////////////////////////////////////
function SoftReload(optional_window) {
    if (!optional_window) { optional_window = window; }
    optional_window.location = optional_window.location;
}

///// for long content strings
function toggleMoreLess(img_el, imgMore, imgLess) {
   if (!img_el || !img_el.previousSibling || !img_el.previousSibling.previousSibling) { return; }
   var text_el              = img_el.previousSibling.previousSibling;
   var displ                = (!text_el.style.display);
   text_el.style.display    = displ ? "inline" : "";
   img_el.src               = displ ? imgLess : imgMore;
}

////////////////////////////////////////////////////////////////////////////////
function toggleDisplay(el) {
    if (!el || !el.style) { return null; }
    if (el.style.display) {
	el.style.display = "";
	return 1;
    }
    el.style.display = "none";
    return 0;
}

////////////////////////////////////////////////////////////////////////////////
// table_cell_element	= TD (i.d.R. das erste TD in einer Zeile
// table_row_height	= normale Zeilenhöhe (meist 18-22px)
// iframe_hieght	= Höhe des aufgeklappten IFrames
// url			= url des IFrames
// force_reload		= Relaod beim erneuten Aufklappen durchführen?
function ToggleTableDetailIFrame(table_cell_element, table_row_height, iframe_height, url, force_reload, append_iframe) {
    if (append_iframe && !table_cell_element.iframe_already_created)  {
	var iframeel = document.createElement('iframe');
	iframeel.style.width = '100%';
	iframeel.style.height = '200px';
	table_cell_element.appendChild(iframeel);
	table_cell_element.iframe_already_created = 1;
    }

    if (table_cell_element.getElementsByTagName("iframe").length > 0) {
	var iframe = table_cell_element.getElementsByTagName("iframe")[0];
	var span = iframe.parentNode;
	var hide = (span.style.display == "");
	if (!hide) { // beim Aufklappen...
	    if (url != iframe.src) {	// hat URL geändert?
		iframe.src = url;
	    } else {
		if (force_reload) { SoftReload(iframe.contentWindow); }
	    }
	}
	span.style.display = hide ? "none" : "";
	table_cell_element.style.height = hide ? table_row_height + "px" : iframe_height + "px";
    } else {
	var width = table_cell_element.parentNode.parentNode.offsetWidth; // <table>
	//var iframeHTML = "<br><span style=\"position: relative; top: 2px; width: " + width + "px; height: 400px\">";
	var iframeHTML = "<br><span style=\"position: relative; top: 2px; width: 10px; height: 10px\">";
	iframeHTML += "<iframe frameborder=\"0\" style=\"position: absolute; overflow: hidden; top: 0px; left: 0px; height: " + (iframe_height - table_row_height) + "px; width: " + (width - 0) + "px\" src=\"" + url + "\"></iframe></span>";
	table_cell_element.insertAdjacentHTML("BeforeEnd", iframeHTML);
	table_cell_element.style.height = iframe_height + "px";
    }
}

////////////////////////////////////////////////////////////////////////////////
function inArray(arr, el) {
    for (var key in arr) {
	if (arr[key] == el) {
	    return 1;
	}
    }
    return 0;
}

////////////////////////////////////////////////////////////////////////////////
function arrayIndexOf(arr, el) {
    for (var key in arr) {
	if (arr[key] == el) { return key; }
    }
    return -1;
}

/***********************************************************************
*
* Muesste eigentlich addEventHandler heissen, ist aber nun zu spaet
* Fuegt einem Event eines JS-Objekt eine Handlerfunktion hinzu,
* und laesst dabei alte Handlerfunktionen fuer das selbe Event ganz.
*
* Params **************************************************************
*
* target       Objekt, an das der Eventhandler drangehangen wird
* eventType    String, mit dem Namen des Events OHNE "on" !!!
* functionRef  Pointer auf die Funktion, die beim Eintreten des Events
*              aufgerufen wird. => Eventhandler
*              => bekommt als Parameter das Eventobjekt uebergeben
*              => Eventobjekt hat Besonderheiten, siehe Unten
*              => kann auch anonyme Funktion sein
*
* Beispiele ***********************************************************
*
* addEvent(window, 'load', function (e) { alert('Page Loaded'); });
* addEvent(document.getElementById('submitButton'), 'click', testWas);
* addEvent(document.getElementById('submitButton'), 'click', function (e) { alert(e.target.innerHTML); });
*
* Eventobjekt *********************************************************
*
* function handleMyEvent(e) => kommt als Parameter (z.B. e) in den Eventhandler
* {
*      die folgenden Sachen koennen der IE6, IE7, Opera 9, Firefox, WebKit-Browser
*      this                => Element, an dem der Eventhandler klebt
*      e.target            => Element, wo das Event auftrat (e.target != this zB bei ul und li)
*      e.clientX/Y         => Stelle des Events auf dem Bildschirm des Users
*      e.pageX/Y           => Stelle des Events in der Seite (relativ zum gesamten Dokument)
*      e.stopPropagation() => eventBubbling canceln fuer alle Browser
*      e.preventDefault()  => verhindert die normale Ausfuehrung des HTML
*                             Elements (ist wie return false; zB bei <a href> mit onclick)
* }
*/
function addEvent(target, eventType, functionRef) {
    if (!target) {
	if (window.console) {
            console.info("addEvent raised Error: no target defined!", "eventType: ", eventType, "| functionRef: ", functionRef);
        }
	return false;
    }

    // die gleiche funktion fuer das gleiche Event auf dem gleichen
    // Objekt kann nur 1x angehangen werden, jedenfalls machen das
    // opera und ff mit addEventListener
    // => zusätzlich kann man so gucken, welche eventhandler schon am
    // HTMLElement kleben
    if(!target.attachedEvents) { target.attachedEvents = new Object; }
    if(!target.attachedEvents[eventType]) { target.attachedEvents[eventType] = []; }
    for(var i=0; i<target.attachedEvents[eventType].length; i++) {
        if(target.attachedEvents[eventType][i] == functionRef) { return null; }
    }
    target.attachedEvents[eventType].push(functionRef);

    if ( target.addEventListener ) {
        target.addEventListener(eventType, functionRef, false);
    } else if ( target.attachEvent ) {
        target.attachEvent("on" + eventType, function (e) {
                //console.log('addEvent old style');
                //crossBrowserZeuch
                if(e.srcElement) { e.target = e.srcElement; }
                e.pageY = window.docEl().scrollTop + e.clientY;
                e.pageX = window.docEl().scrollLeft + e.clientX;
                e.stopPropagation = function() { e.cancelBubble = true; };
                e.preventDefault  = function() { e.returnValue = false; };
                functionRef.bind(target)(e);
                e = null; // Memory leak fix
                if (!isIE8()) { target = null; }
            }
        );
    } else {
        /* Fuer uralte browser, schwer zu testen */
        var originalHandler = target["on" + eventType];
        if ( originalHandler ) {
            target["on" + eventType] = function(e){originalHandler(e);functionRef(e);};
        } else {
            target["on" + eventType] = functionRef;
        }
    }
    return null;
}
// gehoert zu addEvent
window.docEl = function () {
    if(!window.docElSaved){window.docElSaved = (document.compatMode == 'BackCompat') ? document.body : document.documentElement; }
    return window.docElSaved;
};

////////////////////////////////////////////////////////////////////////////////
// window.pageXOffset / window.pageYOffset
// IE Kompatibilitaet zu allen anderen Browsern
// X/Y Wert wie weit gescrollt ist in px
if( isIE() ) {
    window.pageXScroll = function () {
        if( document.documentElement ) { return document.documentElement.scrollLeft; }
        return document.body.scrollLeft; // IE im Quirksmode
    }

    window.pageYScroll = function () {
        if( document.documentElement ) { return document.documentElement.scrollTop; }
        return document.body.scrollTop; // IE im Quirksmode
    }
} else {
    window.pageXScroll = function () { return window.pageXOffset; }
    window.pageYScroll = function () { return window.pageYOffset; }
}


////////////////////////////////////////////////////////////////////////////////
// holt sich alle Elemente nach dem CSS-Klassenname ran
// nicht von mir, irgendwo her kopiert
if (!document.getElementsByClassName) {
    document.getElementsByClassName = function(className, parentNode) {
        var results = [];
        if (document.evaluate) {
            var query = document.evaluate(".//*[contains(concat(' ', @class, ' '), ' " + className + " ')]", parentNode || document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
            for (var i = 0, length = query.snapshotLength; i < length; i++) { results.push(query.snapshotItem(i)); }
        }
        else {
            var nodes = (parentNode || document).getElementsByTagName("*");
            for (var i = 0, length = nodes.length; i < length; i++) {
                var nodes_i = nodes[i];
                if ((" " + nodes_i.className + " ").indexOf(" " + className + " ") > -1) {
                    results.push(nodes_i);
                }
            }
        }
        return results;
    };
} else {
    document._getElementsByClassName = document.getElementsByClassName;
    document.getElementsByClassName = function (className, parentNode) {
        if (parentNode && parentNode != document) {
            return parentNode.getElementsByClassName(className);
        }
        return document._getElementsByClassName(className);
    };
}

////////////////////////////////////////////////////////////////////////////////
// gibt alle keys in einem JSObject als Array zurück
// ähnlich dem Perlbefehl keys()
function keys(hash) {
    var arr = [];
    for(key in hash) { arr.push(key); }
    return arr;
}

////////////////////////////////////////////////////////////////////////////////
// gibt alle values in einem JSObject als Array zurück
// ähnlich dem Perlbefehl values()
function values(hash) {
    var arr = [];
    for(key in hash) { arr.push(hash[key]); }
    return arr;
}

////////////////////////////////////////////////////////////////////////////////
// gibt true zurück, falls aktuelles Fenster ein Popup ist
function i_am_a_popup() {
    return window.parent == window;
}

////////////////////////////////////////////////////////////////////////////////
//schickt die Form ab, in der das element drin ist
function submitFormForElement(el) {
    if (!el) { return; }
    while (el && el.tagName.toUpperCase() != 'FORM') { el = el.parentNode; }

    if (!el || el.tagName.toUpperCase() != 'FORM') {
        if (window.console) { console.warn('submitFormForElement raised Error: Form not found. :('); }
        return;
    }
    el.submit();
}


////////////////////////////////////////////////////////////////////////////////
// holt sich den Style, so wie das Element auf der Seite ist, ran.
// also auch Eigenschaften, die ueber CSS-Stylesheet zugewiesen wurden
// kann IE auch, nur eben anders, wird kompatibel gemacht
if (!window.getComputedStyle) {
    // man MUSS 2 parameter uebergeben, auch wenns bissel doof ist.
    // W3C fragen, warum oder was der zweite Parameter sein soll
    function getComputedStyle(el, pseudoEl)     {
        if (el.currentStyle) { return el.currentStyle; }
        if (document.defaultView.getComputedStyle) { return document.defaultView.getComputedStyle(el, ''); }
        return undef;
    }
}

////////////////////////////////////////////////////////////////////////////////
// fügt Strings trim ( führende und abschließende Spaces wegschneiden ) hinzu
String.prototype.trim = function () {
    return this.replace(/^\s+/, "").replace(/\s+$/, "");
};

////////////////////////////////////////////////////////////////////////////
function addCSSclass(el, CSSclass) {
    var elClassNames;
    if (!el) { return; }

    if (!el.className || el.className == "") {
        el.className = CSSclass;
        return;
    }

    // falls die klasse schon vorhanden ist, nicht nocheinmal hinzufügen
    if (el.className.match('(?:^|\\s)' + CSSclass + '(?:\\s|$)' )) {
        return;
    }

    el.className += " " + CSSclass;
}

////////////////////////////////////////////////////////////////////////////
function removeCSSclass(el, CSSclass) {
    if (!el || !el.className || el.className == "") { return; }

    var className = el.className;
    var rxRemoveCSSclass = new RegExp('(?:^|\\s)' + CSSclass.trim() + '(?=\\s|$)');
    className = className.replace( rxRemoveCSSclass, '' ).trim();
    el.className = className;
}

////////////////////////////////////////////////////////////////////////////////
// testet ob das el(ement) innerhalb vom containingEl(ement) liegt
function insideElement(el, containingEl) {
    if(el == containingEl) { return false; }
    while(el) {
        if(el == containingEl) { return true; }
        el = el.parentNode;
    }
    return false;
}

////////////////////////////////////////////////////////////////////////////////
// deaktiviert die Möglichkeit Text zu selektieren
function prevent_select() {
    if (isIE()) {
        window._oldonselectstart = document.body.onselectstart;
        document.body.onselectstart = function () { return false; };
    } else if (isOpera()) {
        document.body.onmousedown = function () { return false; };
    } else {
        addCSSclass(document.body, 'selectDeactivated');
    }
}

////////////////////////////////////////////////////////////////////////////////
// aktiviert die Möglichkeit Text zu selektieren
function allow_select() {
    if (isIE()) {
        if(window._oldonselectstart) {
            document.body.onselectstart = window._oldonselectstart;
        } else {
            document.body.onselectstart = null;
        }
        return;
    }

    if (isOpera()) {
        document.body.onmousedown = null;
    }

    removeCSSclass(document.body, 'selectDeactivated');
    return;
}

////////////////////////////////////////////////////////////////////////////////
// ruft die function ein einem context auf => das selbe wie context.function()
// das verändert das this in dieser function
// sehr nützlich um zB bei JS-Klassen den Klassencontext (this) zu behalten
// => siehe js/banner_editor/banner_editor.js
Function.prototype.bind = function(context) {
    var self = this;
    return function(){
        //console.log('applying');
        return self.apply(context, arguments);
    };
};

Function.prototype.extend = function(constructor, prototype) {
    var base = this;
    var Extended = function() {
        base.apply(this, arguments);
        constructor.apply(this, arguments);
    }

    Extended.implement(base.prototype);
    Extended.implement(prototype);
    return Extended;
}

Function.prototype.implement = function(proto) {
    for(var i in proto) {
        // so kann man methoden aus der Baseklasse mit BASEmethodenname aufrufen
        // ganz schoen assi, aber irgendwie gehts ni anders :(
        if (this.prototype[i]) { this.prototype['BASE' + i] = this.prototype[i]; }
        this.prototype[i] = proto[i];
    }
}


////////////////////////////////////////////////////////////////////////////////
// IE Memoryleaks vermeiden
// immer wenn man ein HTML-Element hat, welches vom DOM entfernt werden soll
// oder von dem man nur eine Referenz hat, kann das MemoryLeaks verursachen,
// deswegen am besten immer die Funktionm hier nehmen
deleteElement = function (el) {
    el.attachedEvents = '';
    if (!isIE()) {
        if (el.parentNode) { el.parentNode.removeChild(el); }
        return;
    }

    var garbageBin = document.getElementById('IELeakGarbageBin');
    if (!garbageBin) {
        garbageBin = document.createElement('DIV');
        garbageBin.id = 'IELeakGarbageBin';
        garbageBin.style.display = 'none';
        document.body.appendChild(garbageBin);
    }

    // move the element to the garbage bin
    garbageBin.appendChild(el);
    garbageBin.innerHTML = '';
}
