/*
 * einbauen dass man statt obj auch string angeben kann
 *  -> shortcut auf objekt
 *  -> auch kommagetrennt mögl
 *
 * damit: jso_mainMenu, basiert aber auf jso_Box -> this.addCorners, this.addShadow !
 *        ebenfalls eben auswahlbox usw
 *        mainMenu muss die auswahlBoxen entsprechend initialisieren, mit gscheitem sPath usw
 *        eigentlich direkt /jso_mainMenu/jso_selectBox
 *
 *    -> this.addBoxCorners, this.addBoxShadow mit jsp_corner, jsp_shadow -> spans direkt einfügen oder box template
 *
 *
 * -> in jso_Box selectBox bzw. mainMenu -> jeder menüpunkt auch ein template, sodass im daten-xml wirklich nur zB
 *                          div.jso_selectBox > ul > li > [a, ul > li > [a, ...]] drin is -> siehe google wiki auswahlBox! ;)
 * -> NEIN!! html SOLL ja h1,  h2 usw enthalten -> GOOGLE!
 * -> viel wichtiger: wie menuBox, selectBox usw die Menüpunkte bearbeiten lassen?
 *    muss mit ein oder zweim ul ebenen (menuBox) und mal li h1 a, li h2 a, oder auch li a klarkommen (beide)
 *
 *
 *
 * - .jso_Box . ... CSS auf dev + zB div#content .jso_Box auf Client-Server
 * - window.aes.aOptions['Slider'], 'Box' usw, zB shadow auf def. true -> später mit ObjektPfad und überschreiben 
 *   zB /Slider/Page,/Box -> erst optionen '', dann Box, dann Page, dann Slider/Page
 *   Anfangs manuell ... oben erst Box, dann Slider/Box, Page, Slider/Page, bzw erstmal nur Box, dann Page Options
 *     -> in Page kann zB Box_shadow gesetzt werden, überschriebt Box -> Box_Shadow?
 * - li > a mit id, dann loop-tpl auf ul > li, ul > li > checkbox, label und ul > li > h1 [> a?; erstmal MIT a!]
 *
 *
 * - luzi
 *   > option: keine höhe fest setzen oder höhe auf bestimmten wert (hier: content-höhe)
 *   > option: keine corners/borders setzen
 *   > option: css für corners/borders überschreibbar? d.h. erst default setzen [oCSS.xyz], dann v. optionen überscheiben lassen
 *
 *
 */


window.jso['/defButton'] = function() {
    var that = this;
    var sColor = '';
    
  	var jsonDefButton = {
  	    'background'   : 'url(/fileadmin/img/bg_button_x.gif) 0 0 repeat-x',
  	    'position'     : 'relative',
  	    'padding'      : '0 33px 2px 12px',
  	    'display'      : 'inline-block',
  	    
  	    'text-decoration': 'none',
  	    'font-size'      : '11px',
  	    'line-height'    : '14px',
  	    'color'          : '#6E6E6E'
  	};
  	
  	this.defButton = function() {
  	    jQuery(document.createElement('img')).attr('src', 'http://www.dci.de/fileadmin/img/bg_button_left.gif').css({ 'left': 0 }).appendTo(this.jE);
  	    jQuery(document.createElement('img')).addClass('over').attr('src', 'http://www.dci.de/fileadmin/img/bg_button_right.gif').css({ 'right': 0 }).appendTo(this.jE);
  	    
  	    this.jE.addClass('jsc_defButton').mouseenter(function() {
  	        that.jE.children('img.over').attr('src', 'http://www.dci.de//fileadmin/img/bg_button_right_active.gif');
  	    }).mouseleave(function() {
  	        that.jE.children('img.over').attr('src', 'http://www.dci.de//fileadmin/img/bg_button_right.gif');
  	    });
  	    
  	    sColor = that.jE.css('color');
  	}
  	
  	
  	this.defButtonBlink = function() {
  	    //var sBold  = that.jE.css('font-weight');
  	    //if (!sBold) sBold = 'normal';
  	    
  	    //that.jE.css('font-weight', 'bold'); // Doof - bold macht den Button breiter ...
  	    
        for (var iI = 0; iI < 2; iI++) {
            that.jE.animate({ 'color': 'red' }, 200)
                   .animate({ 'color': sColor }, 50);
        }
  	}
}

window.jso['/menuBox/selectBox/IconBar/Close'] = '/IconBar';
window.jso['/menuBox/selectBox/selectBox/IconBar/Close'] = '/IconBar';
window.jso['/IconBar/Close'] = function() {
    var that = this;
    
    this.Close = function() {
        this.jE.css('cursor', 'pointer').click(function() {
            //TODO eigentlich müsste "close" als Msg gesendet werden (müssen dann eigentl. alle verstehen)
            //     damit z.B. selectBox 2. Ebene auch eine offene selectBox 3. Ebene schließt
            //     msgs show, hide, validate, update, ...?
            
            //that.callerObj().callerObj().hide({});
            that.jE.closest('div.jso_selectBox').getObj().callerObj().sendMessage('show');
            
        });
    }
}


window.jso['/Box/IconBar/Phone'] = '/IconBar';
window.jso['/IconBar/Phone'] = function() {
    var that = this;
    
    this.Phone = function() {
        // find objs
        // addExternal
        this.jE.text('');
        
        // funktion einbauen Baseclass .isContext --> getTplPath machen mit dem Context, wenn eins da --> true
        // Nach Objekten in ... wo suchen? Jedenfalls alle die .isContext('Phone') haben!!
        // Bei allen die Phone haben, mit addExternal das Phone-Icon in die IconBar
        // Evtl. Check auf Context Phone UND external IconBar?
        
        that.callerObj().callerObj().parentReady(function() {
            //TODO specially for the subtabBox here ... (.append in .each also)
            //     if this.getObj().isContext('Phone') -> get this context for display in thickbox
            that.callerObj().callerObj().jE.next('div.jso_Box').find('div.jso_subtabBox').each(function() {
                var oThis = this; 
                
                
                var jObj = jQuery(document.createElement('img')).attr('src', 'img/icon_phone.gif').click(function() {
                    alert(jQuery(window.aes.getObj(oThis).getXML()).find('.jsd_phone').text());
                });
                
                jQuery(this).find('> div > div.jst_IconBar').append(jObj);
            });
        });
    }
}


window.jso['/Box/IconBar/eMail'] = '/IconBar';
window.jso['/IconBar/eMail'] = function() {
    var that = this;
    
    this.eMail = function() {
        this.jE.text('');
        
        that.callerObj().callerObj().parentReady(function() {
            that.callerObj().callerObj().jE.next('div.jso_Box').find('div.jso_subtabBox').each(function() {
                var oThis = this; 
                var jObj  = jQuery(document.createElement('img')).attr('src', 'img/icon_mail.gif').click(function() {
                    alert(jQuery(window.aes.getObj(oThis).getXML()).find('.jsd_email').text());
                });
                
                jQuery(this).find('> div > div.jst_IconBar').append(jObj);
            });
        });
    }
}

