var batchManager = {

    cache: $H(),
    original: null,
    loading: null,
    current: null,
    
    preview: function(num, params) {
        if ((batchManager.current != params)) {
            if (batchManager.cache[params]) {
                $('main_content').innerHTML = batchManager.cache[params];
                batchManager.current = params;
                $('batch-menu').childNodes[1].innerHTML = "Preview of Page " + num;
                return;
                }
                
            if (!batchManager.loading) {
                batchManager.loading=params;
                new Ajax.Updater('main_content', './@@renderContent',
                     { 
                        asynchronous: true,
                        parameters: params,
                        onLoading: function(request) 
                                        { 
                                          $('batch-menu').childNodes[1].innerHTML = "Loading Page " + num + "...";
                                        },
                        onComplete:function(request) 
                                        { stopbusy(); 
                                          scrollToTop();
                                          batchManager.cache[params] = $('main_content').innerHTML;
                                          batchManager.current = params;
                                          batchManager.loading = null;
                                          $('batch-menu').childNodes[1].innerHTML = "Preview of Page " + num;
                                        }
                     }
                  );
                }
            }
       },
       
    hideMenu: function(event) {
        dynamichide(event);
        },

    dropMenu: function(obj, e, target){
        Event.stop(e);
        
        if (typeof dropmenuobj!="undefined") //hide previous menu
            dropmenuobj.style.visibility="hidden"
            clearhidemenu()
            if (ie5||ns6){
                obj.onmouseout=delayhidemenu;
                $('batch-menu').innerHTML = target.innerHTML;
                dropmenuobj = $('batch-menu');
                if (hidemenu_onclick) 
                    dropmenuobj.onclick=function(){dropmenuobj.style.visibility='hidden'; }
                dropmenuobj.onmouseover=clearhidemenu
                dropmenuobj.onmouseout=ie5? function(){ batchManager.hideMenu(event)} : function(event){ batchManager.hideMenu(event)}
                showhide(dropmenuobj.style, e, "visible", "hidden")
         
                dropmenuobj.x= getposOffset(obj, "left")
                dropmenuobj.y= getposOffset(obj, "top")
                dropmenuobj.style.left=dropmenuobj.x // -clearbrowseredge(obj, "rightedge")+"px" */
                dropmenuobj.style.top=dropmenuobj.y +obj.offsetHeight+"px" // -clearbrowseredge(obj, "bottomedge")+obj.offsetHeight+"px" */
                }
        return clickreturnvalue()
        }
        
}




