/*
 * Kleine Sammlung von Javascript-Funktionen für:
 * - IE-Bufixing
 * - IE-Flyout-Menüs
 * - Typeahead für Volltextsuche (benutzt AJAX)
 * Zusammengestellt von Mirko Gustony für MVS Zeppelin GmbH & Co. KG
 */

function detectBrowser() {
    var BO = new Object();
    BO["ie"] =  (document.all!=null)  && (window.opera==null);
    BO["ie4"]  =  BO["ie"] && (document.getElementById==null);
    BO["ie5"]  =   BO["ie"] && (document.namespaces==null) && (!BO["ie4"]) ;
    BO["ie6"]  =  BO["ie"] && (document.implementation!=null) && (document.implementation.hasFeature!=null);
    BO["ie7"]  =  BO["ie6"] && (window.XMLHttpRequest);
    BO["ie55"]  =  BO["ie"] && (document.namespaces!=null) && (!BO["ie6"]);
    BO["ns4"]  = !BO["ie"] &&  (document.layers !=null) &&  (window.confirm !=null) && (document.createElement ==null);
    BO["opera"] =  (self.opera!=null);
    BO["gecko"] =  (document.getBoxObjectFor!=null);
    BO["khtml"] = (navigator.vendor =="KDE");
    BO["konq"] =  ((navigator.vendor == 'KDE')||(document.childNodes)&&(!document.all)&&(!navigator.taintEnabled));
    BO["safari"] = (document.childNodes)&&(!document.all)&&(!navigator.taintEnabled)&&(!navigator.accentColorName);
    BO["safari1.2"] = (parseInt(0).toFixed==null) && (BO["safari"] && (window.XMLHttpRequest!=null));
    BO["safari2.0"] = (parseInt(0).toFixed!=null) && BO["safari"] && !BO["safari1.2"] ;
    BO["safari1.1"] = BO["safari"] && !BO["safari1.2"]  &&!BO["safari2.0"];
    return BO;
}

/*
 * EventManager
 * by Keith Gaughan
 *
 * This allows event handlers to be registered unobtrusively, and cleans
 * them up on unload to prevent memory leaks.
 *
 * Copyright (c) Keith Gaughan, 2005.
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Common Public License v1.0
 * (CPL) which accompanies this distribution, and is available at
 * http://www.opensource.org/licenses/cpl.php
 *
 * This software is covered by a modified version of the Common Public License
 * (CPL), where Keith Gaughan is the Agreement Steward, and the licensing
 * agreement is covered by the laws of the Republic of Ireland.
 */
var EventManager = {
    _registry: null,
    Initialise: function(){
        if(this._registry == null){
            this._registry = [];
            // Register the cleanup handler on page unload.
            EventManager.Add(window, "unload", this.CleanUp);
        }
    },

    /**
     * Registers an event and handler with the manager.
     *
     * @param  obj         Object handler will be attached to.
     * @param  type        Name of event handler responds to.
     * @param  fn          Handler function.
     * @param  useCapture  Use event capture. False by default.
     *                     If you don't understand this, ignore it.
     *
     * @return True if handler registered, else false.
     */
    Add: function(obj, type, fn, useCapture)
    {
        this.Initialise();

        // If a string was passed in, it's an id.
        if (typeof obj == "string")
            obj = document.getElementById(obj);
        if (obj == null || fn == null)
            return false;

        // Mozilla/W3C listeners?
        if (obj.addEventListener)
        {
            obj.addEventListener(type, fn, useCapture);
            this._registry.push({obj: obj, type: type, fn: fn, useCapture: useCapture});
            return true;
        }

        // IE-style listeners?
        if (obj.attachEvent && obj.attachEvent("on" + type, fn))
        {
            this._registry.push({obj: obj, type: type, fn: fn, useCapture: false});
            return true;
        }

        return false;
    },

    /**
     * Cleans up all the registered event handlers.
     */
    CleanUp: function()
    {
        for (var i = 0; i < EventManager._registry.length; i++)
        {
            with (EventManager._registry[i])
            {
                // Mozilla/W3C listeners?
                if (obj.removeEventListener)
                    obj.removeEventListener(type, fn, useCapture);
                // IE-style listeners?
                else if (obj.detachEvent)
                    obj.detachEvent("on" + type, fn);
            }
        }

        // Kill off the registry itself to get rid of the last remaining
        // references.
        EventManager._registry = null;
    }
};