window.jso['_ToolBar'] = '/Box'
window.jso['/ToolBar'] = function() {
    var that = this;
    
    this.ToolBar = function() {
        this.initializeNextChildren();
        
        this.initBox(undefined, 'ToolBar');
    }
}

window.jso['/ToolBar/Sort'] = function() {
    var that = this;
    
    //TODO: div.jsc_Sort --> div generiert select, label usw?
    //      oder andersrum: ist ein select, JS baut das JS drum?
    //      in meta angeben nach was gefiltert/sortiert werden soll?
    
    this.Sort = function() {
        that.jE.addClass('jsc_Sort');
        
        that.jE.change(this.execSort);
    }
    
    this.execSort = function() {
        var aVal = that.jE.val().split(',');
        
        if (aVal[0].length) {
            var jElems = new Object();
            var aElems = new Array();
            var iI     = 0; // for an unique id
            
            var numSort = function(a, b) {
                // Workaround - das "__-__" wird für ID gebraucht, bei sortierung aber raus!
                a = parseFloat(a.substr(0, a.indexOf('__-__')));
                b = parseFloat(b.substr(0, b.indexOf('__-__')));
                
                return a - b;
            }
            
            that.callerObj().jE.nextAll('div.jso_subtabBox').each(function() {
                var jE   = jQuery(this);
                var sVal = jE.getObj().getJSDs()[aVal[0]];
                
                if (aVal[2] == 'num') sVal = parseFloat(sVal);
                
                jElems[sVal + '__-__' + ++iI] = jE;
                aElems.push(sVal + '__-__' + iI);
            });
            
            if (aVal[2] == 'num') aElems.sort(numSort);
            else                  aElems.sort();
            
            // Eingefügt wird "falsch rum", d.h. wenn NICHT desc -> umdrehen!
            if (aVal[1] != 'desc') aElems.reverse();
            
            for (var iI in aElems) that.callerObj().jE.after(jElems[aElems[iI]]);
        }
    }
}
window.jso['/ToolBar/Filter'] = function() {
    var that    = this;
    var bRadios = false;
    var iShown  = 0;
    
    // Template as a string, then jQueried!
    var sNot = this.getTpl('', '', true);
    var jNot = sNot ? jQuery(sNot) : undefined;
    
    this.Filter = function() {
        that.jE.addClass('jsc_Filter');
        
        bRadios = that.jE.children('input').length ? true : false;
        
        if (bRadios) {
            that.jE.children('input:first').click();
            
            that.jE.children('input').click(this.execFilter);
        }
        else that.jE.change(this.execFilter);
        
        //alert(this.getTpl('', '', true));
        //this.getTpl('', '', true)
        
        //TODO immer in ToolBar drin? ToolBar immer direkt über Liste?
        if (jNot) {
            this.initializeElements(jNot);
            //that.callerObj().jE.after(jNot);
            that.callerObj().jE.nextAll('.jso_ToolBar').before(jNot);
        }
        
        //TODO check ob inputs oder select/options!
        that.callerObj().parentReady(function() {
            var jCurr = that.jE.children('input:first');
            
            that.execFilter('plain');
            
            while ((iShown == 0) && jCurr.length) {
                jCurr = jCurr.attr('checked', '').nextAll('input:first').attr('checked', 'checked');//.click();
                
                that.execFilter('plain');
            }
            
            if (iShown == 0) {
            	that.jE.children('input:first').attr('checked', 'checked');
                that.execFilter('plain');
            }
        });
    }
    
    this.execFilter = function(sType) { //, bShow) {
        if (typeof sType != 'string') sType = 'slide';
        if (jQuery.browser.msie)      sType = 'plain';
        
        //if (jNot) jNot.hide();
        
        //sType = 'plain';
        //if (typeof bShow != 'boolean') bSHow = 'slide';
        var sMasterVal = undefined;
        var sName      = undefined;
        
        if (that.jE.children('input').length) {
            sMasterVal = that.jE.children('input:checked').attr('value');
            sName      = that.jE.children('input:first').attr('name');
        }      
        else {
            sMasterVal = that.jE.val();
            sName      = that.jE.attr('name');
        }
        
        if (!sMasterVal) sMasterVal = '';
        
        if (sMasterVal.length) {
            iShown = 0;
            
            sMasterVal = parseInt(sMasterVal);
            
            //TODO über metadata angeben!
            //     irgendwie von einem Root ausgehen o.ä.?
            //     Oder einfach jeder subtabBox ne klasse xyz, bzw. nem Container außen rum ne Klasse geben?
            //     Dann evtl. auch den Tickern ne Klasse geben, und einfach ".klasse:first" abfragen
            //
            //     -> jedenfalls am Anfang die Abfrage eval'en, dann speichern ... denk ich ...
            //
            //alert(that.callerObj().jE.nextAll('div.jso_subtabBox').length);
            that.callerObj().jE.nextAll('div.jso_subtabBox').find('> div.jsc_Box-Inner > div.jso_slideContainer > div.jso_Slide:eq(1) > div.jso_verttabBox > div.jso_slideContainer > div.jso_Slide').each(function() {
                var jE   = jQuery(this);
                var oP   = jE.closest('div.jso_subtabBox').getObj();
                
                //Workaround - Object isn't initialized yet, for speed reasons ...
                //TODO         WRITE function jQuery().getJSDs - if .getObj, .getObj().getJSDs, else find(.jsd_)
                //20091214 - PASST erstmal ...
                var oParams = new Object();
                if (jE.getObj()) oParams = jE.getObj().getJSDs();
                else             oParams[sName] = jE.find('.jsd_' + sName).text();
                
                var sVal = oParams[sName] ? parseInt(oParams[sName]) : parseInt(oP.getJSDs()[sName]);
                
                
                var oFilter = oP.jE.data('Filter');
                
                if (!oFilter) oFilter = new Object();
                oFilter[sName] = (sMasterVal == sVal) ? true : false;
                
                var bShow = true;
                for (var sI in oFilter) if (oFilter[sI] === false) bShow = false;
                
                if (bShow) {
                    oP.show({ 'sType': sType });
                    iShown++;
                }
                else oP.hide({ 'sType': sType });
                
                oP.jE.data('Filter', oFilter);
            });
            
            // Filter_Show eigenes JSO? Wie mitkriegen dass was geupdated wurde? domManip überwachen o.ä.?
            that.callerObj().jE.find('.jso_Filter_Show').text(iShown);
            
            that.sendMessage('filter', sMasterVal);
            
            //if (iShown == 0) if (jNot) ((sType == 'plain') ? jNot.show() : jNot.slideDown());
            jNot.show();
        }
    }
}