var bebopManager = {
    
    hide_gallery: 0,
    selected_link: -1,
    processing_key: false,
    scroll_target: null,
    
    onLoad: function() {
    
        if (typeof LivePage!="undefined") {
            LivePage.startClient()
            LivePage.Responders.register(bebopManager.clientHandlers);
            }
          
        browserChecker.init();
        checkBrowser();
        windowManager.onResize();
        bebopManager.onContentUpdated();
        editManager.onLoad();
        },
        
    onContentLoading: function(topic) {
        startbusy();
        if ($(topic)) {
            $$('.selected-topic').each(function(e) {
                        e.removeClassName('selected-topic'); }
                );
            $(topic).className = 'selected-topic';
            }
        },
        
    onContentUpdated: function(topic) {        
        highlightSearchKeywords();
        stopbusy();
        
        var links = bebopManager.selectableLinks();
        var up = $('select_prev_link');
        if (up) up.className = (links) ? '' : 'disabled';
        var down = $('select_next_link');
        if (down) down.className = (links) ? '' : 'disabled';
        if ($(topic)) {
            $(topic).className = 'selected-topic';
            }
        },
        
    onUnload: function() {
        editManager.onUnload();
        if (typeof LivePage!="undefined") {
            LivePage.stopClient()
            }
        },
        
    onClose: function() {
        bebopManager.onUnload();
        },
        
    onKeyDown: function(e) {
        e = (e) ? e : ((event) ? event : null);
        if (e) {
            func = bebopManager.keyMap(e.keyCode);
            if (func) {
                Event.stop(e);
                if (!bebopManager.processing_key) {
                    bebopManager.processing_key = true;
                    setTimeout(func + "bebopManager.processing_key=false;", 200);
                    }
                }
            }
        return true;
        },
        
    onKeyPress: function(e) { bebopManager.onKeyDown(e); },
    onKeyUp: function(e) { bebopManager.onKeyDown(e); },
    
    keyMap: function(keyCode) {
        switch (keyCode) {
            case 13: return (bebopManager.selectableLinks()) ? "bebopManager.enterSelectedLink();" : false;
            case 27: return "bebopManager.escapeMode();";
            case 37: return ($('prev_page')) ? "bebopManager.showPreviousPage();" : false;
            case 38: return ($('select_prev_link') && $('select_prev_link').className != 'disabled') ? "bebopManager.chooseLink(-1);" : false;
            case 39:
            case 32:
                 return ($('next_page')) ? "bebopManager.showNextPage();" : false;
            case 40: return ($('select_next_link') && $('select_prev_link').className != 'disabled') ? "bebopManager.chooseLink(1);" : false;
            }
        return false;
        },
         
    selectView: function(key) {
        /* Safari's history doesn't recognize window.location.href assignments. 
           Therefore we use a trick: the necessary infos for a view switch are collected in a form
           and the GET request is submitted by a javascript call. */
           
        $('goto_view').value = key;
        /*alert(key + ' ' + $('goto_context').name + ':' + $('goto_context').value ) */
        document.forms['goto_form'].submit();
        },
        
    now: function() {
        var t = new Date();
        return t.getTime();
        },
 
    dynamicHideMemberInfo: function(event) {
        dynamichide(event);
        },

    dropMemberInfo: function(obj, e, target){
        Event.stop(e);
        bebopManager.showGallery();
        
        if (typeof dropmenuobj!="undefined") //hide previous menu
            dropmenuobj.style.visibility="hidden"
            clearhidemenu()
            if (ie5||ns6){
                obj.onmouseout=delayhidemenu
                dropmenuobj = target;
                if (hidemenu_onclick) 
                    dropmenuobj.onclick=function(){dropmenuobj.style.visibility='hidden'; bebopManager.resizeGallery();}
                dropmenuobj.onmouseover=clearhidemenu
                dropmenuobj.onmouseout=ie5? function(){ bebopManager.dynamicHideMemberInfo(event)} : function(event){ bebopManager.dynamicHideMemberInfo(event)}
                showhide(dropmenuobj.style, e, "visible", "hidden")
         
                dropmenuobj.x= getposOffset(obj, "left")
                dropmenuobj.y= getposOffset(obj, "top")
                dropmenuobj.style.left=dropmenuobj.x // -clearbrowseredge(obj, "rightedge")+"px" */
                dropmenuobj.style.top=dropmenuobj.y +obj.offsetHeight+"px" // -clearbrowseredge(obj, "bottomedge")+obj.offsetHeight+"px" */
                }
        return clickreturnvalue()
        },
    
    placePortrait: function(portrait, x, y) {
        var width = 30;
        if (Element.hasClassName(portrait, 'online')) {
            portrait.style.border = "solid white 2px";
            y -= 2;
            width += 2;
            }
        else {
            portrait.style.border = "solid white 0px";
            }
        portrait.style.top=y + "px";
        portrait.style.left=x + "px";
        return width;
      },
      
      
    gallery: function() {
        var portraits = new Array;
        var gallery = $('gallery');
        if (gallery) {
            for (var i = 0; i < gallery.childNodes.length; i++) {    
                var sub = gallery.childNodes[i];
                for (var j = 0; j < sub.childNodes.length; j++) {
                    var child = sub.childNodes[j];
                    if (child.className && Element.hasClassName(child, 'portrait')) {
                        portraits.push(child);
                        }
                    }
                }
            }
        return portraits;
        },
                      
    hideGallery: function() {
        bebopManager.gallery().map(Element.hide);
        },
      
    showGallery: function() {
        var gallery = $('gallery');
        if (gallery) {
            
            var show = function(value) {
                try {
                    Element.show(value);
                    }
                    catch(e) {}
                }
                
            bebopManager.gallery().map(show);
            bebopManager.hide_gallery = bebopManager.now() + 2000;
            setTimeout("bebopManager.checkGallery()", 2000);
            }
            
      },
      
    checkGallery: function() {
      if (typeof dropmenuobj!="undefined") {
            if (dropmenuobj.style.visibility=="hidden") {
                bebopManager.resizeGallery();
                }
            else {
                setTimeout("bebopManager.checkGallery()", 2000);
                }
            }
      },
      
    showDialog: function(dialog) {
        dialog = $(dialog);
        
        Element.show('overlay');
        Element.show(dialog);
        windowManager.centerElement(dialog);
     
        new Draggable(dialog);
        window.onscroll = resizeOverlay;
        },
        
    hideDialog: function(dialog) {
        Element.hide(dialog);
        Element.hide('overlay');
        },
    
    showViewMenu: function() {
        var menu = $('viewmenu');
        if (menu) {
            bebopManager.setOpacity(menu, 0.99);
            }
        },
        
    escapeMode: function() {
        bebopManager.showViewMenu();
        bebopManager.selected_link = -1;
        },

    
    setOpacity: function(element, value) {
        if (browserChecker.isSafari) {
            element.style.opacity = (value == 1 || value === '') ? '' : (value < 0.00001) ? 0 : value;
            }
        else {
            element.setOpacity(value);
            }
        },
        
    hideViewMenu: function() {
        var menu = $('viewmenu');
        if (menu) {
            bebopManager.setOpacity(menu, 0.0);
            }
        },
        
    showNextPage: function() {
        var a = $('next_page');
        if (a && a.href) window.location.href = a.href;
        return false;
        },
        
    showPreviousPage: function() {
        var a = $('prev_page');
        if (a && a.href) window.location.href = a.href;
        return false;
        },
                
    selectableLinks: function() {
        if ($('select_prev_link') || $('select_next_link')) {
            var links = new Array;
            $A($('main_content').getElementsByTagName('a')).each(function(a) {
                if (a.innerHTML) links.push(a);
                });
            if (links.length == 0) return null;
           //  if (bebopManager.selected_link == 0 && links.length == 1) return null; 
            return links;
            }
        return null;
        },
        
    chooseLink: function(incr) {
        var links = bebopManager.selectableLinks();
        if (!links) return;
        var selected = null;
        try {
            selected = links[bebopManager.selected_link];
            selected.style.color = '';         
            var icon = $('selected_link_icon');
            if (icon) icon.hide();
            }
        catch (e) { };  
         
        bebopManager.selected_link += incr;
        if (bebopManager.selected_link >= links.length) {
            bebopManager.selected_link = 0;
            }
        if (bebopManager.selected_link < 0) {
            bebopManager.selected_link = links.length-1;
            }
        try {
            selected = links[bebopManager.selected_link];
            selected.style.color = 'red';
            var offset = Position.cumulativeOffset(selected);
            var icon = $('selected_link_icon');
            if (icon) {
                var delta = icon.width/2;
                icon.show();
                icon.style.top = (offset[1] - delta + selected.offsetHeight/2) + "px";
                icon.style.left = (offset[0] + 4 + selected.offsetWidth) + "px";
                }
            var x = offset[0];
            var y = offset[1] + selected.offsetHeight;
            var size = new getPageSize();
            var scroll = new getScrollPos();
           
            window.scrollTo(scroll.scrollX, y - size.height/2);
            }
        catch (e) { alert(e.name); };  
        },
        
    enterSelectedLink: function() {
        var links = bebopManager.selectableLinks();
        
        if (links && bebopManager.selected_link > -1) {
            try {
                var a = links[bebopManager.selected_link];
                if (a.onclick) a.onclick();
                else if (a.href) window.location.href = a.href;
                }
            catch(e) {
                alert(e);
                }
            }
        },

    resizeGallery: function() {
        var gallery = $('gallery');
        if (gallery) {
            var startX = $('headline').offsetWidth;
            var startY = 2;
            var x = startX;
            var y = startY;
            
            var offset = Position.cumulativeOffset($('pictograms'));
            var max = offset[0] - 60;
            
            var portraits = bebopManager.gallery()
              
            var isOnline = function(value, index) {
                return Element.hasClassName(value, 'online')
                }
                
            var placeIt = function(value, index) {
                var posY = y;
                var deltaX = bebopManager.placePortrait(value, x, y);
                    
                if (x > max) {
                    x = startX;
                    y += 45;
                    }
                else {
                    x += deltaX;
                    }
                
                if (posY > startY) {
                    Element.hide(value);
                   }
                else {
                    Element.show(value);
                    }
                }
                 
            var partitions = portraits.partition(isOnline);
            partitions.flatten().map(placeIt);
            bebopManager.hide_gallery = 0;
            }
      },
      
    scrollStepNow: 0,
    scrollStepThen: 0,
    
    scrollToElement: function(element) {
        
        if (element) {
            bebopManager.scroll_target = element;
            }
        else {
            element = bebopManager.scroll_target;
            }
                
        var yStep = 25;                 // pixels per vertical step
        var xStep = 10;                 // pixels per horizotal step
        var tStep = 10;                 // time-step: milliseconds of timeout (increase to reduce speed)
    
        if (window.pageYOffset){                                // browser-switch:
            var yScroll = window.pageYOffset;                   // 'window.pageYOffset'
            var xScroll = window.pageXOffset;                   // works on firefox/opera/safari ...
        }
        else if (document.body && document.body.scrollTop) {    // for IE the use of
            var yScroll = document.body.scrollTop;              // 'document.body.scrolltop'
            var xScroll = document.body.scrollLeft;             // will *normally* work ...
        }
        else {
            var yScroll = 0;
            var xScroll = 0;
        }
        
    
        if (element) {
            var yDir = element.offsetTop - yScroll;
            var xDir = element.offsetLeft - xScroll;
    //        var yGrade = (yDir/Math.abs(yDir))*yStep;     // straight and smooth scrolling
    //        var xGrade = (xDir/Math.abs(xDir))*xStep;     // not as dynamic as the following one
          var yGrade = yDir/yStep;    // these definitions lead to a unproportional delay-effect
          var xGrade = xDir/xStep;    // not as linear as the foregoing ones
    
            bebopManager.scrollStepNow = yDir;
    
            if ((Math.abs(yDir)>yStep) && (bebopManager.scrollStepNow != bebopManager.scrollStepThen)) {
                window.scrollBy(xGrade, yGrade);
                bebopManager.scrollStepThen = bebopManager.scrollStepNow;
                setTimeout("bebopManager.scrollToElement(null)", tStep);
            }
            else if ((bebopManager.scrollStepNow != bebopManager.scrollStepThen)) {
                window.scrollTo(0, element.offsetTop);
                bebopManager.scrollStepThen = bebopManager.scrollStepNow;
                setTimeout("bebopManager.scrollToElement(null)", tStep);
            }
            else {
                window.scrollTo(0, element.offsetTop);
                bebopManager.scrollStepNow = null;
                bebopManager.scrollStepThen = null;
                new Effect.Highlight(element);
                bebopManager.scroll_target = null;
            }
        }
    }
    
}