function addEvent(target,eventName,handlerName) {
	if(!target) return;
    EventManager.Add(target,eventName,handlerName,false); // Speicherleck im IE bekämpfen
}

function translateEvent(evt) {
    var evt = (evt) ? evt : ((window.event) ? window.event : "");
    var eElement = (evt.target) ? evt.target : evt.srcElement;
    return eElement;
}

function getElementsByClassName(className, range) {
    var elts = document.getElementsByTagName(range);
    var classArray = new Array();
    for (var i = 0; i < elts.length; ++i) {
        if (elts[i].getAttribute('class') && elts[i].getAttribute('class').split(' ').inArray(className)) {
            classArray.push(elts[i]);
        } else if (elts[i].className) {
            var tempClass = elts[i].className.split(' ');
            for (var j = 0; j < tempClass.length; j++) {
                if (tempClass[j] == className) { classArray[classArray.length] = elts[i]; }
            }
        }
    }
    return classArray;
}

function findPosX(obj)
{
	var curleft = 0;
	if (obj.offsetParent)
	{
		while (obj.offsetParent)
		{
			curleft += obj.offsetLeft
			obj = obj.offsetParent;
		}
	}
	else if (obj.x)
		curleft += obj.x;
	return curleft;
}

function findPosY(obj)
{
	var curtop = 0;
	if (obj.offsetParent)
	{
		while (obj.offsetParent)
		{
			curtop += obj.offsetTop
			obj = obj.offsetParent;
		}
	}
	else if (obj.y)
		curtop += obj.y;
	return curtop;
}

function checkXMLHTTP() {
    var xmlhttp=false;
    /*@cc_on @*/
    /*@if (@_jscript_version >= 5)
    // JScript gives us Conditional compilation, we can cope with old IE versions.
    // and security blocked creation of the objects.
    try {
        xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
    } catch (e) {
        try {
            xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
        } catch (E) {
            xmlhttp = false;
        }
    }
    @end @*/
    if (!xmlhttp && typeof XMLHttpRequest!='undefined') {
        xmlhttp = new XMLHttpRequest();
    }
    return xmlhttp;
}

function fixExternalLinks() {
    var actionLinks = getElementsByClassName('extern', 'a');
    for ( var i = 0, anElement; anElement = actionLinks[i]; i++ ) {
        anElement.innerHTML = "&#187;" + anElement.innerHTML;
    }
}

function ie_content_before(el,content) {
    if(el.runtimeStyle.behavior.toLowerCase()=="none"){return;};
    el.runtimeStyle.behavior="none";
    content = content || "";
    el.insertAdjacentHTML("AfterBegin",content);
    document.getElementById('content').style.height = "1px";
}

function fixQuotes() {
    var allQ = document.getElementsByTagName('q');
    for( var i=0, anElement; anElement = allQ[i]; i++ ) {
        anElement.innerHTML = "&#8222;" + anElement.innerHTML + "#8220;";
    }
    var allCite = document.getElementsByTagName('cite');
    for( var i=0, anElement; anElement = allCite[i]; i++ ) {
        anElement.innerHTML = "&#8222;" + anElement.innerHTML + "#8220;";
    }
}

function filter( oArray, fNodeName ) {
    var rArray = new Array();
    for( var i=0, anElement; anElement = oArray[i]; i++ ) {
        if( anElement.nodeName == fNodeName && anElement.firstChild.className == 'hasSubMenu' ) rArray[rArray.length] = anElement;
    }
    return rArray;
}