window.jso['/ToolBar/TickerStatus'] = function() {
    var that = this;
    
    this.TickerStatus = function() {
        this.jE.text('');
        
        //TODO irgendwie besser durchhangeln? In meta angeben, aber ggf. die slideContainer nach nem bestimmten Slide mit bestimmtem Namen fragen?
        that.callerObj().parentReady(function() {
            that.callerObj().jE.nextAll('div.jso_subtabBox').find('> div.jsc_Box-Inner > div.jso_slideContainer > div.jso_Slide:eq(1) > div.jso_verttabBox > div.jso_slideContainer > div.jso_Slide').each(function() {
                /*
                var oThis = this; 
                var jObj  = jQuery(document.createElement('img')).attr('src', 'img/icon_mail.gif').click(function() {
                    alert(jQuery(window.aes.getObj(oThis).getXML()).find('.jsd_email').text());
                });
                
                jQuery(this).find('> div > div.jst_IconBar').append(jObj);
                */
                //alert(window.aes.getObj();
                var jE      = jQuery(this);
                
                //20091214 - PASST erstmal ...
                var iStatus = -1;
                if (jE.getObj()) iStatus = parseInt(jE.getObj().getJSDs()['status']);
                else             iStatus = parseInt(jE.find('.jsd_status').text());
                
                var sStatus = 'verfügbar';
                if (iStatus == 1) sStatus = 'bald verfügbar';
                if (iStatus == 2) sStatus = 'geplant';
                
                var jElem   = jQuery('<span />').text('Status').attr('title', sStatus).append(jQuery('<img />').attr({ 'src': '/fileadmin/img/ampel_'+iStatus+'.png', 'alt': sStatus, 'title': sStatus, 'class': 'jsc_TickerStatus' }));
                
                jE.closest('div.jso_subtabBox').getObj().addExternal('IconBar', jElem);
            });
        });
    }
}


window.jso['/Zettel'] = function() {
    var that = this;
    var sOverlay = '';
    
    var aElems = new Array();
    
    var fPriceB2B = 0;
    var fPriceB2C = 0;
    var fPrice    = 0.20;
    
    //BESSER: einfach den Zettel in div.jso_Infoboards packen --> /Infoboards/Zettel!! Gar kein Kontext!
    //TODO Unterscheidung per Context nach den einzelnen Zetteln?
    //     Mechanik mit Elementen im Zettel - getInContext() - für jeden gleich
    //     JS Spielereien halt im jeweiligen Zettel-Context!
    
    // nicht direkt auf den Filter Handelskanal zugreifen per ID wie jetzt, irgendwie besser?
    // Oder passt das, weil es eh "inContext" gemacht werden soll?
    // Auch beim Filter direkt auf execFilter ... gut?
    // Allg. aufarbeiten ...
    
    // IDs innerhalb Zettel -> irgendwie mit eindeutiger ObjID? --> Wenn Zettel in JS-Tpl,
    // können die IDs mit jsid_${_obj_id}_selected_items gemacht werden, und im Zettel-JSO
    // entsprechend darauf zugreifen!
    // Mit that.jE drauf zugreifen wär schön, geht aber halt im Overlay nich -> jQuery('#xyz')
    
    // Wenn im Overlay was geändert wird, auch auf Mainfenster übertragen!
    // Verknüpfung Kategorie-Daten Preise <--> Zettel ... metadata? Plugin-mäßig?
    
    this.Zettel = function() {
        this.jE.addClass('jsc_Zettel').children('.jsc_Zettel-Tb').attr('id', 'jsid_Zettel_' + this.getId());
        
        aElems = new Array();
        
        that.callerObj().parentReady(function() {
            //alert(that.callerObj().jE.attr('class'));
            that.callerObj().jE.nextAll('div.jso_subtabBox').find('> div.jsc_Box-Inner > div.jso_slideContainer > div.jso_Slide:eq(1) > div.jso_verttabBox > div.jso_slideContainer > div.jso_Slide').each(function() {
                var jE    = jQuery(this);
                
                //20091214
                //var jElem = jQuery('<span />').append('<input type="checkbox"'+((parseInt(jE.getObj().getJSDs()['status']) == 2) ? '' : ' checked="checked"')+' />');
                var jElem = jQuery('<span />').append('<input type="checkbox"'+((parseInt(jE.find('.jsd_status').text()) == 2) ? '' : ' checked="checked"')+' />');
                //var jElem = jQuery('<span />').append('<input type="checkbox" checked="checked" />');
                
                var oParent = jE.closest('div.jso_subtabBox').getObj()
                oParent.addExternal('IconBar', jElem);
                
                aElems.push(jElem);
                
                //20091214
                //jElem.data('ticker', jE.getObj().getJSDs());
                jElem.data('ticker', { uid: jE.find('.jsd_uid').text(), title: jE.find('.jsd_title').text() });
                jElem.data('portal', oParent.getJSDs());
            });
            
            var oCat = that.callerObj().jE.prev('.jso_Box').getObj();
            if (oCat) {
                var oJSDs = oCat.getJSDs();
                
                fPriceB2B = parseFloat(oJSDs.price_b2b);
                fPriceB2C = parseFloat(oJSDs.price_b2c);
            }
            
            if (!isNaN(fPriceB2C)) {
                fPrice = fPriceB2C;
                
                jQuery('#jsid_Zettel_price_av > strong').text('€ '+fPrice.formattedStr());
                jQuery('#form_Zettel_budget').keyup();
            }
        });
        
        this.jE.find('#form_Zettel_type_Kostenlos').click(function() {
            jQuery('#form_Zettel_budget').attr('readonly', 'readonly').css('background-color', 'silver').keyup();
        });
        this.jE.find('#form_Zettel_type_Budget').click(function() {
            jQuery('#form_Zettel_budget').attr('readonly', '').css('background-color', 'white').keyup();
        });
        
        this.jE.find('#form_Zettel_channel').change(function() {
            //jQuery('#ToolBar_Filter_price_model').val(jQuery(this).val());
            jQuery('#ToolBar_Filter_price_model input:checked').attr('checked', '');
            jQuery('#ToolBar_Filter_price_model input[value="'+jQuery(this).val()+'"]').attr('checked', 'checked');
            
            if (jQuery(this).val() == '0') fPrice = isNaN(fPriceB2B) ? 0.20 : fPriceB2B;
            else                           fPrice = isNaN(fPriceB2C) ? 0.15 : fPriceB2C;
            
            jQuery('#jsid_Zettel_price_av > strong').text('€ '+fPrice.formattedStr());
            jQuery('#form_Zettel_budget').keyup();
            
            //jQuery('#ToolBar_Filter_price_model').change();
            jQuery('#ToolBar_Filter_price_model').getObj().execFilter('plain');
            that.createCheckboxes();
            jQuery('#jsid_Zettel_head').text('( Handelskanal: '+jQuery('#form_Zettel_channel option:selected').text()+')');
        });
        
        this.jE.find('#form_Zettel_budget').keyup(function() {
            var fVal = parseFloat(jQuery(this).val().replace(/\./g, '').replace(/,/g, '.'));
            
            if (jQuery(this).attr('readonly')) fVal = 200;
            
            //alert(parseFloat(jQuery(this).val()));
            //alert(parseFloat(jQuery('#jsid_Zettel_price_av').text()));
            
            if (isNaN(fVal)) jQuery('#jsid_Zettel_amount_av > strong').text('-');
            else jQuery('#jsid_Zettel_amount_av > strong').text(Math.round(fVal / fPrice));
        });
        
        this.jE.children('a').click(function() {
            that.createCheckboxes();
            
            //jQuery('#form_Zettel_channel').val(jQuery('#ToolBar_Filter_price_model').val());
            jQuery('#form_Zettel_channel option').each(function() {
                if (!jQuery('#ToolBar_Filter_price_model input[value='+jQuery(this).attr('value')+']').length) jQuery(this).hide();
            });
            jQuery('#form_Zettel_channel').val(jQuery('#ToolBar_Filter_price_model input:checked').val()).change();
            
            jQuery('#jsid_Zettel_head').text('( Handelskanal: '+jQuery('#form_Zettel_channel option:selected').text()+')');
            
            //alert(aSel.join(', '));width: 817px; height: 570px;
            tb_show(null, '#TB_inline?height=570&width=817&inlineId=jsid_Zettel_' + that.getId(), false);
            
            this.blur();
            return false;
        });
        
        //TODO Eigentlich nich hier rein ... eigenes Element!
        this.jE.find('> div.select_all > input').change(function() {
            for (var iI = 0; iI < aElems.length; iI++) {
                aElems[iI].children('input').attr('checked', jQuery(this).attr('checked'));
            }
        });
        
        that.parentReady(function() {
            //alert(jQuery('#ToolBar_Filter_price_model').length);
            jQuery('#ToolBar_Filter_price_model').getObj().registerMessage('filter', function(sMsg, oData) {
                if (oData == '0') fPrice = isNaN(fPriceB2B) ? 0.20 : fPriceB2B;
                else              fPrice = isNaN(fPriceB2C) ? 0.15 : fPriceB2C;
                
                jQuery('#ToolBar_Zettel_price').text('€ '+fPrice.formattedStr());
            });
        });
        
        this.jE.find('#form_Zettel_type_Kostenlos:checked').click();
        
        this.initializeNextChildren();
    }
    
    this.createCheckboxes = function() {
        var aSel = new Array();
        //var sList = '';
        var bSel = false;
        
        for (var iI = 0; iI < aElems.length; iI++) {
            if (!aElems[iI].filter(':visible').length) continue;
            
            var sSel = '';
            if (aElems[iI].children('input').filter(':checked').length) {
                sSel = ' checked="checked"';
                bSel = true;
            }
            
            /*
            if (!aElems[iI].data('ticker')) {
                alert(aElems[iI].data('ticker_node').getObj());
                //aElems[iI].data('ticker', aElems[iI].data('ticker_node').getObj().getJSDs());
            }
            */
            
            aSel.push('<input'+sSel+' type="checkbox" name="tickers['+aElems[iI].data('ticker').uid+']" value="'+aElems[iI].data('portal').title+' - '+aElems[iI].data('ticker').title+'" id="jsid_Zettel_Item_'+aElems[iI].data('ticker').uid+'" /> <label for="jsid_Zettel_Item_'+aElems[iI].data('ticker').uid+'">'+aElems[iI].data('portal').title+'</label>');
        }
        
        jQuery('#jsid_Zettel_selected_items > div.jsc_Box-Inner').html(aSel.join(''));//<br style="clear: left;" />'));
        
        if (!bSel) jQuery('#jsid_Zettel_selected_items > div.jsc_Box-Inner > input[type=checkbox]').attr('checked', 'checked');
        //TODO: auch checkboxen auf Seite selbst aktualisieren, v.a. wenn im Overlay manuell was geändert wird
    }
}
// Just for the Zettel
window.jso['/ToolBar/Zettel/Form'] = function(superClass) {
    this.Form = function() {
        superClass.Form.call(this);
    }
    
    this.submit = function() {
        var j1 = jQuery('#form_Zettel_channel > option[value=1]').attr('value', 'Consumer');
        var j0 = jQuery('#form_Zettel_channel > option[value=0]').attr('value', 'Firmenkunde');
        
        superClass.submit.call(this);
        
        j1.attr('value', '1');
        j0.attr('value', '0');
    }
}



