/**
* Fahrzeugdetails.js
* @author Elko Panzyk, Panzyk Network
* $Revision: 273 $
* $Id: Fahrzeugdetails.js 273 2008-09-22 00:58:04Z panzyk $
*  
*/


/**
* ZubehoerRechner
* @author Elko Panzyk, Panzyk.Net
* @uses Prototype 1.5.1 + 
*/  
function ClassZubRechner()
	{ 
	this.f_Preis = 0.00;
	this.f_Mwst = 0.00;
	this.f_Grundpreis = 0.00;

	this.b_Dbf = false;
	this.f_Uvp = 0.00;
	this.f_ZubehoerUvp = 0.00;
	this.f_Ueberfuehrung = 0.00;
    this.s_Letzter_Dialog = "";
    
	this.a_Kategorie = [];
    this.a_Stack = [];
    this.o_TempCheck = [];
    this.o_DialogCheck = [];
    
    this.o_Dialogdaten = { id:"", art:"", von:"" };
    
    this.o_Check_Speicher = [];
    this.o_Ersteinstieg_Id = [];
    this.o_JatoStack = [{i:[],e:[]}];

    this.o_Wahrungsoptionen = {
        dezimalstellen: 2,
        fixaktiv: false,
        prefix: '',
        suffix: ' &euro;',
        gruppentrenner: '.',
        dezimaltrenner: ','
        };

    /**
     * Exit Bit um die Rekursion vorzeitig zu verlassen
     * da kein Exit
     */
    this.b_Stop = false;
    
	this.s_Ausschlusstext = "#{Zubehoer}, #{Kategorie}";
	this.o_tplErsparnis_Prozent = new Template( "#{ErsparnisProzent}% #{UvpGesamt}" );
	this.o_tplErsparnis = new Template( "#{Ersparnis} &euro;" );
	
	/**
     * Default Texte
	 */
	this.o_Ausgabetexte = { row: new Template( '<tr>'+
			'<td class="zubbez">#{Zubehoer}</td>'+
			'<td valign="top">{#{Id}}:<input type="checkbox" id="azub#{Id}" value="#{Id}:#{An}" #{CheckboxChecked}/></td>'+
			'<td class="zubpreis">#{Preis}</td>'+
			'</tr>' ),
			and:	'<tr><td colspan="3">UND:</td></tr>',
			or:		'<tr><td colspan="3">ODER:</td></tr>',
			not:	'<tr><td colspan="3">NICHT MIT:</td></tr>',
			open:	'<tr><td colspan="3">(</td></tr>',
			close:	'<tr><td colspan="3">)</td></tr>',
			liste:	new Template( '<tr><td colspan="3">#{Zubehoer}</td></tr>' ),
			include: '<tr><td colspan="3">Exclude</td></tr>',
			exclude: '<tr><td colspan="3">Include</td></tr>',
			button: '<input type="Button" value="Übernehmen" id="but_Uebernehmen"/><input type="Button" value="Abbrechen" id="but_Abbrechen"/>',
			taopen: '<table>',
			taclose:'</table>',
			Ersparnis: new Template( "#{ErsparnisProzent}% #{UvpGesamt}" ),
			ErsparnisProzent: new Template( "#{ErsparnisProzent}% #{UvpGesamt}" )
			};

	this.o_CheckboxStatusAn = [];
	this.o_CheckboxStatus = [];
	this.a_AbhaengigkeitenStack = [];
	this.o_NeuerPreis = [];
	this.o_Discount = [];
	this.o_Jato = { Optionen: [], Index: [], Ref: [] };
	this.o_Dialog = [];
	}


/**
 * Waehrungskonfiguration
 * @param object Waehrungsoptionen
 * @author Elko Panzyk, Panzyk Networks
 */
ClassZubRechner.prototype.Waehrungskonfiguration = function ( o_Wahrungsoptionen ){
    this.o_Wahrungsoptionen = Object.extend( this.o_Wahrungsoptionen, o_Wahrungsoptionen );
    }


/**
 * float2euro
 * Wandelt eine Floatzahl in ein lesefreundliches Format
 * @param float Zahl;
 * @param integer AnzahlNullen ( 0-4 )
 * @return string Zahl;
 * @author Elko Panzyk, Panzyk Network
 * @version 1.3 (Waehrung)
 */
ClassZubRechner.prototype.float2euro = function ( f_Zahl, i_Modus ) {
    
    var b_WaehrungsSymbol = ( i_Modus == 2 && this.o_Wahrungsoptionen.fixaktiv === false ) ? false : true;

    var s_Dezimalseperator = this.o_Wahrungsoptionen.dezimaltrenner;
    var s_Gruppenseperator = this.o_Wahrungsoptionen.gruppentrenner;
    var s_Prefix = b_WaehrungsSymbol === true ? this.o_Wahrungsoptionen.prefix : "";
    var s_Suffix = b_WaehrungsSymbol === true ? this.o_Wahrungsoptionen.suffix : "";
    var i_Nullen = this.o_Wahrungsoptionen.dezimalstellen;


    var s_Vorzeichen = "";
    if( f_Zahl < 0 ) { f_Zahl = f_Zahl * -1; s_Vorzeichen = "-"; }
    var i_Faktor = ( i_Nullen > 0 )? Math.pow(10, i_Nullen) : 1;
    f_Zahl = (Math.round( f_Zahl*i_Faktor )/i_Faktor);
	var a_Zahl = f_Zahl.toString().split (".");
	if ( typeof(a_Zahl[1] ) === "undefined" ){ a_Zahl [1] = "00000"; }
	if ( a_Zahl [1].length === 1 ) { a_Zahl [1] += "0000"; }
	
	var i_Position = a_Zahl[0].length;
	while ( i_Position > 0 ){ 
		i_Position -= 3; if (i_Position <= 0) { break; }
		a_Zahl[0] = a_Zahl[0].substring( 0, i_Position ) + s_Gruppenseperator + a_Zahl[0].substring( i_Position, a_Zahl[0].length );
		}
	
	a_Zahl[1]=( i_Nullen !== null ? a_Zahl[1].substring (0, i_Nullen) : a_Zahl[1].substring (0, 2) );
	return i_Nullen === 0 ? s_Prefix + s_Vorzeichen+a_Zahl[0] + s_Suffix : s_Prefix + s_Vorzeichen+a_Zahl[0] + s_Dezimalseperator + a_Zahl[1] + s_Suffix;
	}


/**
 * Base64 Decoder
 * @author: Elko Panzyk
 */
ClassZubRechner.prototype.fn_Base64Decode = function ( s_String ) {
	var s_Output = "";
	var i_Chr1, i_Chr2, i_Chr3;
	var i_Enc1, i_Enc2, i_Enc3, i_Enc4;
	var i = 0;
	var s_Treffer = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";

	s_String = s_String.replace( /[^A-Za-z0-9\+\/\=]/g, "" );

	while ( i < s_String.length ){
		i_Enc1 = s_Treffer.indexOf( s_String.charAt( i++ ) );
		i_Enc2 = s_Treffer.indexOf( s_String.charAt( i++ ) );
		i_Enc3 = s_Treffer.indexOf( s_String.charAt( i++ ) );
		i_Enc4 = s_Treffer.indexOf( s_String.charAt( i++ ) );

		i_Chr1 = ( i_Enc1 << 2 ) | ( i_Enc2 >> 4 );
		i_Chr2 = (( i_Enc2 & 15 ) << 4 ) | ( i_Enc3 >> 2 );
		i_Chr3 = (( i_Enc3 & 3 ) << 6 ) | i_Enc4;

		s_Output = s_Output + String.fromCharCode( i_Chr1 );
		if ( i_Enc3 != 64 ) { s_Output = s_Output + String.fromCharCode( i_Chr2 ); }
		if ( i_Enc4 != 64 ) { s_Output = s_Output + String.fromCharCode( i_Chr3 ); }
		}
	return s_Output;
	}

/**
 * fn_Float()
 * Erzeugt eine Floatzahl
 * @param string Zahl;
 * @return float Zahl;
 */
ClassZubRechner.prototype.fn_Float = function ( s_Daten ){ 
    var f_Daten = parseFloat( s_Daten );
    return isNaN ( f_Daten ) ? 0.00 : f_Daten;
    };
    
/**
 * daten ()
 * Zerlegt die Informationen
 * @param string s_Wert;
 * @return object {id,aus,preis,kat,uvp}
 */
ClassZubRechner.prototype.daten = function ( s_Wert ){
    var a_Daten = s_Wert.split(":");
    
    return { id:a_Daten[0], 
             aus:a_Daten[1], 
             preis:parseFloat( a_Daten[2] ), 
             kat:a_Daten[3], 
             uvp:parseFloat( a_Daten[4] ),
			 typ:a_Daten[5],
			 apreis:parseFloat( a_Daten[6] )
             };
    };


/**
 * Erzeugt Jato-Ausschluss-Index für eigenes Zubehoer
 * @author Elko Panzyk
 */
ClassZubRechner.prototype.eigenesZubehoer = function (){

var i_Zaehler = 0;
$$("input[id^='zub']").each( function( o_Item ) { 
	var o_Daten = this.daten ( o_Item.value );
	if ( o_Daten.aus != "o" ){
		/** Exclude-Regeln && Index **/
		this.o_Jato.Optionen[ i_Zaehler ] = [ o_Daten.id, "E", '', o_Daten.aus.replace(/ /g, "&&") ];
		if ( Object.isUndefined( this.o_Jato.Index[ o_Daten.id ] ) ){ this.o_Jato.Index[ o_Daten.id ] = []; }
		this.o_Jato.Index[ o_Daten.id ] = [ i_Zaehler ];
		i_Zaehler++;
		}
	}.bind(this) );
}

/**
 * Floatgeparste Mwst
 */
ClassZubRechner.prototype.mwst = function ( s_Mwst ){
    this.f_Mwst = this.fn_Float( s_Mwst );
	//console.log( "Mwst:" + this.f_Mwst );
    };

/**
 * Floatgeparster Grundpreis
 */
ClassZubRechner.prototype.grundpreis = function ( s_Grundpreis ){
    this.f_Grundpreis = this.fn_Float( s_Grundpreis );
	//console.log ( "Grundpreis:" +  this.f_Grundpreis );
    };

/**
 * FloatGeparster Zubehoeraufpreis
 */ 
ClassZubRechner.prototype.aufpreis = function ( s_Aufpreis ){
    this.f_Preis = this.fn_Float( s_Aufpreis );
	//console.log ( "Preis:" + this.f_Preis );
    };
 
/**
 * FloatGeparste Uvp
 */