function listopen(evt) {
    var eElement = translateEvent(evt);
    while( eElement.nodeName != 'LI' ) { eElement = eElement.parentNode; }
    for( var x = 0; eElement.childNodes[x]; x++ ) {
        if( eElement.childNodes[x].className == 'submenu' ) 
        {
            eElement.childNodes[x].style.visibility = 'visible';
            addEvent( eElement.childNodes[x], 'mouseover', sublistopen );
            addEvent( eElement.childNodes[x], 'mouseout', sublistclose );
        }
        if( eElement.childNodes[x].className == 'hasSubMenu' && eElement.childNodes[x].id != 'isActive' )
        { 
            eElement.childNodes[x].style.color = '#000000';
            eElement.childNodes[x].style.backgroundColor = '#000000';
            eElement.childNodes[x].style.backgroundImage = 'url(gfx/template.content.menu-flyout-bg_active.jpg)';
            eElement.childNodes[x].style.backgroundPosition = 'top right';
            eElement.childNodes[x].style.backgroundRepeat = 'no-repeat';
        }
    }
}

function listclose(evt) {
    var eElement = translateEvent(evt);
    if( eElement.nodeName != 'LI' ) eElement = eElement.parentNode;
    for( var x = 0; eElement.childNodes[x]; x++ )
    {
        if( eElement.childNodes[x].className == 'submenu' ) 
        { 
            eElement.childNodes[x].style.visibility = 'hidden';
        }
        if( eElement.childNodes[x].className == 'hasSubMenu' && eElement.childNodes[x].id != 'isActive' )
        { 
            eElement.childNodes[x].style.color = '#ffffff';
            eElement.childNodes[x].style.backgroundColor = '#990000';
            eElement.childNodes[x].style.backgroundImage = 'url(gfx/template.content.menu-flyout-bg_passive.jpg)';
            eElement.childNodes[x].style.backgroundPosition = 'top right';
            eElement.childNodes[x].style.backgroundRepeat = 'no-repeat';
        }
	}
}

function sublistopen(evt) {
    var eElement = translateEvent(evt);
    while( eElement.nodeName != 'UL' ) { eElement = eElement.parentNode; }
    eElement.style.visibility = 'visible';
    eElement.parentNode.firstChild.style.color = '#000000';
    eElement.parentNode.firstChild.style.backgroundColor = '#000000';
    eElement.parentNode.firstChild.style.backgroundImage = 'url(gfx/template.content.menu-flyout-bg_active.jpg)';
    eElement.parentNode.firstChild.style.backgroundPosition = 'top right';
    eElement.parentNode.firstChild.style.backgroundRepeat = 'no-repeat';
}

function sublistclose(evt) {
    var eElement = translateEvent(evt);
    while( eElement.nodeName != 'UL' ) { eElement = eElement.parentNode; }
    eElement.style.visibility = 'hidden';
    eElement.parentNode.firstChild.style.color = '#ffffff';
    eElement.parentNode.firstChild.style.backgroundColor = '#990000';
    eElement.parentNode.firstChild.style.backgroundImage = 'url(gfx/template.content.menu-flyout-bg_passive.jpg)';
    eElement.parentNode.firstChild.style.backgroundPosition = 'top right';
    eElement.parentNode.firstChild.style.backgroundRepeat = 'no-repeat';
}

function clearElement(elm) {
    for(var i=0, delNode; delNode = elm.childNodes[i]; i++) {
        elm.removeChild(delNode);
    }
}