window.jso['/goTo'] = function() {
    var that = this;
    
    this.goTo = function() {
        that.jE.addClass('jsc_goTo');
        
        //alert(that.jE.html());
        that.jE.change(function() {
            //TODO change: jsp_post -> create form before that.jE, put that.jE inside, perhaps (form).data('obj', that)?
            if (that.jE.parent('form').length && !that.jE.siblings().length) {
                that.jE.parent('form').submit();
            }
            else if (that.jE.val()) {
                document.location.href = that.jE.val();
                that.jE.children('option:first').attr('selected', 'selected');
            }
        });
    }
}








window.jso['/Box'] = function() {
    var that  = this;
    var iOrgW = undefined;
    var oT    = undefined;
    var oParams = undefined;
    var zIndex  = -1;
    
    this.Box = function() {
        oParams = this.getParams();
        
        //TODO - don't use 'Inner' here, but use 'Outer' for Shadows, Corners etc ...
        if (oParams['parseJSDs']) this.parseJSDs(this.getTplPath('Inner'));
        else if (oParams['next']) {
            this.initializeNextChildren();
        }
        else                      this.initializeChildren();
        
        this.initBox();
    }
    
    this.initBox = function(oAltParams, sContext) {
        oParams = this.getParams();
        var iInnerHeight = '';
        
        if (!sContext) sContext = '';
        
        // breite/höhe aus jso_Box rausnehmen, auf jsc_Box-Inner setzen
        //          dann auch höhe shadow_right setzen
        
        // je nachdem ob shadow, corner, shadow-left -> elemente einfügen, css setzen
        
        
        // See index.js: findTplPath
        var oTpl = this.getTpl(sContext, 'Box');
        //if (sContext == 'ToolBar') alert(oTpl);
        if (!oTpl) return;
        
        if (this.jE.children().length) {
            // We can't use .remove() -> also removes event handler and data
            // Also, append() is bad because it moves script tags ...
            //var jTmp      = jQuery(document.createElement('span'));
            //var jChildren = this.jE.children().appendTo(jTmp);
            var oTmp      = document.createElement('span');
            var oChildren = this.jE.children().get();
            for (var iI in oChildren) oTmp.appendChild(oChildren[iI]);
            
            // Later: pass params for e.g. showing or hiding shadow/borders/...
            this.jE.html(oTpl, {});
            
            //this.addExternal('Box', jChildren);
            //jTmp.remove();
            for (var iI in oChildren) this.jE.find('.jst_Box').get(0).appendChild(oChildren[iI]);
            
            this.jE.addClass('jsc_Box');
        }
        else this.jE.html(oTpl, {});
        
        
        // Shadow eigentl. erst extra hinzufügen, so dann Höhe setzen:
        //alert(this.getObjName() +'--'+ this.jE.height() +'--'+ this.jE.children('.jsc_Box-Inner').css('height') +'--'+ this.jE.children('.jsc_Box-Inner').innerHeight() +'--'+ this.jE.children('.jsc_Box-Inner').outerHeight());
        //if (this.jE.children('.jsc_Box-Inner').height() > 0) alert(this.getObjName() +'--'+  (this.jE.height() - this.jE.children('.jsc_Box-Inner').height()));
        
        if (oParams['noShadow'] || (oAltParams && oAltParams['noShadow'])) {
            this.jE.css('padding-right', '0').children('.jsc_Shadow_Top_Right, .jsc_Shadow_Bottom_Right, .jsc_Shadow_Bottom_Left, .jsc_Shadow_Right, .jsc_Shadow_Bottom').css('display', 'none');
            //this.jE.find('> div.jsc_Box-Inner > div.jsc_IconBar').css('right', 0);
        }
        else {
            this.jE.css('padding-right', '7px');
            
            //TODO [overflow_height]: height() is wrong if div is hidden ... show, then hide!
            var iInnerHeight = this.jE.children('.jsc_Box-Inner').height();
            
            if (!iInnerHeight && !this.jE.children('.jsc_Box-Inner:visible').length) {
                this.jE.show();
                iInnerHeight = this.jE.children('.jsc_Box-Inner').height();
                
                // TODO while closest('jsc_Box')? This way only three levels!
                if (!iInnerHeight && !this.jE.closest('.jsc_Box-Inner:visible').length) {
                    //TODO closest('jso_selectBox') -> closest('jsc_Box')? [but jsc_Box at parents not yet set (done AFTER initializeChildren!)
                    var jE = this.jE.parent().closest('.jso_selectBox').show();
                    iInnerHeight = this.jE.children('.jsc_Box-Inner').height();
                    
                    jE.hide();
                }
                
                this.jE.hide();
            }
            
            // if (jQuery.browser == ie6) -> set height, reset bottom. how to find out about changes
            // in height? force all children to sendMsg if .domManip?
            //this.jE.children('.jsc_Shadow_Right').css('height', (iInnerHeight - 9) + 'px');
        }
        
        //TODO DOM Änderungen am Element abfangen und ggf. Höhe anpassen (auch für andere Elemente wichtig,
        //     wo es nich nur um die Höhe geht!)
        
        //TODO Evtl. auch was über CSS steuern? Also wenn div.jsc_leftShadow:visible, dann anderes auch?
        // dann aber sauber trennen, was über jsp_ gemacht wird!
        if (oParams['leftShadow'] || (oAltParams && oAltParams['leftShadow'])) {
            //TODO pos absolute, padding-left, top 0, bottom 0, bzw. ie6 rausrechnen? --> BESSER!
            //if (this.jE.find('> div > h3').text() == 'Beschaffungs- dienstleister') alert(iInnerHeight);
            
            
            this.jE.css('padding-left', '6px').children('.jsc_Shadow_Left').css({'display': 'block', 'height': iInnerHeight + 'px' });
            // Nich so ... lieber im CSS nach jsp_noShadow ...
            this.jE.children('.jsc_Shadow_Bottom_Left').css('left', '6px');
        }
        
        
        zIndex = parseInt(this.jE.css('z-index'));
        if (!zIndex || (zIndex == 'auto') || isNaN(zIndex)) zIndex = 0;
    }
    
    //TODO return this, so that function can be chained!
    this.hide = function(oAnimation) {
        if (!oAnimation) oAnimation = {};
        
        if (oAnimation.sType == 'special_move_yeah') {
            //TODO [overflow_height]: do a overflow: hidden? -> Save old value ...
            //this.jE.css('z-index', 20).fadeOut(1000);
            if (!oT) oT = setTimeout(function() { that.jE.stop(true).css('z-index', (zIndex + 20)).fadeOut(650); }, 200);
        }
        else if (oAnimation.sType == 'slide') {
            if (this.jE.filter(':visible').length) this.jE.slideUp();
        }
        else if (oAnimation.sType == 'plain') {
            if (this.jE.filter(':visible').length) this.jE.hide();
        }
        else {
            if (this.jE.filter(':visible').length) this.jE.fadeOut();
        }
        
        // fadeOut, slideUp, nach links/rechts sliden, ...
    }
    
    //TODO z-indices not absolute, but this.jE.css('z-index', (this.jE.css('z-index') + 2)) and so on
    //     if z-index doesn't exist use none, 1, 2; else curr, curr + 1, cur + 2
    this.show = function(oAnimation) {
        if (!oAnimation) oAnimation = {};
        
        if (oAnimation.sType == 'special_move_yeah') {
            if (oT) {
                clearTimeout(oT);
                oT = undefined;
            }
            
            //if (!that.jE.filter(':visible').length) {
            if ((!that.jE.filter(':visible').length) || (that.jE.css('opacity') < 1)) {
                if (!iOrgW) iOrgW = this.jE.show().children('div.jsc_Box-Inner').width();
                
                var sO = this.jE.css('overflow');
                if (!sO) sO = 'visible';
                
                // IE - width ... problem ...
                if (!iOrgW) iOrgW = 215;
                
                
                this.jE.stop(true).show().css({ 'opacity': 1, 'z-index': (zIndex + 22), 'overflow': 'hidden' }).children('div.jsc_Box-Inner').stop(true).css({ 'width': 0, 'background-color': '#e5e5e5' }).animate({ 'width': iOrgW + 'px', 'backgroundColor': '#ffffff' }, 400, function() {
                    that.jE.css({ 'z-index': (zIndex + 21), 'overflow': sO });
                });
            }
            /*
            else if (that.jE.css('opacity') < 1) {
                this.jE.stop(true).animate({ 'opacity': 1 }, 100);
            }
            */
        }
        else if (oAnimation.sType == 'slide') {
            if (!this.jE.filter(':visible').length) this.jE.slideDown();
        }
        else if (oAnimation.sType == 'plain') {
            if (!this.jE.filter(':visible').length) this.jE.show();
        }
        else {
            if (!this.jE.filter(':visible').length) this.jE.fadeIn();
        }
    }
    
    return this;
}