bebopManager.clientHandlers = {
    /* LivePage handlers that can be extended via
       registrations to LivePage.Responders */
     
    onLogin: function(event) {
            LivePage.logging("login received " + event.who);
            
            var portrait = $('portrait.'+ event.who);
            if (portrait) {
                Element.addClassName(portrait, 'online');
                bebopManager.resizeGallery();
                }
            return;
            },
            
    onLogout: function(event) {            
            LivePage.logging("logout received " + event.who);
            var portrait = $('portrait.'+ event.who);
            if (portrait) {
                Element.removeClassName(portrait, 'online');
                bebopManager.resizeGallery();
                }
            return;
            }
}


var browserChecker = {

    init : function() {
            var ua = navigator.userAgent;
            this.isMSIE = (navigator.appName == "Microsoft Internet Explorer");
            this.isMSIE5 = this.isMSIE && (ua.indexOf('MSIE 5') != -1);
            this.isMSIE5_0 = this.isMSIE && (ua.indexOf('MSIE 5.0') != -1);
            this.isGecko = ua.indexOf('Gecko') != -1;
            this.isSafari = ua.indexOf('Safari') != -1;
            this.isOpera = ua.indexOf('Opera') != -1;
            this.isMac = ua.indexOf('Mac') != -1;
            this.isNS7 = ua.indexOf('Netscape/7') != -1;
            this.isNS71 = ua.indexOf('Netscape/7.1') != -1;
        
            // Fake MSIE on Opera and if Opera fakes IE, Gecko or Safari cancel those
            if (this.isOpera) {
                this.isMSIE = true;
                this.isGecko = false;
                this.isSafari =  false;
            }
       }
};