function Typeahead(inputelementid,suggestboxid,serviceurl) {
    // Eigenschaften
    this.editkey = false; // Wurde die Backspace- oder Entfernen-Taste gedrückt?
    this.inputelementid = inputelementid; // Die ID des Eingabefelds, welches mit dem Typeahead versehen werden soll.
    this.inputelement = false; // Das Eingabefeld, welches mit dem Typeahead versehen werden soll.
    this.iswaitingforsuggestions = false; // Läuft gerade eine Anfrage?
    this.pressedkeycount = 0; // Wieviele Tasten wurden gedrückt?
    this.request = false; // Das XMLHTTP-Objekt.
    this.searchedtext = ""; // Nach welchem Text wurde gesucht?
    this.serviceurl = serviceurl; // Welchen URL hat das serverseitige Skript?
    this.suggestbox = false; // Die Box für die Liste der Vorschläge.
    this.suggestboxid = suggestboxid; // Die ID der Box für die Liste der Vorschläge.
    this.suggestions = new Array(); // Das Array der Vorschläge.
    this.suggestedindex = 0; // Die Position innerhalb des Arrays.
    this.suggestedtext = ""; // Der vorgeschlagene Text.
    
    // Variablen
    var My = this; // Referenz auf this.
    
    // Methoden
    this.doCompleteTypeahead = function (text) {
        if(text) My.searchedtext = text;
        if(My.searchedtext == "") return;
        My.suggestedtext = "";
    
        if(My.suggestedindex==0) {
            //search for one matching suggestion
            var newSuggestionArray = new Array();
            for(var i=0; i < My.suggestions.length; i++) { 
                if (My.suggestions[i].toLowerCase().indexOf(My.searchedtext.toLowerCase()) == 0) {
                    if(My.suggestedtext == "") My.suggestedtext = My.suggestions[i];
                    newSuggestionArray[newSuggestionArray.length] = My.suggestions[i];
                }
            }
            My.suggestions = newSuggestionArray;
        } else {
            // Navigation mit Curortasten
            My.suggestedtext = My.suggestions[My.suggestedindex-1];
        }
        if(My.suggestedtext=="") {
            // Keine übereinstimmenden Vorschläge im Array
            My.iswaitingforsuggestions = true;
            My.requestSuggestions(My.request,My.inputelementid,My.searchedtext,My.serviceurl);
        } else {
            My.iswaitingforsuggestions = false;
            if( My.pressedkeycount == 0 ) {
                var startIndex = My.searchedtext.length; 
                My.inputelement.value = My.suggestedtext;
                My.doSelectText(My.inputelement, startIndex, My.suggestedtext.length);
            }
            My.doShowSuggestList();
        }
    };
    this.doShowSuggestList = function () {
        clearElement(My.suggestbox);
        var suggestionList = document.createElement("ul");
        for (var i=0, currentIndex; currentIndex = My.suggestions[i]; i++) {
            if (currentIndex.toLowerCase().indexOf(My.searchedtext.toLowerCase()) == 0) {
                var listItem = document.createElement("li");
                if(My.suggestedindex-1 == i) {
                    if(browser["ie"]) listItem.id = "activeSuggest"; else listItem.setAttribute("id","activeSuggest"); 
                } else {
                    addEvent(listItem, 'mouseover', My.handleMouseover);
                    addEvent(listItem, 'mouseout', My.handleMouseout);
                }
                addEvent(listItem, 'click', My.handleClick);
                var listItemText = document.createTextNode(currentIndex);
                listItem.appendChild(listItemText);
                suggestionList.appendChild(listItem);
            }
            if(browser["ie"]) { listItem = null; listItemText = null; } // Memory leaks im IE bekämpfen
        }
        if(suggestionList.childNodes.length==0) {
            My.suggestbox.style.visibility = "hidden";
        } else {
            My.suggestbox.appendChild(suggestionList);
            My.suggestbox.style.visibility = "visible";
        }
        if(browser["ie"]) { suggestionList = null; } // Memory leaks im IE bekämpfen
    };
    this.doSelectText = function (elm,startIndex,nbChars) {
        if (elm.createTextRange) { // für Internet Explorer
            var txtRange = elm.createTextRange(); 
            txtRange.moveStart("character", startIndex); 
            txtRange.moveEnd("character", nbChars - elm.value.length);      
            txtRange.select();           
        } else if (elm.setSelectionRange) { // für Mozilla
            elm.setSelectionRange(startIndex, nbChars);
        }     
        elm.focus();
    };
    this.doStyleSuggestbox = function (elm,refelm) {
        if(browser["ie"]) elm.className = "suggestContainer"; else elm.setAttribute("class","suggestContainer");
        elm.style.overflow = "hidden";
        elm.style.left = findPosX(refelm) + "px";
        elm.style.top = findPosY(refelm) + refelm.offsetHeight + "px";
        if(browser["ie"]) {
            elm.style.width = (refelm.offsetWidth).toString() + "px";
        } else {
            elm.style.width = (refelm.offsetWidth-2).toString() + "px";
        }
        elm.style.visibility = "hidden";
    };
    this.handleClick = function (evt) {
        var eElement = translateEvent(evt);
        My.inputelement.value = eElement.firstChild.nodeValue;
        My.inputelement.focus();
    };
    this.handleBlur = function (evt) {
        window.setTimeout( function() { My.suggestbox.style.visibility = "hidden"; } ,500 );
    };
    this.handleKeyup = function (evt) {
        switch(evt.keyCode) {
            case 8: // Backspace wurde gedrückt
                My.searchedtext = My.inputelement.value;
                if(My.searchedtext.length>0) {
                    My.suggestedindex = 0;
                    My.iswaitingforsuggestions = true;
                    My.editkey = true;
                    My.requestSuggestions(My.request,My.inputelementid,My.searchedtext,My.serviceurl);
                } else {
                    clearElement(My.suggestbox);
                    My.suggestbox.style.visibility = "hidden";
                }
                return; // kein vollständiges Typeahead bei Backspace
            case 46: // Entfernen-Taste wurde gedrückt
                My.searchedtext = My.inputelement.value;
                My.suggestedindex = 0;
                My.iswaitingforsuggestions = true;
                My.editkey = true;
                My.requestSuggestions(My.request,My.inputelementid,My.searchedtext,My.serviceurl);
                return; // kein vollständiges Typeahead bei Entfernen-Taste
            case 40: // Cursortaste "runter" wurde gedrückt
                if(My.suggestedindex < My.suggestions.length) My.suggestedindex ++;
                My.doCompleteTypeahead();//suggest();
                evt.stopPropagation();
                evt.preventDefault();
                break;
            case 38: // Cursortaste "hoch" wurde gedrückt
                if(My.suggestedindex > 1) My.suggestedindex --;
                My.doCompleteTypeahead();
                evt.stopPropagation();
                evt.preventDefault();
                break;
            case 39: // Cursortaste "rechts" wurde gedrückt
                if(My.suggestions[My.suggestedindex-1]) My.inputelement.value = My.suggestions[My.suggestedindex-1];
                My.suggestbox.style.visibility = "hidden";
                My.inputelement.focus();
                break;
            case 9: // Tab-Taste wurde gedrückt
                if(My.suggestions[My.suggestedindex-1]) My.inputelement.value = My.suggestions[My.suggestedindex-1];
                My.suggestbox.style.visibility = "hidden";
                My.inputelement.focus();
                break;
            default:
                My.pressedkeycount--;
                if (My.searchedtext != My.inputelement.value) {
                    My.suggestedindex = 0;
                    My.searchedtext = My.inputelement.value.toLowerCase();
                    if(My.searchedtext.indexOf(" ") == -1) {
                        My.iswaitingforsuggestions = true;
                        clearElement(My.suggestbox);
                        //My.suggestbox.style.visibility = "hidden";
                        My.requestSuggestions(My.request,My.inputelementid,My.searchedtext,My.serviceurl);
                        //My.doCompleteTypeahead();
                    }
                }
        }
    };
    this.handleKeydown = function (evt) {
        if(evt.keyCode != 38 && evt.keyCode != 39 && evt.keyCode != 40 && evt.keyCode != 46 && evt.keyCode != 8 && evt.keyCode != 9) { 
            My.pressedkeycount++;
            My.editkey = false;
        }
    };
    this.handleMouseover = function (evt) {
        var eElement = translateEvent(evt);
        eElement.style.backgroundColor="Highlight";
        eElement.style.color="HighlightText";
    };
    this.handleMouseout = function (evt) {
        var eElement = translateEvent(evt);
        eElement.style.backgroundColor="Menu";
        eElement.style.color="MenuText";
    };
    this.readResponseSuggestions = function (evt) {
        if (My.request.readyState == 4) {
            if(My.request.responseText && My.request.responseText.length>0) {
                My.suggestions = My.request.responseText.split("&");
                if(My.iswaitingforsuggestions) {
                    if(My.searchedtext.length > 0 && !My.editkey) {
                        My.doCompleteTypeahead();
                    } else {
                        My.doShowSuggestList();
                    }
                }
            } else {
                My.suggestbox.style.visibility = "hidden";
            }
        }
    };
    this.requestSuggestions = function (requestobj,elmid,searchedtext,serviceurl) {
        requestobj.abort();
        requestobj.onreadystatechange = My.readResponseSuggestions;
        //addEvent(requestobj, 'readystatechange', My.readResponseSuggestions ); <- doesn't work
        requestobj.open("GET", serviceurl + "?inputid="+escape(elmid)+"&inputtxt="+escape(searchedtext), true);
        requestobj.send(null);
    };
    
    // Constructor
    this.inputelement = document.getElementById(this.inputelementid);
    this.request = checkXMLHTTP();
    if(browser["ie"]) this.inputelement.autocomplete = "OFF"; else this.inputelement.setAttribute("autocomplete","OFF"); // Browserseitige Autovervollständigung verhindern
    this.suggestbox = document.createElement("div"); // Suggestbox erzeugen
    if(browser["ie"]) this.suggestbox.id = this.suggestboxid; else this.suggestbox.setAttribute("id",this.suggestboxid);
    this.doStyleSuggestbox(this.suggestbox,this.inputelement);
    document.getElementsByTagName("body")[0].appendChild(this.suggestbox);
    addEvent(this.inputelement, 'keyup', this.handleKeyup);
    addEvent(this.inputelement, 'keydown', this.handleKeydown);
    addEvent(this.inputelement, 'blur', this.handleBlur);
}