//  Alles nimmer nötig wenn menuBox einfach ein Root-Elem wäre!
window.jso['/Slides/slideContainer/Slide/menuBox'] = '_';

window.jso['_menuBox'] = '/Box';
window.jso['/menuBox'] = function() {
    var that    = this;
    
    this.menuBox = function() {
        //window.startTimer('menuBox');
        
        // Very strict initialization, because children JSOs can contain uls themselves!
        var jSubs = this.jE.find('> ul > li > div, > ul > li > ul > li > div');
        
        //TODO find('> ul > li') with no div -> check for href -> load via AJAX on request?
        
        this.initializeElements(jSubs);
        
        //TODO tell oChildren to find this.jE.prev().filter/find('a') and bind click event themselves? (then regMsg('show') to all oChildren and sendMsg('show') when executed!!)
        //     or do it here? Not nice, e.g. to use oChild.jE and so on.
        for (var iI in this.oChildren) {
            var oChild = this.oChildren[iI];
            
            //TODO better save jQuery(this) on a var and not call it every time, hmm? Examine .each, probably do it with "for (var jE in jSubs)"?
            //var jLink = jQuery(this).prev('a').length ? jQuery(this).prev('a') : jQuery(this).prev().find('a');
            var jLink = oChild.jE.prev('a').length ? oChild.jE.prev('a') : oChild.jE.prev().find('a');
            
            // To get oChild within an own variable scope (var oTmp)
            // -> oChild changes with the iteration and so it also would for the
            //    click event handler for jLink!
            var tmpFunc = function() {
                var jTmp = jLink;
                var oTmp = oChild;
                
                jTmp.data('obj_show', oTmp);
                
                //CHANGE mouseover statt click
                /*
                jTmp.mouseover(function() {
                    //alert(jTmp.text() +'--'+ jQuery(this).text());
                    that.sendMessage('show', oTmp);
                    
                    return false;
                });
                */
            }.call();
        }
        
        //TODO > * > passt das?
        this.jE.find('> ul > li > * > a, > ul > li > ul > li > * >a').mouseover(function() {
            //alert(jTmp.text() +'--'+ jQuery(this).text());
            that.sendMessage('show', jQuery(this).data('obj_show'));
            
            return false;
        });
        
        this.jE.mouseleave(function() {
            that.sendMessage('show');
        });
        
        this.initBox();
        //window.endTimer('menuBox');
    }
    
    return this;
}