// ===========================================================================
// Window manager
// ===========================================================================

var windowManager = {

    editing: false,
        
    offset: function(element) {
        var offset = {}
        element = $(element)
        offset.top = element.offsetTop
        offset.left = element.offsetLeft
        while(element = element.offsetParent) {
          offset.top += element.offsetTop
          offset.left += element.offsetLeft
        }
        return offset
    },
    
    size: function(element) {
        var s = {}
        element = $(element)
        
        s.width = element.clientWidth
        s.height = element.clientHeight
        if(s.width == 0) s.width = element.scrollWidth
        if(s.height == 0) s.height = element.scrollHeight
        return s
    },
    
    innerSize: function() {
        var size = {}
        size.width = window.innerWidth || 
                       document.documentElement && document.documentElement.clientWidth ||
                       document.body.clientWidth
        size.height = window.innerHeight ||
                       document.documentElement && document.documentElement.clientHeight ||
                       document.body.clientHeight
        return size
    },
    
    last_size: {width: 0, height: 0},
    
    onResize: function() {
        bebopManager.resizeGallery();
        
        if (windowManager.editing) 
            windowManager.onResizeDuringEdit();
        else {
            var dialog = $('modal_dialog_form');
            if (dialog) {
                windowManager.centerElement(dialog);
                resizeOverlay();
                }
            }
    },
    
    onClick: function() {
        bebopManager.resizeGallery();
    },
    
    reload: function() {
        editManager.removeEditors(true);
        if (browserChecker.isSafari) {
            /*alert('Cannot reload. This is a known Safari Bug. Please click Cancel again.');*/
            window.history.back();
            }
        else {
            window.location.reload();
            }
        
    },
    
    centerElement: function(element) {
        
        var scrollPos = new getScrollPos();
        var pageSize = new getPageSize();
        var emSize = new getElementSize(element);
        var x = Math.round(pageSize.width/2) - (emSize.width /2) + scrollPos.scrollX;
        element.style.left = Math.max(x, 0) +'px';
        },    
        
    startFullPageEditing: function() {
        windowManager.last_size = {width: 0, height: 0};
        windowManager.editing = true;
        windowManager.onResizeDuringEdit();
        },
        
    stopFullPageEditing: function() {
        windowManager.editing = false;
        },
        
    onResizeDuringEdit: function() {
        /* keep track of the size from the last resize, because IE likes to call resize over and over
         * even if the window hasn't really resized. */
        
        var inner_size = windowManager.innerSize()
        
        if(inner_size.width == windowManager.last_size.width && inner_size.height == windowManager.last_size.height)
          return
      
        var fixed_height = inner_size.height;
        windowManager.last_size = inner_size
        
        var hint = $('form.hint')
        var title = $('form.title')
        var abstrakt = $('form.abstract') // $('mce_editor_0')
        
        var body_id  = 'form.body';
        
        try {
            body_id = tinyMCE.getEditorId('form.body');
            }
        catch(e) {
            }
        var body = $(body_id);
        var box   = $('main_content')     // edit_box
        var buttons = $('edit_submit_buttons')
        var comment = $('version_text')
        if ($('col')) {
            
            fixed_height = windowManager.offset('col').top +
                               windowManager.size('col').height -
                               windowManager.size(body).height + 40
            }
        
        /* Due to the shadow on the right of the box, 8 pixels should be enough
         * to compensate (and is, for Safari), but firefox seems to want 3
         * times that number and I can't determine why... */
        var width = Math.max(windowManager.size(box).width, 640)
        if(width > 0) {
            var extra = 0;
            
            try {
                if (tinyMCE) extra = 10;
                }
            catch(e) {}
            
            if (hint) hint.style.width = width + "px"
            if (title) title.style.width = width + extra + "px"
            if (abstrakt) abstrakt.style.width = width + "px"
            if (body) body.style.width = width + "px"
            if (buttons) buttons.style.width = width + extra + "px"
            if (comment) comment.style.width = width + "px"
        }
        
        if(fixed_height < inner_size.height) {
          
            var height = Math.max(inner_size.height - fixed_height, 340) + "px";
            if (body) body.style.height = height; // fixed_height + "px";
          
            try {
                if (tinyMCE) {
                    inst = tinyMCE.getInstanceById('form.body');
                    inst.body.style.height = height;
                    }
                }
            catch(e) {}
            }
     }
}