ClassZubRechner.prototype.uvp = function ( s_Uvp ){
    this.f_Uvp = this.fn_Float( s_Uvp );
	//console.log ( "Uvp (Grundpreis):" + this.f_Uvp );
    }

/**
 * DBF-Modus
 */
ClassZubRechner.prototype.dbf = function ( s_Dbf ){
    this.b_Dbf = ( s_Dbf == '1' ? true : false );
    }
    
/**
 * FloatGeparste ZubehoerUvp
 */
ClassZubRechner.prototype.zubehoeruvp = function ( s_ZubehoerUvp ){
    this.f_ZubehoerUvp = this.fn_Float( s_ZubehoerUvp );
	//console.log ( "ZubehoerUvp:" + f_ZubehoerUvp );
    }
       
/**
 * FloatGeparste Ueberfuehrungskosten
 */
ClassZubRechner.prototype.ueberfuehrungskosten = function ( s_Ueberfuehrung ){
    this.f_Ueberfuehrung = this.fn_Float( s_Ueberfuehrung );
	//console.log ( "Uebeferfuehrung:" + this.f_Ueberfuehrung );
    }  
   
/**
 * show()
 * Zeigt Datenwerte an
 */
ClassZubRechner.prototype.show = function (){
    var s_Preis = this.float2euro ( this.f_Preis, 2 );
	var f_NeuerPreis = 0.00;
	var f_Discount = 0.00;

	this.o_NeuerPreis.each ( function ( o_Item ){ 
	
	f_NeuerPreis += ( o_Item.opreis - o_Item.uvp ) ;
	 }.bind(this) );
	this.o_Discount.each ( function ( o_Item ){ f_Discount += this.fn_Float ( o_Item ); }.bind(this) );

    var f_Gesamtpreis = this.f_Preis + this.f_Grundpreis - f_NeuerPreis + f_Discount;
    var s_MwstAnteil = this.float2euro ( ( f_Gesamtpreis / ( 100 + this.f_Mwst ) ) * this.f_Mwst, 2 );

    var s_Preis = this.float2euro ( ( this.f_Preis - f_NeuerPreis ), 2 ); 
    
	var f_NeuerPreis = 0.00;
	var f_Discount = 0.00;

	var s_Gesamtpreis = this.float2euro ( ( f_Gesamtpreis - f_NeuerPreis ), 2 );
    
    
    /** Nettocode var s_MwstAnteil = float2euro ( ( (f_Gesamtpreis * this.f_Mwst ) / 100 ), 2 ); **/  
    $$("span.Aufpreis").each ( function ( o_Item ){ o_Item.update ( s_Preis ); } );
    $$("span.Gesamtpreis").each ( function ( o_Item ){ o_Item.update ( s_Gesamtpreis ); } );
    $$("span.MwstAnteil").each ( function ( o_Item ){ o_Item.update ( s_MwstAnteil ); } );
	$$("span.Discount").each ( function ( o_Item ) { o_Item.update ( this.float2euro ( f_Discount , 2 ) ); }.bind(this) );

	/**
	 * DBF-Voodoo
     * Ist der DBF-Modus aktiviert, gebe die Ersparnis aus
     */
    if ( this.b_Dbf === true ){
        var f_Gesamtpreis_nu = f_Gesamtpreis - this.f_Ueberfuehrung;
        var f_UvpGesamt = this.f_Uvp + this.f_ZubehoerUvp  + f_NeuerPreis + f_Discount;
        var f_Ersparnis = f_UvpGesamt - f_Gesamtpreis_nu;
        var f_ErsparnisProzent = 100 - ( ( f_Gesamtpreis_nu * 100 ) / f_UvpGesamt );
        
		//alert ( "Ersparnis:" + f_ErsparnisProzent + " f_UvpGesamt:" + f_UvpGesamt + " f_ErsparnisProzent:" + f_ErsparnisProzent );
        var o_Tpl1 = this.o_Ausgabetexte.ErsparnisProzent; 
        var o_Tpl2 = this.o_Ausgabetexte.Ersparnis;
        
	// EPK Uvp Gesamt
	$$("span.uvp_gesamt").each ( function ( o_Item ){ o_Item.update ( this.float2euro ( f_UvpGesamt, 2 ) ); }.bind(this));

        if ( f_Ersparnis > 0 ){
            $$("td.uvp").each ( function ( o_Item ){ o_Item.update ( o_Tpl1.evaluate( { ErsparnisProzent: this.float2euro ( f_ErsparnisProzent, 2 ), UvpGesamt: this.float2euro ( f_UvpGesamt, 2 ) } ) ); }.bind(this) ); 
            $$("td.uvp_preis").each ( function ( o_Item ){ o_Item.update ( o_Tpl2.evaluate( { Ersparnis: this.float2euro ( f_Ersparnis, 2 ) } ) ); }.bind(this) ); 
            } else {
                $$("td.uvp").each ( function ( o_Item ){ o_Item.update ( "" ); } );
                $$("td.uvp_preis").each ( function ( o_Item ){ o_Item.update ( "" ); } );
                }
        }

    };

/**
 * Setzt den Zubehoer-Aufpreis auf 0
 */
ClassZubRechner.prototype.reset = function (){
    this.f_Preis = 0.00;
    this.o_NeuerPreis = [];
	this.o_Discount = [];
	
    this.show();
	$$("input[id^='zub']").each( function( o_Item ) { 
		o_Item.checked=false;
		var o_Zubehoer = this.daten( o_Item.value );
		o_Zubehoer.typ = '';
		o_Zubehoer.apreis = o_Zubehoer.preis; 
		this.schreibeDaten ( o_Item, o_Zubehoer );
		
		var o_Zubpreis = $( "zpreis" + o_Zubehoer.id );
		o_Zubpreis.update ( this.float2euro ( o_Zubehoer.preis, 1 ) );
		}.bind(this) );

	this.JatoInit();
    };

/**
 * Ließt die Problemfälle (Ausschluss) aus der Tabelle
 * @param string Zubehoer-Id
 * @return array Report
 */
ClassZubRechner.prototype.Probe = function ( a_Problem ){
    var daten = this.daten;
    var myTemplate = new Template( this.s_Ausschlusstext );
    var a_Kategorie = this.a_Kategorie;

    a_Problem.each(function(s_Key) { 
        var o_Daten = $( "zub"+s_Key );
        var o_Quelle = ( o_Daten === null ) ? {id:'0', aus:'', preis:'0.00', kat:'0'} : daten ( o_Daten.value );
        
        var o_Zubtext = $( "ztxt" + s_Key );
        var o_Show = {Zubehoer: o_Zubtext.innerHTML.unescapeHTML(), Kategorie: a_Kategorie[ o_Quelle.kat ] };
        alert( myTemplate.evaluate(o_Show) ); 
        });
    
    return true;
    };

/**
 * Prüft, ob es zu Abhängigkeiten kommt
 * @param string Ausschlusswerte
 * @return boolean ja/nein
 */  
ClassZubRechner.prototype.checkAusschluss = function( s_Ausschluss ){
    var b_Exit = false;
    var a_Problem = [];
    $w( s_Ausschluss ).each(function( s_Key ){
        var o_Checkbox = $( "zub" + s_Key );
        if ( o_Checkbox !== null ){ 
            if ( o_Checkbox.checked === true ) { a_Problem[a_Problem.length]=s_Key; }
            }
        });
    if ( a_Problem.length > 0 ){ b_Exit = this.Probe( a_Problem ); }
    return b_Exit;
    };



/**
 * checkAktiv
 * zeigt, ob ein Zubehoer angewaehlt ist
 * @param string Id
 * @return bolean;
 */
ClassZubRechner.prototype.checkAktiv = function ( s_Id, b_InvertCheck, a_CheckId ){

if ( s_Id == a_CheckId[2] && a_CheckId[3] === true ){ return b_InvertCheck ? false : true; }

var o_Checkbox = $( "zub" + s_Id );
    if ( o_Checkbox !== null ){
        /** pruefe gewaehlte Dialoge **/
        if ( !Object.isUndefined( this.o_DialogCheck [ s_Id ] )){ 
            if ( this.o_DialogCheck [ s_Id ][1] === true ) { return b_InvertCheck ? false : true; } }
        /** vorher gewaehlte Dialoge **/ 
		if ( !Object.isUndefined( this.o_CheckboxStatus[ a_CheckId[0] ][s_Id] ) ){
			if ( this.o_CheckboxStatus[ a_CheckId[0] ][s_Id][1]=== true ) { return b_InvertCheck ? false : true; } 
			}
        else { if ( o_Checkbox.checked === true ) { return b_InvertCheck ? false : true; } }
        }
return b_InvertCheck ? true : false;
}


/**
 * checkRegel
 * prueft eine AND / OR / NOT - Regel auf Wahrheit
 * @param string Regel
 * @param bolean 
 * @return object { ids: [array aller Ids],  wahr: bolean }
 */
ClassZubRechner.prototype.checkRegel = function ( s_Regel, b_InvertCheck, a_CheckId ){

/* 
 * Zerlege Regel in Zubehoer Ids, ersetze Ids durch Checkstatus
 * Beispiel: Regel:    1234&&3454&&322||32322
 *           Ergebnis: true&&false&&true||true
 *           true or false ist der Checkstatus des Elements
 */
var a_Ids = [];
var a_Id_true = [];
var a_Id_false = [];

var s_Regelcheck = s_Regel.replace(/\d+/g, function( Treffer ){ 
	a_Ids.push( Treffer );
	var b_Status = this.checkAktiv( Treffer, b_InvertCheck, a_CheckId );
	if ( b_Status === true ){ a_Id_true.push ( Treffer ); } else { a_Id_false.push ( Treffer ); }
	
	/** pruefe, ob angewaehlt **/
	return b_Status;
	}.bind(this) );

/* keine leere Regel? dann pruefe Regel auf Ergebnis */
if ( s_Regelcheck != "" ){
	/** erstelle Pruefregel-Funktion und teste Regel **/
	f_Check = new Function ('{return (' +s_Regelcheck+') ? true : false; }');
	return { ids: a_Ids, id_true: a_Id_true , id_false: a_Id_false, wahr: f_Check() };
	}

/** keine Regel, also wahr **/
return {ids: a_Ids, id_true: a_Id_true , id_false: a_Id_false, wahr: true};
}

/**
 * fn.holeJatoOptionen()
 * holt die notwendigen Regeln fuer ein
 * Zubehoer ab
 * @param string ZubehoerId
 * @return object {E:[],I:[],R:[],P:[],D:[]
 * @author Elko Panzyk, Panzyk Networks
 */