window.jso['_selectBox'] = '/Box';
window.jso['/selectBox'] = function() {
    var that = this;
    
    this.jE.addClass('jsc_selectBox');
    
    this.selectBox = function() {
        //window.startTimer('selectBox');
        
        // Reassign that, since this obj could probably the prototype of another
        // Then, the "old" that is just the object to the point in the prototype
        // rootline where this object was (for that, this constructor has to be
        // called with .call(this) to provide the "last version" of "this"
        
        //TODO Ey - also possible with "that = window.aes.getObj(this.jE)"?
        that = this;
        
        //alert(this.dd);
        //this.dd = 'abc';
        
        this.initBox();
        
        this.callerObj().registerMessage('show', msgShow);
        
        //window.endTimer('selectBox');
    }
    
    var msgShow = function(sMsg, oData) {
        if (oData === that) {
            //if (!that.jE.filter(':visible').length) that.show({ 'sType': 'special_move_yeah' });
            that.show({ 'sType': 'special_move_yeah' });
        }
        else {
            that.sendMessage('show');
            that.hide({ 'sType': 'special_move_yeah' });
        }
    }
    
    return this;
}
window.jso['/menuBox/selectBox'] = function(superClass) {
    /*
     * div > h1/2/..., div > ul > li > a
     * this.initBox()!
     * xyz.php?abc=123&category=X&def=456 [only for param "category"? also for others?]
     *
     */
    
    var that = this;
    
    this.selectBox = function() {
        
        //JOO <div class="jso_IconBar"><img class="jso_Close" src="..." />
        //    --> Box schließen. Wie findet Close raus wen es schließen muss? IMMER .callerObj.callerObj?
        //        Was ist das callerObj wenn es ein External ist? Muss das Ziel irgendwie zurückgeben ...
        this.jE.prepend('<div class="jso_IconBar jsc_IconBar"><img class="jso_Close jsc_Close" src="http://data.dci-se.de/img/close.gif" /></div>');
        
        // Hier allgemein mit Tpls arbeiten, zB für iconBar, und sauber multiple/nicht multiple trennen
        // das mit dem counter und category usw, besser irgendwie in Funktionen packen?
        
        if (this.getParams()['notMultiple']) {
            var jSubs = this.jE.find('> ul > li > div');
            this.initializeElements(jSubs);
            
            for (var iI in this.oChildren) {
                var oChild = this.oChildren[iI];
                var jLink  = oChild.jE.prev('a').length ? oChild.jE.prev('a') : oChild.jE.prev().find('a');
                
                var tmpFunc = function() {
                    var jTmp = jLink;
                    var oTmp = oChild;
                    
                    jTmp.data('obj_show', oTmp);
                    //CHANGE mouseover statt click
                    //TODO   wenn mouseover wo kein untermenü -> evtl. untermenüs ausblenden
                    /*
                    jTmp.mouseover(function() {
                        //alert(jTmp.text() +'--'+ jQuery(this).text());
                        //alert(oTmp.jE.html());
                        that.sendMessage('show', oTmp);
                        
                        return false;
                    });
                    */
                }.call();
            }
            
            this.jE.find('> ul > li > a').mouseover(function() {
                //alert(jTmp.text() +'--'+ jQuery(this).text());
                //alert(jQuery(this).data('obj_show').jE.html());
                that.sendMessage('show', jQuery(this).data('obj_show'));
                
                return false;
            });
            
        }
        else {
            // root selectBox keeps li > a (or li > hX > a, ...), this one uses a template -> labels and checkboxes!
            var oTpl = this.getTpl('ListItem');
            var iUnd = 0;
            
            //TODO just insert checkboxes and defButton if jsp_multiple? Else, just direct links ...
            this.jE.find('> ul > li').each(function() {
                //TODO here there's no h1, h2 or else in the li ... but what if? find('a:first')?
                //     If link was found, insert every part of the query, e.g. query_category
                var oParams = that.makeTplParams(jQuery(this).children('a'), 'listitem');
                var iParam  = undefined;
                
                if (oParams['listitem[href]']) iParam = oParams['listitem[href]'].parseQuery()['categories'];
                
                //TODO function putData, getData? Check if jQuery Obj -> get DOM Obj, check for i > parseInt, f > parseFloat, ...?
                //jQuery.data(this, 'iCategory', ((iParam === undefined) ? -1 : iParam));
                oParams['category'] = (iParam === undefined) ? -1 : iParam;
                oParams['counter'] = ++iUnd;
                
                jQuery(this).html(oTpl, oParams);
                
                jQuery(this).children('label').click(function() {
                    //alert(jQuery.data(this, 'iCategory'));
                    //alert(jQuery(this).prev('input[type=checkbox]').val());
                    document.location.href = 'index.php?categories=' + jQuery(this).prev('input[type=checkbox]').val();
                    return false;
                });
            });
        }
        
        // jso_Button.click -> document.location.href = xy.php?category=' + aSelected.join(',')
        // function for this tpl with input checkbox and labels ... use a .submit() function?
        // can be overloaded by other objects if the tpl is different
        this.initializeElements(this.jE.children('div.jso_IconBar')); // Sonst steht defButton evtl. auf [1],
        this.initializeElements(this.jE.children('a.jso_defButton')); // weil es im HTML weiter hinten kommt ...
        //alert(this.oChildren[1].defButton);
        
        // Nur wenn der defButton auch drin is - und der sollte eh nur bei nicht multiple drin sein!
        if (this.oChildren[0] && this.oChildren[0].defButton) {
            var jCheckboxes = that.jE.find('> ul > li > input[type=checkbox]');
            
            this.oChildren[0].jE.click(function() {
                var aCats = new Array();
                
                jCheckboxes.filter(':checked').each(function() {
                    aCats.push(jQuery(this).val());
                });
                
                document.location.href = 'index.php?categories=' + aCats.join(',');
                
                return false;
            });
        }
        
        
        // See super.selectBox why the .call! Super constructor is called after all the stuff above
        // because it calls this.initBox and changes the HTML with that!
        superClass.selectBox.call(this);
    }
    
    /* SHOW BOX - old
    
    //jQuery('div.menu_main ul li div.jso_selectBox').fadeOut();
    //jQuery(this).parent('h1, h2').next('div.jso_selectBox').fadeIn();
    
    var jO = jQuery('div#menu_main ul li div.jso_selectBox:visible');
    var jB = jQuery(this).parent('h1, h2').next('div.jso_selectBox');
    var iW = jB.show().children('div.jsc_Box-Inner').width();
    
    jB.css({ 'z-index': 22 }).children('div.jsc_Box-Inner').css({ 'width': 0, 'background-color': '#e5e5e5' }).animate({ 'width': iW + 'px', 'backgroundColor': '#ffffff' }, 400, function() {
    //jB.css({ 'z-index': 22, 'overflow': 'hidden' }).children('div.jsc_Box-Inner').css({ 'margin-left': (-1 * iW) + 'px', 'background-color': '#e5e5e5' }).animate({ 'marginLeft': 0, 'backgroundColor': '#ffffff' }, 400, function() {
        jB.css({ 'z-index': 21 });
    });
    
    //jB.css({ 'z-index': 22, 'width': 0 }).
    //jB.children('div.jsc_Box-Inner').css({ 'background-color': '#e5e5e5' }).animate({ 'width': iW + 'px', 'backgroundColor': '#ffffff' }, 400, function() {
    //    jB.css({ 'z-index': 21 });
    //});
    
    jO.css('z-index', 20).fadeOut(650);
    
    */
}
window.jso['/menuBox/selectBox/selectBox'] = function(superClass) {
    this.selectBox = function() {
        superClass.selectBox.call(this);
        
        var sLeft = this.callerObj().jE.show().css('left');
        var iLeft = parseInt(sLeft.substr(0, sLeft.length - 2));
        
        var sLeft = this.jE.show().css('left');
        iLeft     = iLeft + parseInt(sLeft.substr(0, sLeft.length - 2));
        
        var that  = this;
        
        this.callerObj().jE.hide();
        this.jE.hide();
        
        this.jE.css('left', (iLeft) + 'px');
        
        this.callerObj().parentReady(function() {
            that.jE.insertAfter(that.callerObj().jE);
        });
    }
}