function startupIE() {
    var myLI = filter( document.getElementById('sitecontent').firstChild.childNodes, 'LI' );
    for( var i=0, anElement; anElement = myLI[i]; i++ ) {
        if( anElement.childNodes[2] && anElement.childNodes[2].className == 'submenu' ) {
            addEvent( anElement, 'mouseover', listopen );
            addEvent( anElement, 'mouseout', listclose );
        }
    }
}

var browser = detectBrowser();

if (!Array.prototype.push) {
    Array.prototype.push = function(elem) {
        this[this.length] = elem;
    };
}
if (!Array.prototype.pop) {
    Array.prototype.pop = function() {
        var response = this[this.length - 1];
        this.length--;
        return response;
    };
}
if(checkXMLHTTP) addEvent(window, 'load', function () {
    var typeaheadpath = window.location.hostname + window.location.pathname.replace(/\/[\+%,a-zA-Z0-9-_]+\.[a-zA-Z0-9-_]+$/,"") + "/isearch2/typeahead.php";
    var volltextsuche = new Typeahead("s","suggestBox","http://" + typeaheadpath);
    if(browser["ie"]&&!browser["ie7"]) startupIE();
    if(browser["ie6"]) try{ if(!!m){ m("BackgroundImageCache", false, true) /* = IE6 only */ } }catch(oh){};
});