ClassZubRechner.prototype.holeJatoOptionen = function ( i_Id ){
	var a_OptIndex = this.o_Jato.Index [ i_Id ];
	var o_Optionen = { E:[], I:[], R:[], P:[], D:[] };

	/** gibt es Regeln ? **/
	if ( !Object.isUndefined( a_OptIndex ) ){

		/** ja, pruefe Regeln und sammle alle Abhaengigkeiten **/
		a_OptIndex.each( function( s_Key ){
			
			switch ( this.o_Jato.Optionen[ s_Key ][1] ){
				/** Exclude **/
				case "E": o_Optionen.E.push( s_Key ); break;
				/** Include **/
				case "I": o_Optionen.I.push( s_Key ); break;
				/** Benoetigt **/
				case "R": o_Optionen.R.push( s_Key ); break;
				/** Neuer Preis **/
				case "P": o_Optionen.P.push( s_Key ); break;
				/** Discount **/
				case "D": o_Optionen.D.push( s_Key ); break;
				}			
			}.bind(this) );	
		}

return o_Optionen;
}

/**
 * fn.JatoInit()
 * Funktion, die Rekursiv Zubehoer abwaehlt
 * @return object Arbeitsprozess-Object
 * @author Elko Panzyk, Panzyk Networks
 */
ClassZubRechner.prototype.JatoInit = function (){
	var o_Check = { id: [ "Init", true, 'x', false ], an:[], aus:[], discount:[], preis:[], Abhaengig: true };
	this.o_CheckboxStatus [ "Init" ] = [];

		$$("input[id^='zub']").each( function( s_ZubKey ){
			var s_Id = s_ZubKey.id.substring(3);

			var b_Abhaengig = true;
			/** Ist die Checkbox gesetzt? **/
			if ( this.checkAktiv ( s_Id, false, o_Check.id ) ){
				var o_Optionen = this.holeJatoOptionen( s_Id );
				
				/** Teste Hauptregel auf Wegfall von Bedingungen **/
				o_Optionen.R.each ( function ( s_Key ){
					var o_Abhaengig = this.checkRegel ( this.o_Jato.Optionen[ s_Key ][2], false, o_Check.id );
					var o_Regel = this.checkRegel ( this.o_Jato.Optionen[ s_Key ][3], false, o_Check.id );
					if ( o_Abhaengig.wahr && !o_Regel.wahr ){ o_Check = this.JatoAus ( s_Id, o_Check ); b_Abhaengig = false; }
					}.bind(this));
				
				/** teste Excludes auf Wegfall von Bedingungen **/
				if ( b_Abhaengig === true ){
					o_Optionen.E.each ( function ( s_Key ){
						var o_Abhaengig = this.checkRegel ( this.o_Jato.Optionen[ s_Key ][2], false, o_Check.id );
						var o_Regel = this.checkRegel ( this.o_Jato.Optionen[ s_Key ][3], true, o_Check.id );
						// Abhängigkeiten ja, Excludes nein? -> Abwahl der der Checkbox
						if ( o_Abhaengig.wahr && !o_Regel.wahr ){ o_Check = this.JatoAus ( s_Id, o_Check ); b_Abhaengig = false; }
						}.bind(this));

					/** Teste Includes auf Wegfall von Bedingungen **/
					if ( b_Abhaengig === true ){
						o_Optionen.I.each ( function ( s_Key ){
							var o_Abhaengig = this.checkRegel ( this.o_Jato.Optionen[ s_Key ][2], false, o_Check.id );
							var o_Regel = this.checkRegel ( this.o_Jato.Optionen[ s_Key ][3], false, o_Check.id );
							// Alle Regeln vorhanden, also muessen die Includes angewaehlt sein
							if ( o_Abhaengig.wahr && o_Regel.wahr ){ o_Regel.ids.each ( function ( s_Key ){ o_Check.an.push ( s_Key ); } ); }
							// Abhaengigkeiten nicht mehr gegeben?, Abwaehlen ... 
							if ( o_Abhaengig.wahr && !o_Regel.wahr ){ o_Check = this.JatoAus ( s_Id, o_Check ); b_Abhaengig = false; }
							}.bind(this));
						} // EndIF
					} // EndIF
				
					
					/** Noch Fleisch vorhanden? dann prüfe ob Preisregeln existieren **/
					if ( b_Abhaengig ){
						/** 
						 * Prüfe Preis Regeln 
						 */
						o_Optionen.P.each ( function ( s_Key ){
							var o_Abhaengig = this.checkRegel ( this.o_Jato.Optionen[ s_Key ][2], false, o_Check.id );
							var o_Regel = this.checkRegel ( this.o_Jato.Optionen[ s_Key ][3], false, o_Check.id );
							if ( !o_Abhaengig.wahr || !o_Regel.wahr ){ o_Check.preis [s_Id] = [ s_Id, false, s_Key ]; }
							if ( o_Abhaengig.wahr && o_Regel.wahr ){ o_Check.preis [s_Id] = [ s_Id, true, s_Key ]; }
							} .bind(this) );

						/** 
						 * Prüfe Discount Regeln 
						 */
						o_Optionen.D.each ( function ( s_Key ){
							var o_Abhaengig = this.checkRegel ( this.o_Jato.Optionen[ s_Key ][2], false, o_Check.id );
							var o_Regel = this.checkRegel ( this.o_Jato.Optionen[ s_Key ][3], false, o_Check.id );
							if ( !o_Abhaengig.wahr || !o_Regel.wahr ){ o_Check.discount [s_Id] = [ s_Id, false, s_Key ]; }
							if ( o_Abhaengig.wahr && o_Regel.wahr ){ o_Check.discount [s_Id] = [ s_Id, true, s_Key ]; }
							} .bind(this) );
					}		
				} // EndIF
			
			}.bind(this));
 
 this.zeigeAenderungen ( "Init", o_Check );
 delete this.o_CheckboxStatus [ "Init" ];
 return o_Check;
 }


/**
 * fn.JatoAus()
 * Funktion, die Rekursiv Zubehoer abwaehlt
 * @param string ZubehoerId
 * @param object Arbeitsprozess-Objekt
 * @return object Arbeitsprozess-Object
 * @author Elko Panzyk, Panzyk Networks
 */
ClassZubRechner.prototype.JatoAus = function ( i_Id, o_Check, b_Fullcheck ){
//console.log ( "JatoAus:" + i_Id );

	/** Verwerfe Checks, wenn nicht angewählt **/
	//if ( this.checkAktiv ( i_Id, true, o_Check.id ) && o_Check.id[0] != i_Id ){ return o_Check; }

	/** Schritt 1: schalte Checkbox aus **/
	var o_Checkbox = $( "zub" + i_Id );
	if ( o_Checkbox !== null ){
			this.o_CheckboxStatus[ o_Check.id[0] ][ i_Id ]= [ i_Id, false ];
			o_Check.aus.push( i_Id );
			} 
	
	/** Preis, Discount entfernen **/
	var o_OptionenAus = this.holeJatoOptionen( i_Id );
	o_OptionenAus.P.each ( function ( s_Key ){ o_Check.preis [i_Id] = [ i_Id, false, s_Key ]; } );
	o_OptionenAus.D.each ( function ( s_Key ){ o_Check.discount [i_Id] = [ i_Id, false, s_Key ]; } );

	var a_RefIndex = this.o_Jato.Ref [ i_Id ];
    var a_Excludes = [];
    
	/** Pruefe alle Zubehoer-Elemente in denen die Id vorkommt **/
	if ( !Object.isUndefined( a_RefIndex ) ){
		a_RefIndex.each( function( s_ZubKey ){
			
			var b_Abhaengig = true;
			
			/** Ist die Checkbox gesetzt? **/
			if ( this.checkAktiv ( s_ZubKey, false, o_Check.id ) ){

				var o_Optionen = this.holeJatoOptionen( s_ZubKey );
				
				/** Teste Hauptregel auf Wegfall von Bedingungen **/
				o_Optionen.R.each ( function ( s_Key ){
					var o_Abhaengig = this.checkRegel ( this.o_Jato.Optionen[ s_Key ][2], false, o_Check.id );
					var o_Regel = this.checkRegel ( this.o_Jato.Optionen[ s_Key ][3], false, o_Check.id );
					if ( o_Abhaengig.wahr && !o_Regel.wahr ){ 
					    a_Excludes.push ( s_ZubKey );
					    //console.log ( "Call JatoAus from JatoAus Hauptregeltest" );
					    o_Check = this.JatoAus ( s_ZubKey, o_Check ); 
					    b_Abhaengig = false; }
					    }.bind(this));
				
				/** teste Excludes auf Wegfall von Bedingungen **/
				if ( b_Abhaengig === true ){
					o_Optionen.E.each ( function ( s_Key ){
						var o_Abhaengig = this.checkRegel ( this.o_Jato.Optionen[ s_Key ][2], false, o_Check.id );
						var o_Regel = this.checkRegel ( this.o_Jato.Optionen[ s_Key ][3], true, o_Check.id );
						if ( o_Abhaengig.wahr && !o_Regel.wahr ){ 
						    a_Excludes.push ( s_ZubKey );
						    //console.log ( "Call JatoAus from JatoAus Excludetest" );
						    o_Check = this.JatoAus ( s_ZubKey, o_Check ); 
						    b_Abhaengig = false; }
						}.bind(this));
					
					/** Teste Includes auf Wegfall von Bedingungen **/
					if ( b_Abhaengig === true ){
						o_Optionen.I.each ( function ( s_Key ){
							var o_Abhaengig = this.checkRegel ( this.o_Jato.Optionen[ s_Key ][2], false, o_Check.id );
							var o_Regel = this.checkRegel ( this.o_Jato.Optionen[ s_Key ][3], false, o_Check.id );
							if ( o_Abhaengig.wahr  && !o_Regel.wahr ){
							    a_Excludes.push ( s_ZubKey ); 
							    //console.log ( "Call JatoAus from JatoAus Includetest" );
							    o_Check = this.JatoAus ( s_ZubKey, o_Check ); 
							    b_Abhaengig = false; }
							}.bind(this));
						} // EndIF
					} // EndIF
				
				    
					
					/** Noch Fleisch vorhanden? dann prüfe ob Preisregeln existieren **/
					if ( b_Abhaengig ){
						/** 
						 * Prüfe Preis Regeln 
						 */
						o_Optionen.P.each ( function ( s_Key ){
							var o_Abhaengig = this.checkRegel ( this.o_Jato.Optionen[ s_Key ][2], false, o_Check.id );
							var o_Regel = this.checkRegel ( this.o_Jato.Optionen[ s_Key ][3], false, o_Check.id );
							if ( !o_Abhaengig.wahr || !o_Regel.wahr ){ o_Check.preis [ s_ZubKey ] = [ s_ZubKey, false, s_Key ]; }
							if ( o_Abhaengig.wahr && o_Regel.wahr ){ o_Check.preis [ s_ZubKey ] = [ s_ZubKey, true, s_Key ]; }
							} .bind(this) );

						/** 
						 * Prüfe Discount Regeln 
						 */
						o_Optionen.D.each ( function ( s_Key ){
							var o_Abhaengig = this.checkRegel ( this.o_Jato.Optionen[ s_Key ][2], false, o_Check.id );
							var o_Regel = this.checkRegel ( this.o_Jato.Optionen[ s_Key ][3], false, o_Check.id );
							if ( !o_Abhaengig.wahr || !o_Regel.wahr ){ o_Check.discount [ s_ZubKey ] = [ s_ZubKey, false, s_Key ]; }
							if ( o_Abhaengig.wahr && o_Regel.wahr ){ o_Check.discount [ s_ZubKey ] = [ s_ZubKey, true, s_Key ]; }
							} .bind(this) );
					}		
				} // EndIF
			
			}.bind(this));
		}

 return o_Check;
 }