bebopManager.Updater = Class.create();
/* A special updater that animates a spinner. */

Object.extend(Object.extend(bebopManager.Updater.prototype, Ajax.Updater.prototype), {

initialize: function(container, url, options) {
    this.container = {
      success: (container.success || container),
      failure: (container.failure || (container.success ? null : container))
    }

    this.transport = Ajax.getTransport();
    this.setOptions(options);
    
    startbusy(options.busy);

    var onComplete = this.options.onComplete || Prototype.emptyFunction;
    this.options.onComplete = (function(transport, object) {
      this.updateContent();
      stopbusy(options.busy);
      highlightSearchKeywords();
      
      onComplete(transport, object);
      
    }).bind(this);

    this.request(url);
  }
 
});



bebopManager.ModalDialog = Class.create();

Object.extend(Object.extend(bebopManager.ModalDialog.prototype, bebopManager.Updater.prototype), {

initialize: function(container, url, options) {
    this.container = {
      success: (container.success || container),
      failure: (container.failure || (container.success ? null : container))
    }

    this.transport = Ajax.getTransport();
    this.setOptions(options);
    
    startbusy(options.busy);

    var onComplete = this.options.onComplete || Prototype.emptyFunction;
    this.options.onComplete = (function(transport, object) {
      this.updateContent();
      stopbusy(options.busy);
      onComplete(transport, object);
      this.afterComplete();
      
    }).bind(this);

    this.request(url);
  },
  
  afterComplete: function() {
    Element.show('modal_dialog');
    var elem = $('modal_dialog_form');
    if (!elem) {
        alert('Element with id modal_dialog_form is missing');
        }
    bebopManager.showDialog(elem);
  }
 
});