window.jso['/navMenu'] = function() {
    var that = this;
    var oP   = undefined;
    
    this.setActive = function(sMsg, iLink) {
        that.jE.find('a').removeClass('active').filter(':eq('+(iLink - 1)+')').addClass('active');
    }
    
    this.navMenu = function() {
        this.initNavMenu();
    }
    
    this.setAdditionalElem = function(jElem, bBefore) {
        // We need the "this" context from the caller, and we need it in the click-context below
        // where "this" is the link context ...
        var that = this;
        
        this.parentReady(function() {
            if (bBefore) jElem.parent().prependTo(that.jE);
            else         jElem.parent().appendTo(that.jE);
        });
        
        jElem.click(function() {
            this.blur();
            
            that.onAdditionalGoto(oP, this);
            return false;
        });
    }
    
    //TODO getNavElement sollte jElem nur zurückgeben, nicht schon an that.jE angehängt haben!
    this.getNavElement = function(iI, iMax, oC) {
        var jElem = jQuery(document.createElement('a')).appendTo(jQuery(document.createElement('li')).appendTo(that.jE)).attr('href', '#').html(oC.aSlides[iI]);
        
        return jElem;
    }
    
    this.onGoto = function(oP, oLink) {
        oP.gotoSlide(jQuery.data(oLink, 'page'));
    }
    
    this.initNavMenu = function() {
        // Yeah, because we want the "real" this, i.e. the this from the caller object!
        // And we need this within parentReady and click --> so should be another var than this!
        var that = this;
        
        //TODO callerObj!
        oP = this.parentObj();
        oP.registerMessage('show', this.setActive);
        
        this.parentReady(function() {
            var oC = oP.getContainer();
            var iMax = oP.getPageCount();
            
            for (var iI = 1; iI <= iMax; iI++) {
                // Yeah baby ...
                //.click(function() {
                jQuery.data(that.getNavElement(iI, iMax, oC).click(function() {
                    this.blur();
                    
                    that.onGoto(oP, this);
                    
                    return false;
                }).get(0), 'page', iI);
            }
        });
    }
}










window.jso['_subtabBox'] = '/Box,/Slides';
window.jso['/subtabBox'] = function() {
    var that    = this;
    
    this.subtabBox = function() {
        //window.startTimer('subtabBox');
        
        var sContext = '';
        
        if (this.getParams()['inContext'] && this.jE.attr('title').length) {
            sContext = this.jE.attr('title');
        }
        
        // Kompletten Inhalt in Template - Inhalte als jsd_ einbauen
        //      parseJSDs erweitern, sodass jso_* erhalten bleibt (hier: jso_PageContainer)
        this.parseJSDs(this.getTplPath(sContext));
        
        // Container soll faden!
        this.jE.addClass('jsc_subtabBox').children('.jso_slideContainer').addClass('jsp_fade').addClass('jsp_varHeight');
        // Slides bzw. Container sagen, dass die Höhe nich gesetzt werden soll ... jsp_varHeight bei slideContainer?
        
        
        //  -> Slides in Pages umbauen, checken dass überall callerObj anstatt parentObj verwendet wird!
        
        // this.initializeChildren() (müsste jso_navMenu und jso_PageContainer sein)
        //  -> jso_PageTitle muss sich verstecken!
        this.initializeChildren();
        
        // PluginIcons in den Header, fügen allen Firmen jeweils ein Icon hinzu.
        //  -> evtl. "intelligent" bauen, dass die eine Liste finden und das hinzufügen?
        //  -> addExternal('IconBar') auf alle Firmen
        
        
        // Generate box without shadows!
        var oParams = new Object();
        
        oParams['noShadow'] = true;
        //oParams['leftShadow'] = true;
        
        // Some subtabBoxes could be empty, so check ...
        if (this.getContainer()) this.initSlides();
        
        this.initBox(oParams);
        
        //window.endTimer('subtabBox');
    }
    
    return this;
}