ClassZubRechner.prototype.JatoZeigeDialogRegel = function ( s_Id, o_Check, s_Regel, b_CheckTyp ){
    var i_Zaehler = 0;
    var s_Ausgabe	= "";
    var i_Box = 0;
    var b_CheckTyp = b_CheckTyp ? true : false;
    var i_Zebra = 0;
    
	/** zerlege Regel in Teile Zahlen, &&, !, ||, (, ) und verarbeite diese **/  
	s_Regel.replace(/\d+/g, function( s_Treffer ){ 
        
        
		i_Zaehler++;
		/** and, or, not, open, close, row **/
		switch ( s_Treffer ){
			default: 
				/** Zahl, gibt es eine Checkbox? **/
				var o_Checkbox = $( "zub" + s_Treffer );
				if ( o_Checkbox !== null ){ 
					
					i_Box++;
					this.Pruefungen ( s_Treffer, "HR ELEMENTE" );
					
					/** hole Zubehoertext & Preis **/
					var o_Zubtext = $( "ztxt" + s_Treffer );
					var s_ZubtextKurz = "";
					$$( "#ztxt" + s_Treffer +" span.kbez" ).each ( function( o_Element ){ s_ZubtextKurz += o_Element.innerHTML; } );

					var o_Zubpreis = $( "zpreis" + s_Treffer );
					
					var b_Checkstatus = this.checkAktiv ( s_Treffer, false, o_Check.id );
					
					i_Zebra++;
					
					/** Template Elemente **/
					var o_Show = { 
					    Zubehoer: s_ZubtextKurz,
					    Zebra:           (i_Zebra % 2)
					    };
					
					/** Template verschmelzung und add **/
					if ( b_Checkstatus === b_CheckTyp ){
					    s_Ausgabe += this.o_Ausgabetexte.liste.evaluate(o_Show);
					    }
					}
				break;
			}
		}.bind(this) );
	
	return {ausgabe: s_Ausgabe, anzahl: i_Zaehler };
    }

/**
 * Dialog Return ...
 */
ClassZubRechner.prototype.JatoIncludeExcludeClick = function (){
 
	Dialogs.close();
	
	this.b_Stop = false;
	this.o_TempCheck.Abhaengig = true;
	/** true erzeugt stackmode ... **/
	var o_Check = this.bereinigeStack( this.o_Dialogdaten.id, this.o_TempCheck, true );
		if ( this.b_Stop === true ){ 
			
			/** Sichere o_Check zwischen **/
			this.zeigeDialog ( o_Check );
			return false;
			}
	
	/** Zwischenspeicher wieder Loeschen **/
	o_Check = this.JatoAn ( this.o_Ersteinstieg_Id , o_Check );
	this.a_Stack = [];
    this.o_TempCheck = [];
    	
	this.zeigeAenderungen( 0, o_Check );
    }
    
/**
 * Include, Exclude Dialog
 * gibt eine Meldung aus, das zus. Zubehoer eingebunden wird
 * @param string s_Id
 * @param o_Check
 * @param b_Stack
 */
ClassZubRechner.prototype.JatoIncludeExcludeDialog = function ( s_Id, o_Check ){

/** Stop Rekursion **/
this.b_Stop = true;

/** Speichere den Herkunftsort des Dialogs **/
this.o_TempCheck = o_Check;

var o_Optionen = this.holeJatoOptionen( this.o_Dialogdaten.id );
var s_Auswahltabelle = "";
var b_Hauptregel = false;
    
	/** lese Require - Regeln und erzeuge Tabelle **/
	o_Optionen.I.each ( function ( s_Key ){
		var o_Abhaengig = this.checkRegel ( this.o_Jato.Optionen[ s_Key ][2], false, [ 0, true ] );
		var o_Regel		= this.checkRegel ( this.o_Jato.Optionen[ s_Key ][3], false, [ 0, true ] );
		var s_Regel		= this.o_Jato.Optionen[ s_Key ][3];
		var i_Zaehler	= 0;
		var s_Ausgabe	= "";
        var o_DialogRegel = this.JatoZeigeDialogRegel ( this.o_Dialogdaten.id, o_Check, s_Regel, true );
        
        s_Ausgabe += this.o_Ausgabetexte.include; 
        s_Ausgabe += o_DialogRegel.ausgabe;
		s_Auswahltabelle += this.o_Ausgabetexte.taopen + s_Ausgabe + this.o_Ausgabetexte.taclose;
		
		}.bind(this));

    
    /** lese Require - Regeln und erzeuge Tabelle **/
	o_Optionen.E.each ( function ( s_Key ){
		var o_Abhaengig = this.checkRegel ( this.o_Jato.Optionen[ s_Key ][2], false, [ 0, true ] );
		var o_Regel		= this.checkRegel ( this.o_Jato.Optionen[ s_Key ][3], false, [ 0, true ] );
		var s_Regel		= this.o_Jato.Optionen[ s_Key ][3];
		var i_Zaehler	= 0;
		var s_Ausgabe	= "";
		var o_DialogRegel = this.JatoZeigeDialogRegel ( s_Id, o_Check, s_Regel, false );

        s_Ausgabe += this.o_Ausgabetexte.exclude;
        s_Ausgabe += o_DialogRegel.ausgabe;
		s_Auswahltabelle += this.o_Ausgabetexte.taopen + s_Ausgabe + this.o_Ausgabetexte.taclose;
		
		}.bind(this));
		
	s_Auswahltabelle = this.o_Ausgabetexte.button + s_Auswahltabelle + this.o_Ausgabetexte.button;
	
	/** lösche alle Dialoge **/
	Dialogs.close();
	this.o_Dialog = new Dialog({
				handle:'dialog',
				title:'Folgende Abhaengigkeiten haben sich ergeben {'+this.o_Dialogdaten.id+'}:',
				width:600,
				content: s_Auswahltabelle,
				/** aktiviere Checkboxen **/
				afterOpen:function(){ 
				    $$("#but_Uebernehmen").each( function (o_Item ){ o_Item.observe('click', IncludeExcludeClick ); } ); 
				    $$("#but_Abbrechen").each( function (o_Item ){ o_Item.observe('click', Abbrechen ); } );
				    }
			});
	
	this.o_Dialog.open();

}

    ClassZubRechner.prototype.checkJatoAnAbschluss = function( i_Id, o_Check ){
		var o_Optionen = this.holeJatoOptionen( i_Id );
		
		/** 
		 * Stufe 4: 
         * Prüfe Abhaengigkeiten
		 */
		if ( !Object.isUndefined( this.o_Jato.Ref [ i_Id ] ) ){
			this.o_Jato.Ref [ i_Id ].each ( function ( s_Key ){
				var b_Ref = true;
				/** Ist die Checkbox gesetzt? **/
				if ( this.checkAktiv ( s_Key, false, o_Check.id ) ){ 
					//console.log ( "--- check:" + s_Key + " === " + ( this.checkAktiv ( s_Key, false, o_Check.id ) ? "checked" : "not checked" ) );
					var o_OptionenRef = this.holeJatoOptionen( s_Key );

					o_OptionenRef.R.each ( function ( i_Index ){ 
						var o_Abhaengig = this.checkRegel ( this.o_Jato.Optionen[ i_Index ][2], false, o_Check.id );
						var o_Regel = this.checkRegel ( this.o_Jato.Optionen[ i_Index ][3], false, o_Check.id );
						//console.log ( "Regelabhaengigkeit:"+this.o_Jato.Optionen[ i_Index ][0]+" (" + o_Abhaengig.wahr + "):" + this.o_Jato.Optionen[ i_Index ][2] + "\n-->(" + o_Regel.wahr + "):" + this.o_Jato.Optionen[ i_Index ][3] );

						if ( o_Abhaengig.wahr && !o_Regel.wahr ){  b_Ref = false; }
						}.bind(this));

					if ( b_Ref === true ){
					o_OptionenRef.E.each ( function ( i_Index ){ 
						var o_Abhaengig = this.checkRegel ( this.o_Jato.Optionen[ i_Index ][2], false, o_Check.id );
						var o_Regel = this.checkRegel ( this.o_Jato.Optionen[ i_Index ][3], true, o_Check.id );
						//console.log ( "Excludeabhaengigkeit:"+this.o_Jato.Optionen[ i_Index ][0]+" (" + o_Abhaengig.wahr + "):" + this.o_Jato.Optionen[ i_Index ][2] + "\n-->(" + o_Regel.wahr + "):" + this.o_Jato.Optionen[ i_Index ][3] );

						if ( o_Abhaengig.wahr && !o_Regel.wahr ){ 
							b_Ref = false; }
						}.bind(this)); } 

					if ( b_Ref === false ){ /*console.log ( i_Id + "Stufe 4: muss Abhaengigkeit mit: "+s_Key+" aufheben." );*/ o_Check = this.JatoAus ( s_Key, o_Check ); }
					}
				}.bind(this));
			}

		/** 
		 * Stufe 5: 
         * Prüfe Neuer Preis Regeln 
		 */
		o_Optionen.P.each ( function ( s_Key ){
			var o_Abhaengig = this.checkRegel ( this.o_Jato.Optionen[ s_Key ][2], false, o_Check.id );
			var o_Regel = this.checkRegel ( this.o_Jato.Optionen[ s_Key ][3], false, o_Check.id );
			if ( !o_Abhaengig.wahr || !o_Regel.wahr ){ o_Check.preis [i_Id] = [ i_Id, false, s_Key ]; }
			if ( o_Abhaengig.wahr && o_Regel.wahr ){ o_Check.preis [i_Id] = [ i_Id, true, s_Key ]; }
			} .bind(this) );

		/** 
		 * Stufe 6:
		 * Prüfe Discount Regeln 
		 */
		o_Optionen.D.each ( function ( s_Key ){
			var o_Abhaengig = this.checkRegel ( this.o_Jato.Optionen[ s_Key ][2], false, o_Check.id );
			var o_Regel = this.checkRegel ( this.o_Jato.Optionen[ s_Key ][3], false, o_Check.id );
			if ( !o_Abhaengig.wahr || !o_Regel.wahr ){ o_Check.discount [i_Id] = [ i_Id, false, s_Key ]; }
			if ( o_Abhaengig.wahr && o_Regel.wahr ){ o_Check.discount [i_Id] = [ i_Id, true, s_Key ]; }
			} .bind(this) );
		
	return o_Check;
	}



















	