function resizeOverlay() {
    var overlay = $('overlay');
    if (overlay) {
        var docElem = document.documentElement;
        var x,y;
        var test1 = document.body.scrollHeight;
        var test2 = document.body.offsetHeight;
        if (test1 > test2) // all but Explorer Mac
        {
            x = document.body.scrollWidth;
            y = document.body.scrollHeight;
        }
        else // Explorer Mac;
             //would also work in Explorer 6 Strict, Mozilla and Safari
        {
            x = document.body.offsetWidth;
            y = document.body.offsetHeight;
        }
            
        
        overlay.style.width = x+'px';
        overlay.style.height = y+'px';
        }
};


getScrollPos = function() {
    var docElem = document.documentElement;
    this.scrollX = self.pageXOffset || (docElem&&docElem.scrollLeft) || document.body.scrollLeft;
    this.scrollY = self.pageYOffset || (docElem&&docElem.scrollTop) || document.body.scrollTop;
}

getPageSize = function() {
    var docElem = document.documentElement
    this.width = self.innerWidth || (docElem&&docElem.clientWidth) || document.body.clientWidth;
    this.height = self.innerHeight || (docElem&&docElem.clientHeight) || document.body.clientHeight;
}

getElementSize = function(elem) {
    this.width = elem.offsetWidth ||  elem.style.pixelWidth;
    this.height = elem.offsetHeight || elem.style.pixelHeight;
}