window.jso['/subtabBox/navMenu'] = '/Box/subtabBox';
window.jso['/Box/subtabBox/navMenu'] = function() {
    var that = this;
    
    //TODO subtabBox, verttabBox: bei initialisierung wie bei Slides goto(1) auslösen? Damit hier nich "manuell" active gesetzt werden muss!
    this.getNavElement = function(iI, iMax, oC) {
        var jElem = jQuery(document.createElement('a')).appendTo(jQuery(document.createElement('li')).appendTo(this.jE)).attr('href', '#').html(oC.aSlides[iI]);
        
        if (iI == 1)    jElem.addClass('active').before('<img class="jsc_borderLeft" src="http://www.dci.de/fileadmin/templates/themenwelten/img/corner_left_company.gif" />');
        if (iI == iMax) jElem.after('<img class="jsc_borderRight" src="http://www.dci.de/fileadmin/templates/themenwelten/img/corner_right_company.gif" />');
        
        return jElem;
    }
    
    this.onGoto = function(oP, oLink) {
        oP.gotoSlide(jQuery(oLink).hasClass('active') ? 1 : jQuery.data(oLink, 'page'));
    }
    
    this.navMenu = function() {
        var sP = this.sPath;
        var sO = this.sObjPath;
        
        this.initNavMenu();
    }
}





window.jso['_verttabBox'] = '/Slides';
window.jso['/Slides/slideContainer/Slide/verttabBox'] = '_';
window.jso['/verttabBox'] = function() {
    var that = this;
    
    this.getMinHeight = function() {
        // only .show if hidden, only hide if hidden before
        // .ready in SlideContainer
        var bHidden = that.jE.parent(':hidden').length;
        
        if (bHidden) that.jE.parent().show();
        
        var iH = that.jE.children('.jso_navMenu ').height();
        
        if (bHidden) that.jE.parent().hide();
        
        return iH;
    }
    
    this.verttabBox = function() {
        this.jE.addClass('jsc_verttabBox').children('.jso_slideContainer').addClass('jsp_fade jsp_varHeight');
        
        // Still parse JSDs to get navMenu "online"
        this.parseJSDs(this.getTplPath());
        
        this.initializeChildren();
        
        
        if (this.getContainer()) this.initSlides();
        
        //TODO Breite slideContainer / navMenu anpassen --> width(), dann immer 110px menü oder 25% in px + 1px umrechnen?
    }
    
    /*
    var addVerticalTabs = function() {
        jQuery('div.box_tab_vert div.img_bottom a.tab').each(function() {
            jQuery(this).attr('href', '#');
            
        }).unbind('click').click(function() {
      	    var oThis = this;
      	    
      	    if (!jQuery(oThis).hasClass('tab_active')) {
      	        jQuery(this).parent().parent().each(function() {
      	            //jQuery('div#container_menu').append('c: ' + encodeURI(document.title + $.data(this)) + '<br />');
      	            window.cookieFunc.createCookie(encodeURI(document.title + $.data(this)), jQuery(oThis).prevAll('a.tab').length);
      	        });
      	        
          	    jQuery(oThis).parent().children('a.tab').removeClass('tab_active');
          	    
          	    jQuery(oThis).addClass('tab_active').parent().children('div.tab').fadeOut(100, function() {
          	        jQuery(oThis).parent().children('div.tab').html(jQuery(oThis).next('span.tab').html()).fadeIn(100, function() {
          	            
          	            
          	        });
          	    });
          	}
          	
          	jQuery(this).blur();
          	return false;
      	});
      	
      	jQuery('div.box_tab_vert div.img_bottom a.tab:last').css('margin-bottom', '-1px');
      	
      	jQuery('div.box_tab_vert div.img_bottom').each(function() {
      	    var iTab = -1;
      	    
      	    jQuery(this).parent().each(function() {
      	        iTab = parseInt(window.cookieFunc.readCookie(encodeURI(document.title + $.data(this))));
      	    });
      	    
      	    var oThis = (iTab > -1) ? jQuery(this).find('a.tab:eq('+iTab+')') : jQuery(this).find('a.tab:first');
      	    
      	    jQuery(oThis).click();
      	    jQuery(this).find('a.tab:first').css('margin-top', '-1px');
        });
    }
    */
    
    return this;
}

window.jso['/Form/verttabBox/navMenu'] = '/verttabBox/navMenu';
window.jso['/verttabBox/navMenu'] = function() {
    var that = this;
    
    this.getNavElement = function(iI, iMax, oC) {
        var jElem = jQuery(document.createElement('a')).appendTo(that.jE).attr('href', '#').html(oC.aSlides[iI]);
        
        if (iI == 1) jElem.addClass('active');
        
        return jElem;
    }
    
    this.navMenu = function() {
        var sP = this.sPath;
        var sO = this.sObjPath;
        
        // Only do if navMenu's jsp_observe/jsp_validate?
        //if (oParams['validate']) {
            this.parentReady(function() {
                var oSlides = that.callerObj().getContainer().oSlides;
                
                for (var iI = 0; iI < oSlides.length; iI++) {
                    (function() {
                        oSlides[iI].registerMessage('valid', function(sMsg, oData) { that.valid(sMsg, oData, iI); });
                    })();
                    //alert(oSlides[iI].getTitle());
                }
            });
        //}
        
        this.initNavMenu();
    }
    
    
    this.valid = function(sMsg, oData, iI) {
        //alert(sMsg);
        //for (var iI in oData) alert(iI + ': ' + oData[iI]);
        /*
        var aErr = new Array();
        
        aErr = that.sendMessage('validate');
        
        var bErr = aErr.join('').length ? true : false;
        
        return bErr ? new Array('error', aErr.join(', ')) : true;
        */
        
        if (!oData.bValid) {
            that.jE.children('a:eq('+(iI - 1)+')').css('color', 'red');
        }
        else that.jE.children('a:eq('+(iI - 1)+')').css('color', '');
    }
}










window.jso['/PageTitle'] = function() {
    var that = this;
    
    this.getTitle = function() {
        return that.jE.text();
    }
    
    this.PageTitle = function() {
        that.jE.css('display', 'none');
    }
}

window.jso['_Page'] = '/Box,/Slides/slideContainer/Slide';
window.jso['/Page'] = function() {
    var that = this;
    var oParams = this.getParams();
    
    this.Page = function() {
        
        if (oParams['parseJSDs']) this.parseJSDs(this.getTplPath('Inner'));
        else if (oParams['all'])  this.initializeAllChildren();
        else if (oParams['next']) this.initializeNextChildren();
        else                      this.initializeChildren();
        
        if (that.jE.closest('.jso_slideContainer').length) this.initSlide(true);
        else                                               this.initBox();
    }
}