/**
 * fn.JatoAn()
 * Funktion, die Rekursiv Zubehoer anwaehlt
 * @param string ZubehoerId
 * @param object Arbeitsprozess-Objekt
 * @return object Arbeitsprozess-Object
 * @author Elko Panzyk, Panzyk Networks
 */
ClassZubRechner.prototype.JatoAn = function ( i_Id, o_Check, b_Stack ){
//console.log ( "fn_JatoAn ( " + i_Id + " ) StackLevel: ( " + this.o_JatoStack.length + " )" );

if ( this.b_Stop === true ) { return o_Check; }

/** Include Id fuer Loops */
var s_Include_Id = "";
var s_Exclude_Id = "";
var a_Includes = [];
var a_Excludes = [];
 
/** 
 * ist der b-Stack=true muss zuerst der Include-Stack abgearbeitet werden ... 
 * die Routine ist ja bei einer Require-Regel ausgestiegen, also kann es sein,
 * das noch Includes auf dem Stack liegen, die noch nicht verarbeitet wurden
 * jeder Dialog steigt mit True-Ein, und kann so die Rekursion aufrecht erhalten
 */
 
	var o_Optionen = this.holeJatoOptionen( i_Id );
	var b_Abhaengig = true;
    
	/**
	 * Muss-Haben Regel 
	 * Stufe 1: Prüfe Require Regeln, Oberste Priorität
     * Wenn diese Regeln nicht übereinstimmen, sofortiger Abbruch, und Fenster zeigen
	 *
	 **/
	o_Optionen.R.each ( function ( s_Key ){
		var o_Abhaengig = this.checkRegel ( this.o_Jato.Optionen[ s_Key ][2], false, o_Check.id );
		var o_Regel = this.checkRegel ( this.o_Jato.Optionen[ s_Key ][3], false, o_Check.id );
		if ( o_Abhaengig.wahr && !o_Regel.wahr ){ 
		    /** zeige Dialog **/
		    b_Abhaengig = false; 
			o_Check.Abhaengig = false;
			o_Check.DialogId = i_Id;
			this.o_Dialogdaten = { art: "RIE", von: "An", id: i_Id };
			this.b_Stop = true;
			//console.log ( "Abhaengigkeit erkannt in: ( "+this.o_Dialogdaten.id+" ), Dialog-Fenster vorgemerkt.\nRegel: "+this.o_Jato.Optionen[ s_Key ][3] );
			}
		} .bind(this) );

	/** Dialog **/
	if ( b_Abhaengig === false ){ return o_Check; }
	
	/** Kein Dialogeinstieg und es gibt es Includes oder Excludes? **/
	if ( b_Stack !== true &&( o_Optionen.I.length > 0 || o_Optionen.E.length > 0 ) ){
	
	    var b_Dialog_check = false;
	    o_Optionen.I.each ( function( s_Key ){ 
	        if ( this.o_Jato.Optionen[ s_Key ][3] !== "" ){ b_Dialog_check = true; } 
	        }.bind(this));
	    
	    o_Optionen.E.each ( function( s_Key ){ 
	        if ( this.o_Jato.Optionen[ s_Key ][3] !== "" ){ b_Dialog_check = true; }
	        }.bind(this));
	    
	    // wenn excluderegeln oder includeregeln prueftauglich dann dialog zeigen
	    if ( b_Dialog_check === true ){
	        this.o_Dialogdaten = { art: "IE", von: "An", id: i_Id };
	        this.b_Stop = true;
	        }
	    //console.log ( "Includes und/oder Excludes erkannt in: ( "+this.o_Dialogdaten.id+" ), Dialog-Fenster vorgemerkt." );
	    }
 
	if ( this.b_Stop === true ) { return o_Check; }
	if ( b_Abhaengig === true ){ 
	    this.o_DialogCheck.each ( function ( a_Element  ) { 
	        if ( Object.isUndefined( a_Element ) === true ){ return; }
	        //console.log ( "Per Dialog Gewaehlt: " + a_Element[0] + " = " + a_Element[1] ); 
	        if ( a_Element[1] === true ){ 
	            a_Includes.push ( a_Element[0] ); 
	            this.o_CheckboxStatus[ o_Check.id [0] ][ a_Element[0] ]= [ a_Element[0], true ];
	            } else { a_Excludes.push ( a_Element[0] ); 
	                this.o_CheckboxStatus[ o_Check.id [0] ][ a_Element[0] ]= [ a_Element[0], false ];
	                }
	        }.bind(this) );
	   
		/** Require-Regel trifft zu ... **/
		var o_Checkbox = $( "zub" + i_Id );
		if ( o_Checkbox !== null ){
			this.o_CheckboxStatus[ o_Check.id [0] ][ i_Id ] = [ i_Id, true ];
			/*o_Check.an.push( i_Id );*/ }

		/** 
		 * Stufe 2:
		 * Prüfe Include Regeln (AN)
		 * Dinge, die dringend benötigt werden, z.b. Packet 
		 */
		o_Optionen.I.each ( function ( s_Key ){
			var o_Abhaengig = this.checkRegel ( this.o_Jato.Optionen[ s_Key ][2], false, o_Check.id );
			var o_Regel = this.checkRegel ( this.o_Jato.Optionen[ s_Key ][3], false, o_Check.id );
			var b_ExcludeCheck = true;
			
			/** Alle Includes anwählen **/
			if ( o_Abhaengig.wahr ){ o_Regel.ids.each ( function ( s_Key ){ o_Check.an.push ( s_Key ); } ); }
			if ( o_Abhaengig.wahr && !o_Regel.wahr ){ 
			    // statt ids, alternativ id_false
			    //console.log ( "Includes ( "+i_Id+" ):\ntrue:"+o_Regel.id_true+"\nfalse:" + o_Regel.id_false + "\nall:" + o_Regel.ids );
				o_Regel.id_false.each ( function ( s_Key ){ 
	                this.o_CheckboxStatus[ o_Check.id [0] ][ s_Key ]= [ s_Key, true ];
	                a_Includes.push ( s_Key );
	                }.bind(this));
				}
			} .bind(this) );

		/** 
		 * Stufe 3:
		 * Prüfe Exclude Regeln (AUS)
		 * Dinge, die nicht enthalten sein dürfen, Ausschluss 
		 */
		o_Optionen.E.each ( function ( s_Key ){
			var o_Abhaengig = this.checkRegel ( this.o_Jato.Optionen[ s_Key ][2], false, o_Check.id );
			var o_Regel = this.checkRegel ( this.o_Jato.Optionen[ s_Key ][3], true, o_Check.id );

			/** Alle Excludes abwählen **/
			if ( o_Abhaengig.wahr && !o_Regel.wahr ){ 
			    // statt ids, id_false
			    //console.log ( "Excludes ( "+i_Id+" ):\ntrue:"+o_Regel.id_true+"\nfalse:" + o_Regel.id_false + "\nall:" + o_Regel.ids );
				o_Regel.id_false.each ( function ( s_Key ){
				    this.o_CheckboxStatus[ o_Check.id [0] ][ s_Key ]= [ s_Key, false ];
				    a_Excludes.push ( s_Key );
				    }.bind(this));
				}
			} .bind(this) );

        this.o_DialogCheck = [];
            
        /**
         * Packe neue Includes und Excludes in den Stack
         */
         //console.log ( "STACK LEVEL ++" );
         this.o_JatoStack.push( { i:a_Includes, e:a_Excludes, id: i_Id, stack: b_Stack } );
         
         /** Gibt es Daten auf dem Stack ? **/
         if ( this.o_JatoStack.length !== 0){
         //console.log ( "STACK\nStack.Excludes:" +this.o_JatoStack.last().e + "\nStack.Includes:"+this.o_JatoStack.last().i );
         /** Gehe durch den Letzten Exclude-Stack **/
        while ( ( this.o_JatoStack.last().e.length !== 0 || this.b_Stop === true ) ) {
            s_Exclude_Id = this.o_JatoStack.last().e.shift();
            //console.log ( "=== Exclude ( " + s_Exclude_Id + " ) from Stack Level:" + this.o_JatoStack.length ); 
            this.JatoAus( s_Exclude_Id, o_Check );
            if ( this.b_Stop === true ) { break; }
            }
         
         /** Gehe durch den Letzten Include-Stack **/
        while ( ( this.o_JatoStack.last().i.length !== 0 || this.b_Stop === true ) ) {
            s_Include_Id = this.o_JatoStack.last().i.shift();
            //console.log ( "=== Include ( " + s_Include_Id + " ) from Stack Level:" + this.o_JatoStack.length ); 
            this.JatoAn ( s_Include_Id, o_Check );
            if ( this.b_Stop === true ) { break; }
            }
             
             /** Stop-Bit gesetzt, Exit **/    
             if ( this.b_Stop === true ){ return o_Check; } 
             }

    o_Check = this.checkJatoAnAbschluss ( i_Id, o_Check );
    }
    
    this.o_JatoStack.pop();
    //console.log ( "Jato.an #Exit Level:" + this.o_JatoStack.length ); 
	return o_Check;
	}



ClassZubRechner.prototype.bereinigeStack = function( i_Id, o_Check, b_Stack ){
//console.log ( "fn:breinigeStack (" + i_Id + ", o_Check, " + b_Stack + " ) " );
var s_Include_Id = "";
var s_Exclude_Id = "";
var a_Includes = [];
var a_Excludes = [];

this.b_Stop = false;

this.JatoAn ( i_Id, o_Check, b_Stack );

while ( ( b_Stack === true && this.o_JatoStack.length > 0 ) ){ 
     //console.log ( "B-STACK\nStack.Excludes:" +this.o_JatoStack.last().e + "\nStack.Includes:"+this.o_JatoStack.last().i );
    //console.log ( "~ Loop Stack ~" ); 
    /** Gehe durch den Letzten Include-Stack **/
    while ( this.o_JatoStack.last().i.length !== 0 ) {
        s_Include_Id = this.o_JatoStack.last().i.shift();
        //console.log ( "--- Include ( " + s_Include_Id + " ) from Stack Level:" + this.o_JatoStack.length ); 
        this.JatoAn ( s_Include_Id, o_Check, this.o_JatoStack.last().stack  );
        if ( this.b_Stop === true ) { break; }
        }
    
    /** Gehe durch den Letzten Include-Stack **/
    while ( this.o_JatoStack.last().e.length !== 0 ) {
        s_Exclude_Id = this.o_JatoStack.last().e.shift();
        //console.log ( "--- Exclude ( " + s_Exclude_Id + " ) from Stack Level:" + this.o_JatoStack.length ); 
        this.JatoAus( s_Exclude_Id, o_Check );
        if ( this.b_Stop === true ) { break; }
        }
        
    /** Include-Stack-Ebene ist Leer, loesche Ebene **/
    if ( this.b_Stop === true ) { return o_Check; }
    o_Check = this.checkJatoAnAbschluss ( this.o_JatoStack.id, o_Check );
    this.o_JatoStack.pop();
    }
 return o_Check; 
 }



	
/**
 * Prueft Abhaengikeiten im Preis oder Discount-Regelbereich
 */
ClassZubRechner.prototype.checkJatoDiscountPreis = function( i_Id, o_Check ){
//console.log( "JatoDiscount" );
	var a_RefIndex = this.o_Jato.Ref [ i_Id ];

	/** Pruefe alle Zubehoer-Elemente in denen die Id vorkommt **/
	if ( !Object.isUndefined( a_RefIndex ) ){
		a_RefIndex.each( function( s_ZubKey ){
			
			/** Ist die Checkbox gesetzt? **/
			if ( this.checkAktiv ( s_ZubKey, false, o_Check.id ) ){

			var o_Optionen = this.holeJatoOptionen( s_ZubKey );

			/** 
			 * Prüfe Preis Regeln 
			 */
			o_Optionen.P.each ( function ( s_Key ){
				var o_Abhaengig = this.checkRegel ( this.o_Jato.Optionen[ s_Key ][2], false, o_Check.id );
				var o_Regel = this.checkRegel ( this.o_Jato.Optionen[ s_Key ][3], false, o_Check.id );
				if ( !o_Abhaengig.wahr || !o_Regel.wahr ){ o_Check.preis [s_ZubKey] = [ s_ZubKey, false, s_Key ]; }
				if ( o_Abhaengig.wahr && o_Regel.wahr ){ o_Check.preis [s_ZubKey] = [ s_ZubKey, true, s_Key ]; }
				} .bind(this) );

			/** 
			 * Prüfe Discount Regeln 
			 */
			o_Optionen.D.each ( function ( s_Key ){
				var o_Abhaengig = this.checkRegel ( this.o_Jato.Optionen[ s_Key ][2], false, o_Check.id );
				var o_Regel = this.checkRegel ( this.o_Jato.Optionen[ s_Key ][3], false, o_Check.id );
				if ( !o_Abhaengig.wahr || !o_Regel.wahr ){ o_Check.discount [s_ZubKey] = [ s_ZubKey, false, s_Key ]; }
				if ( o_Abhaengig.wahr && o_Regel.wahr ){ o_Check.discount [s_ZubKey] = [ s_ZubKey, true, s_Key ]; }
				} .bind(this) );
			}

		}.bind(this) );
	}
o_Check = this.checkJatoDiscountPreis ( i_Id, o_Check ); 
return o_Check;
}

/**
 * Debugwerte fuer Checkbox
 */
ClassZubRechner.prototype.Pruefungen = function ( s_Id, s_Ausgabe ){

var o_Optionen = this.holeJatoOptionen( s_Id );
s_Ausgabe +="( " + s_Id + " ) ________________\n";
o_Optionen.R.each ( function ( s_Key ){
    s_Ausgabe += "Require:\n";
    s_Ausgabe += "chk:" + this.o_Jato.Optionen[ s_Key ][2] + "\n";
    s_Ausgabe += "reg:" + this.o_Jato.Optionen[ s_Key ][3] + "\n";
}.bind( this ) );

o_Optionen.I.each ( function ( s_Key ){
    s_Ausgabe += "Include:\n";
    s_Ausgabe += "chk:" + this.o_Jato.Optionen[ s_Key ][2] + "\n";
    s_Ausgabe += "reg:" + this.o_Jato.Optionen[ s_Key ][3] + "\n";
}.bind( this ) );

o_Optionen.E.each ( function ( s_Key ){
    s_Ausgabe += "Exclude:\n";
    s_Ausgabe += "chk:" + this.o_Jato.Optionen[ s_Key ][2] + "\n";
    s_Ausgabe += "reg:" + this.o_Jato.Optionen[ s_Key ][3] + "\n";
}.bind( this ) );

s_Ausgabe += "\n";
//console.log ( s_Ausgabe );
}

ClassZubRechner.prototype.erzeugeCondition = function ( s_Regel){
    /**
     * Regeln aufdröseln
     */
    var o_Condition = [];
    var i_Condition = 0;
    var a_Condition_Modus = [ 0 ];
	     
    s_Regel.replace(/\d+|&+|!+|\|+|\(|\)/g, function( s_Treffer ){
    
    if ( Object.isUndefined( o_Condition[ a_Condition_Modus.last() ] ) ){
		     o_Condition[ a_Condition_Modus.last() ] = { typ: '', zid: [] };
		     } 
		         
        switch ( s_Treffer ){
            /** Speichere Logischen Operator **/
            case "&&": o_Condition[ a_Condition_Modus.last() ].typ = "C"; break; /** Checkbox **/
            case "||": o_Condition[ a_Condition_Modus.last() ].typ = "R"; break; /** Radio **/
            /** Condition Stack **/
            case "(":  a_Condition_Modus.push( ++i_Condition ); break;
		    case ")":  a_Condition_Modus.pop(); break;
		    case "!": break;
		    /** Zubehoer-Condition-Level **/
		    default:
		    o_Condition[ a_Condition_Modus.last() ].zid.push( s_Treffer );
		    break; 
		    }
        });
        
    //console.log ( "Condition: " + o_Condition );
    return o_Condition;
    }


/**
 * Ließt die Problemfälle (Ausschluss) aus der Tabelle
 * @param string Zubehoer-Id
 * @return array Report
 * @author Elko Panzyk, Panzyk Networks
 */
ClassZubRechner.prototype.zeigeAbhaengigkeiten = function ( s_Id, o_Check ){
    
    this.o_TempCheck = o_Check;
    this.s_Letzter_Dialog = s_Id;
    this.b_Stop = true;
    
    //this.Pruefungen ( s_Id, "GEW CHECKBOX" );
    
	this.a_AbhaengigkeitenStack.push ( s_Id );
	var o_Optionen = this.holeJatoOptionen( s_Id );
	var s_Auswahltabelle = "";
	var b_Hauptregel = false;
    
	/** lese Require - Regeln und erzeuge Tabelle **/
	o_Optionen.R.each ( function ( s_Key ){
		var o_Abhaengig = this.checkRegel ( this.o_Jato.Optionen[ s_Key ][2], false, [ 0, true ] );
		var o_Regel		= this.checkRegel ( this.o_Jato.Optionen[ s_Key ][3], false, [ 0, true ] );
		var s_Regel		= this.o_Jato.Optionen[ s_Key ][3];
		var i_Zaehler	= 0;
		var i_Zebra     = 0;
		var s_Ausgabe	= "";
		b_Hauptregel = true;
        
        var i_Box = 0;
        
        //console.log ( "HAUPT-REGEL:" + s_Regel + " fuehrt zu einem Konflikt" );
		/** zerlege Regel in Teile Zahlen, &&, !, ||, (, ) und verarbeite diese **/
		
		var o_Condition = this.erzeugeCondition( s_Regel );
		var i_Condition = 0; // Aktuelle Position (Level)
		var a_Condition_Modus = [ 0 ]; // Condition Stack
		  
		s_Regel.replace(/\d+|&+|!+|\|+|\(|\)/g, function( s_Treffer ){ 
            
            
			i_Zaehler++;
			/** and, or, not, open, close, row **/
			switch ( s_Treffer ){
				case "&&": s_Ausgabe += this.o_Ausgabetexte.and;   break;
				case "||": s_Ausgabe += this.o_Ausgabetexte.or;    break;
				case "!":  s_Ausgabe += this.o_Ausgabetexte.not;   break;
				case "(":  s_Ausgabe += this.o_Ausgabetexte.open; a_Condition_Modus.push( ++i_Condition ); break;
				case ")":  s_Ausgabe += this.o_Ausgabetexte.close; a_Condition_Modus.pop(); i_Zebra = 0; break;
				
				default: 
					/** Zahl, gibt es eine Checkbox? **/
					var o_Checkbox = $( "zub" + s_Treffer );
					if ( o_Checkbox !== null ){ 
						
						i_Box++;
						this.Pruefungen ( s_Treffer, "HR ELEMENTE" );
						
						/** hole Zubehoertext & Preis **/
						var o_Zubtext = $( "ztxt" + s_Treffer );
						var s_ZubtextKurz = "";
						$$( "#ztxt" + s_Treffer +" span.kbez" ).each ( function( o_Element ){ s_ZubtextKurz += o_Element.innerHTML; } );

						var o_Zubpreis = $( "zpreis" + s_Treffer );
						var s_Checkbox_Typ = o_Condition[ a_Condition_Modus.last() ].typ;
						i_Zebra ++;
						
						var b_Checkstatus = this.checkAktiv ( s_Treffer, false, o_Check.id );
						
						/** Template Elemente **/
						var o_Show = { Zubehoer:		s_ZubtextKurz, 
									   CheckboxValue:	o_Checkbox.value, 
									   CheckboxChecked: b_Checkstatus ? ( s_Checkbox_Typ === "C" ? 'checked' : 'checked' ) : '',
									   Preis:			o_Zubpreis.innerHTML,
									   Row:				i_Zaehler%2,
									   Id:				s_Treffer,
									   Zaehler:			i_Zaehler,
									   CheckboxAlt:     b_Checkstatus ? 1 : 0,
									   An:				s_Id,
									   Zebra:           (i_Zebra % 2),
									   Level:           a_Condition_Modus.last(),
									   Name:            s_Checkbox_Typ === "C" ? 'C'+a_Condition_Modus.last()+"_"+i_Box : 'R'+a_Condition_Modus.last(),
									   Checktyp:        s_Checkbox_Typ === "C" ? 'checkbox' : 'radio' };
						
						/** Template verschmelzung und add **/
						s_Ausgabe += this.o_Ausgabetexte.row.evaluate(o_Show);
						}
					break;
				}
			}.bind(this) );
		
		s_Auswahltabelle += this.o_Ausgabetexte.button + this.o_Ausgabetexte.taopen + s_Ausgabe + this.o_Ausgabetexte.taclose + this.o_Ausgabetexte.button ;
		
		}.bind(this));


	/** lösche alle Dialoge **/
	Dialogs.close();
	this.o_Dialog = new Dialog({
				handle:'dialog',
				title:'Weiteres Zubehoer wird benoetigt {'+s_Id+'}:',
				width:600,
				content: s_Auswahltabelle,
				/** aktiviere Checkboxen **/
				afterOpen:function(){ 
				    $$("#but_Uebernehmen").each( function (o_Item ){ o_Item.observe('click', JatoClick ); } );
				    $$("#but_Abbrechen").each( function (o_Item ){ o_Item.observe('click', Abbrechen ); } );
				    }
			});
	
	this.o_Dialog.open();
	//return false;
    };
 
/**
 * Schreibt geaenderte Zubehoer-Informationen in den
 * Checkbox-Wert
 */
ClassZubRechner.prototype.schreibeDaten = function ( o_Checkbox, o_Daten ){
	o_Checkbox.value = o_Daten.id + ":" + 
					   o_Daten.aus + ":" +
					   o_Daten.preis + ":" + 
					   o_Daten.kat + ":" + 
					   o_Daten.uvp + ":" +
					   o_Daten.typ + ":" +
					   o_Daten.apreis;
	//console.log ( "Neuer Value:" + o_Checkbox.value );
	}


/**
 * PruefeIncludes
 * prueft gewaehlte Checkboxen auf Includes und setzt
 * Includes auf 0 Euro
 * @author Elko Panzyk
 * @param o_Check
 * @return o_Check
 */
ClassZubRechner.prototype.pruefeIncludes = function ( o_Check ){

    /** durchlaufe alle Checkboxen, und pruefe Abhaengigkeiten, wenn gesetzt **/
	$$("input[id^='zub']").each( function( s_ZubKey ){
		var s_Id = s_ZubKey.id.substring(3);

		var b_Abhaengig = true;
		/** Ist die Checkbox gesetzt? **/
		if ( this.checkAktiv ( s_Id, false, o_Check.id ) ){
			var o_Optionen = this.holeJatoOptionen( s_Id );
			
			/** Teste Hauptregel auf Wegfall von Bedingungen **/
			o_Optionen.R.each ( function ( s_Key ){
				var o_Abhaengig = this.checkRegel ( this.o_Jato.Optionen[ s_Key ][2], false, o_Check.id );
				var o_Regel = this.checkRegel ( this.o_Jato.Optionen[ s_Key ][3], false, o_Check.id );
				if ( o_Abhaengig.wahr && !o_Regel.wahr ){ b_Abhaengig = false; }
				}.bind(this));

				/** Teste Includes auf Wegfall von Bedingungen **/
				if ( b_Abhaengig === true ){
					o_Optionen.I.each ( function ( s_Key ){
						var o_Abhaengig = this.checkRegel ( this.o_Jato.Optionen[ s_Key ][2], false, o_Check.id );
						var o_Regel = this.checkRegel ( this.o_Jato.Optionen[ s_Key ][3], false, o_Check.id );
						if ( o_Abhaengig.wahr && o_Regel.wahr ){ o_Regel.ids.each ( function ( s_Key ){ o_Check.an.push ( s_Key ); } ); }
						}.bind(this));
					} // EndIF
				} // EndIF
		}.bind(this));
	return o_Check;
	}

/**
 * zeigeAenderungen
 */
ClassZubRechner.prototype.zeigeAenderungen = function ( s_ZubehoerId, o_Check ){
	this.f_Preis = 0.00;
	this.f_ZubehoerUvp = 0.00;

	o_Check = this.pruefeIncludes ( o_Check );

	/**
	 * Upgrade 0,00 Euro
	 */
	o_Check.an.each ( function ( s_Id ) { 
		var o_Checkbox = $( "zub" + s_Id );
		if ( s_ZubehoerId != s_Id ){ 
			var o_Zubehoer2 = this.daten( o_Checkbox.value );
			o_Zubehoer2.typ = "I"; 
			o_Zubehoer2.apreis = 0.00;
			this.schreibeDaten ( o_Checkbox, o_Zubehoer2 );
			}
		}.bind(this) );

	 this.o_CheckboxStatus [ s_ZubehoerId ].each ( function ( a_Id ){
	    /** IE Bug **/
	    if ( !Object.isUndefined( a_Id ) ){
		    if ( !a_Id[1] ){ 
			    var o_Optionen = this.holeJatoOptionen( a_Id [0] );
			    /** hole alle Include - Regeln **/
			    o_Optionen.I.each ( function ( s_Key ){
				    /** Zerlege Regel in Zubehoer-Ids **/
				    var s_Regel = this.o_Jato.Optionen[ s_Key ][3];
				    var s_Regelcheck = s_Regel.replace(/\d+/g, function( s_Treffer ){ 
					    var o_Checkbox = $( "zub" + s_Treffer );
					    var o_Zubehoer2 = this.daten( o_Checkbox.value );
					    o_Zubehoer2.typ = '';
					    o_Zubehoer2.apreis = o_Zubehoer2.preis; 
					    this.schreibeDaten ( o_Checkbox, o_Zubehoer2 );
					    var o_Zubpreis = $( "zpreis" + s_Treffer );
					    o_Zubpreis.update ( this.float2euro ( o_Zubehoer2.preis, 1 ) );
					    }.bind(this));
				    }.bind(this));
			    }
			}
		}.bind( this ) );

	/** Gesamtpreis **/
	$$("input[id^='zub']").each( function( o_Checkbox ){
		var o_Zubehoer2 = this.daten( o_Checkbox.value );
		if ( !Object.isUndefined( this.o_CheckboxStatus [ s_ZubehoerId ][o_Zubehoer2.id] ) ){
			o_Checkbox.checked = this.o_CheckboxStatus [ s_ZubehoerId ][o_Zubehoer2.id][1];
			}
		if ( o_Checkbox.checked ){
			switch ( o_Zubehoer2.typ ){
				case "I": break;
				default: this.f_Preis += o_Zubehoer2.preis; this.f_ZubehoerUvp += o_Zubehoer2.uvp; break;
				}
			}
		
		}.bind(this));
	
	o_Check.preis.each ( function ( a_Check ){
		if ( !Object.isUndefined( a_Check ) ){
		    var o_Zubpreis = $( "zpreis" + a_Check[0] );
		    var o_Checkbox = $( "zub" + a_Check[0] );
		    var o_Zubehoer = this.daten( o_Checkbox.value );
            
            //console.log ( "neuerpreis:" + o_Zubehoer.id );
            
		    if ( a_Check[1] && o_Zubehoer.typ !== 'I' ){
		        //console.log ( "MITO: neuerpreis:" + o_Zubehoer.id + "Typ: " + o_Zubehoer.typ );
			    this.o_NeuerPreis[ a_Check[0] ] = { 
				    id: a_Check[0], 
				    //EK: this.fn_Float ( this.o_Jato.Optionen[ a_Check[2] ][5] ), 
				    //VK: this.fn_Float ( this.o_Jato.Optionen[ a_Check[2] ][6] ), 
				    uvp: this.fn_Float ( this.o_Jato.Optionen[ a_Check[2] ][4] ),
				    ouvp: o_Zubehoer.uvp,
				    preis: this.fn_Float ( this.o_Jato.Optionen[ a_Check[2] ][5] ), 
				    opreis: o_Zubehoer.preis
				    };

			    o_Zubehoer.apreis = this.o_NeuerPreis[ a_Check[0] ].uvp;
			    //console.log ( "Mite:" +  o_Zubehoer.apreis );
			    this.schreibeDaten ( o_Checkbox, o_Zubehoer );

			    o_Zubpreis.update ( '<strike>'+ this.float2euro ( o_Zubehoer.preis, 1 ) + '</strike><br />' + 
								    this.float2euro (this.o_NeuerPreis[ a_Check[0] ].uvp, 1 ) );
    			
			    } else { delete this.o_NeuerPreis[ a_Check[0] ];
				    switch ( o_Zubehoer.typ ){
					    case "I": o_Zubpreis.update ( '<strike>'+ this.float2euro ( o_Zubehoer.preis, 1 ) + '</strike><br />' + this.float2euro ( 0.00, 1 ) ); break;
					    default: o_Zubpreis.update ( this.float2euro ( o_Zubehoer.preis, 1 ) ); 
								 o_Zubehoer.typ = "N";
							     o_Zubehoer.apreis = o_Zubehoer.preis; 
							     //console.log ( "Mute:" +  o_Zubehoer.apreis );
							     this.schreibeDaten ( o_Checkbox, o_Zubehoer );
							     break; 
					    }
				    }
            }
		}.bind(this) );

	o_Check.discount.each ( function ( a_Check ){
	    if ( !Object.isUndefined( a_Check ) ){ 
		    if ( a_Check[1] ){ 
			    this.o_Discount[ a_Check[0] ] = this.fn_Float ( this.o_Jato.Optionen[ a_Check[2] ][4] ); 
			    } else { 
			    delete this.o_Discount[ a_Check[0] ];
			    }
            }
		}.bind(this) );
		
	o_Check.an.each ( function ( s_Id ) { 
		var o_Checkbox = $( "zub" + s_Id );
		var o_Zubehoer = this.daten( o_Checkbox.value );

		if ( s_ZubehoerId != s_Id && o_Checkbox.checked ){
			var o_Zubpreis = $( "zpreis" + s_Id );
			o_Zubpreis.update ( '<strike>'+ this.float2euro ( o_Zubehoer.preis, 1 ) + '</strike><br />' + 
								this.float2euro ( 0.00, 1 ) );
			}
		}.bind(this) );
    this.show();
 }

/** Zeige Dialog **/
ClassZubRechner.prototype.zeigeDialog = function ( o_Check ){
    switch ( this.o_Dialogdaten.art ){
        case "IE":
        this.JatoIncludeExcludeDialog ( this.o_Dialogdaten.id, o_Check );  
        break;
        case "RIE":
        this.zeigeAbhaengigkeiten ( this.o_Dialogdaten.id, o_Check );
        break;
        default:
        alert ( "Unbekannter Dialog-Typ" );
        break;
        } 
    }
  
/**
 * click ()
 * auf das Zubehoer, Einstieg
 * @param object checkbox
 * @author Elko Panzyk
 */    
ClassZubRechner.prototype.click = function ( o_Checkbox ){
    /** Leere Stack **/
    this.o_JatoStack = [];
    this.b_Stop = false;
    
    this.a_Stack = [];
    this.o_TempCheck = [];
    this.o_DialogCheck = [];
    //console.log ( "Leere Stack und alte gewaehlte Boxen" );
    
    o_Checkbox.disabled = true;
    var o_Zubehoer = this.daten( o_Checkbox.value );
	this.o_CheckboxStatus [ 0 ] = [];

    if ( o_Checkbox.checked === true ){ var b_checked = true;
    
        //this.o_DialogCheck [ o_Zubehoer.id ] = [o_Zubehoer.id, true ];
        this.o_Ersteinstieg_Id = [o_Zubehoer.id, true ];
        
		var o_Check = this.JatoAn ( o_Zubehoer.id, { id: [ 0, true, 'x', false ], an:[], aus:[], discount:[], preis:[], Abhaengig: true } );
		if ( this.b_Stop === true ){ 
			
			/** Speichere Dialog 1 im Stack **/
			this.a_Stack.push( [ o_Zubehoer.id, true ] );
			this.o_TempCheck = o_Check;
			this.zeigeDialog ( o_Check );
			//this.zeigeAbhaengigkeiten ( o_Check.DialogId, o_Check );
			o_Checkbox.checked = false;
			o_Checkbox.disabled = false;
			return false;
			}
        } else {
			var o_Check = this.JatoAus ( o_Zubehoer.id, { id: [ 0, false, 'x', false ], an:[], aus:[], discount:[], preis:[], Abhaengig: true });
			}
	
	/** Zwischenspeicher wieder Loeschen **/
	
	this.a_Stack = [];
    this.o_TempCheck = [];
    	
	this.zeigeAenderungen( 0, o_Check );
	delete this.o_CheckboxStatus [ o_Zubehoer.id ];

    o_Checkbox.disabled=false;
    };


ClassZubRechner.prototype.abhdaten = function ( s_Daten ){
	var a_Daten = s_Daten.split(":");
	return { id: a_Daten[0], ref: a_Daten[1] }
	}


/**
 * Einstieg für Abhängigkeiten
 */
ClassZubRechner.prototype.AbhClick = function ( ){
    
    this.b_Stop = false;
   // if ( this.o_JatoStack.length === 0 ){ this.o_JatoStack.push( { i:[], e:[] } ); }
    
    $$("input[id^='azub']").each( function( o_Item ) { 
        //alert ( "DIALOGDETAILS: " + o_Item.id + " = " +o_Item.type + " Wert:" + o_Item.value + " = " + ( o_Item.checked ) );
        var a_Checkbox = o_Item.value.split(",");
        if ( ( a_Checkbox[1] == "1" ? true : false ) !== o_Item.checked ){
            this.o_DialogCheck[ a_Checkbox[0] ] = [ a_Checkbox[0], o_Item.checked];
            /** Fuege Includes und Excludes auf dem Stack ein **/
            /*if ( o_Item.checked === true ){ this.o_JatoStack.last().i.push( a_Checkbox[0] ); } else {
                this.o_JatoStack.last().e.push( a_Checkbox[0] );
                }*/
            }
     }.bind(this) );
    
	Dialogs.close();
	
	this.o_TempCheck.Abhaengig = true;
	
	/** true erzeugt stackmode ... **/
	var o_Check = this.bereinigeStack( this.o_Dialogdaten.id, this.o_TempCheck, true );

	if ( this.b_Stop === true ){ 
		/** Sichere o_Check zwischen **/
		this.o_TempCheck = o_Check;
		this.zeigeDialog ( o_Check );
		return;
		}
	
	/** Zwischenspeicher wieder Loeschen **/
	o_Check = this.JatoAn ( this.o_Ersteinstieg_Id , o_Check );
	this.a_Stack = [];
    this.o_TempCheck = [];
	this.zeigeAenderungen( 0, o_Check );
	}


/**
 * Rechner_Class initialisieren
 */
var o_Zub = new ClassZubRechner();

/**
 * Zubehoer-Checkbox geklickt
 */
function zubClick (event) {
    var o_Checkbox = event.element();
    o_Zub.click( o_Checkbox );
    }

/**
 * Dialog Function
 */
function IncludeExcludeClick ( event ){
    o_Zub.JatoIncludeExcludeClick();
    }
    
function JatoClick (event) {
    o_Zub.AbhClick();
	}

/**
 * Zubehoer-Checkbox geklickt
 */
function zubShow (event) {
	var o_zubShow = event.element();
	o_zubShow.next('span.bez').toggle();
	}

function Abbrechen (){
    Dialogs.close();
    }
    
/**
 * Liest Anzahl und Modelle aus
 */      
function hole_Resellerdaten ( o_Event )
	{
    new Ajax.Request('../RSDienste/',{ 
    parameters: {todo: 'jsReseller'},
    method:'post',
    encoding:'UTF-8',
    onSuccess: function(transport){
        var json = transport.responseText.evalJSON(true);
        //$$("input[id^='bf']").each( function( o_Item ) { o_Item.value = json[o_Item.name]; } ); 
        $$("textarea[id^='bf']").each( function( o_Item ) { o_Item.value = json[o_Item.name]; } ); 
        }
    });
    return false;
    }

/**
 * Setzt Event-Händler nach dem Laden
 */
function handlerFunction(description,page,line) {
 // put error-handling operators here
 return true;
}
window.onerror=handlerFunction;


var o_ZubehoerTab = {};

Event.observe(window, 'load', function() {
    /**
     * Wenn ein Reset-Schalter vorhanden ist,
     * Belege ihn mit einer Alle Zubehoer-Checkboxen abwählen
     * Funktion
     */ 
    if ( $('but_reset') !== null ) { 
        $('but_reset').observe('click', 
        function (){ o_Zub.reset(); });
        }
    
	$$("input[id='Mwst_Satz']").each( function( o_Item ){ o_Zub.mwst ( o_Item.value ); } );
	$$("input[id='Grundpreis']").each( function( o_Item ){ o_Zub.grundpreis ( o_Item.value ); } );
	$$("input[id='Uvp']").each( function( o_Item ){ o_Zub.uvp ( o_Item.value ); } );
	$$("input[id='Ueberfuehrungskosten']").each( function( o_Item ){ o_Zub.ueberfuehrungskosten ( o_Item.value ); } );
	$$("input[id='DbfModus']").each( function( o_Item ){ o_Zub.dbf ( o_Item.value ); } );

    /**
     * gibt es ein Waehrungsoptionen Element, verarbeite es
     */
    $$("#Waehrungskonfiguration").each( function( o_Item ){ 
        var s_Json = o_Item.value;
        if ( s_Json.isJSON() ) { o_Zub.Waehrungskonfiguration ( s_Json.evalJSON() ); }
        });

    $$("input[id='Dezimalseperator']").each( function( o_Item ){ o_Zub.o_Wahrungsoptionen.dezimaltrenner = o_Item.value; } );
    $$("input[id='Gruppenseperator']").each( function( o_Item ){ o_Zub.o_Wahrungsoptionen.gruppentrenner = o_Item.value; } );
    $$("input[id='Waehrung']").each( function( o_Item ){ o_Zub.o_Wahrungsoptionen.suffix = o_Item.value; } );
    
    //console.log ( "LOADING..." ); 
    
    o_Zub.a_Kategorie = $("Kategorienlabel").value.split("|");
    
	/**
     * Jato Daten in die Klasse einlesen
	 */
	var b_Jatodaten = false;
	$$("#Jato").each( function( o_Item ){
		var s_Json = o_Zub.fn_Base64Decode ( o_Item.value );
		if ( s_Json.isJSON() ) { o_Zub.o_Jato = s_Json.evalJSON();  b_Jatodaten = true; }
		} );
	/** 
	 * kein Jato-Objekt vorhanden, erzeuge aus 
	 * Ausschlussinformationen Standardzubehoer
     */
	if ( b_Jatodaten === false ){ o_Zub.eigenesZubehoer(); }

	/**
	 * Uebergibt bei Existenz ein Dialog-Template
	 */
	$$("#jsDialoge").each( function (o_Item ){
		var s_Dialog = o_Item.value;
		//alert ( s_Dialog );
		if ( s_Dialog.isJSON() ){
			var o_Dialog = s_Dialog.evalJSON();
			o_Zub.o_Ausgabetexte = {
					row:     new Template( o_Dialog.row ),
					and:     o_Dialog.and,
					or:	     o_Dialog.or,
					not:     o_Dialog.not,
					open:    o_Dialog.open,
					close:   o_Dialog.close,
					include: o_Dialog.include,
					exclude: o_Dialog.exclude,
					liste:   new Template( o_Dialog.liste ),
					taopen:  o_Dialog.taopen,
					taclose: o_Dialog.taclose,
					button: o_Dialog.button,
					Ersparnis: new Template( o_Dialog.Ersparnis ),
					ErsparnisProzent: new Template( o_Dialog.ErsparnisProzent ) };
			}

		} );

    /**
     * Erzeugt ein Click-Event auf allen Zubehoer-Checkboxen
     */
    $$("input[id^='zub']").each( function( o_Item ) { o_Item.observe('click', zubClick ); } );
    o_Zub.JatoInit();

	/**
         * Fuege + hinzu
	 */
	$$( "#Label_Sonderzubehoer td[id^='ztxt'] span.kbez" ).each ( function ( o_Objekt ){ 
		o_Objekt.insert({before: '<span class="zshow" style="font-family: Courier, mono, monospace !important; color: #ffffff; background: #2868b0; cursor: hand; padding: 0px 2px 0px 2px; margun-right: 2px;">i</span>&nbsp;' }); 
		o_Objekt.next('span.bez').hide();
		});
	$$( "#Label_Sonderzubehoer td[id^='ztxt'] span.zshow" ).each( function( o_Item ) { o_Item.observe('click', zubShow ); } );

    /**
     * Dropdown für die Bildauswahl
     */
    $$("#Bildwahl li").each( function( o_Knoten ){
		var o_ul = $A( o_Knoten.getElementsByTagName("ul") ).first();
		if( o_ul != null ){ o_Knoten.onmouseover = o_Knoten.onmouseout = function(){ Element.toggle( o_ul ); } }
		});
	
	/**
	 * Verstecke die Bildauswahl
	 */
	$$("ul#Bildwahl li ul").each(function( o_Knoten ){ Element.hide( o_Knoten ); });
	
	if ( $('TabKategorie') !== null ){
	        o_ZubehoerTab = new ProtoTabs('tab_zubehoer',{defaultPanel:$('TabKategorie').value});
		var b_alles_zeigen = false; 
		$$('#ZUB_ALLES_ZEIGEN').each(function(o_Element){ b_alles_zeigen = o_Element.readAttribute('value') == '1' ? true : false; });
		if ( b_alles_zeigen === true ){ o_ZubehoerTab.showAll(); }
        }
    });

/* --- Ende Load-Event --- */
