function Cookie( name, value, bArray, expires, bExOr42)
{
	( name) ? this.name = name : this.name = "";
	( expires) ? this.expires = expires : this.expires = "";

	this.value = null;
	this.valueKey = null;	// Helfer wenn Array

	// flag ob Exklusivoderverschluesselung für 
	// value stattfindet oder nicht (true/false)
	( bExOr42) ? this.bExOr42 = true : this.bExOr42 = false;

	// flag ob es sich um ein Array handelt (true/false)
	( bArray) ? this.bArray = true : this.bArray = false;



	// Hilfsmethode falls value ein Array ist
	// merk sich Key von Array in einem anderen Array
	function SetValue( target, newValue)
	{
		if( newValue)
		{
			if( target.bArray)	// string // todo
			{
				target.value = new Array();
				target.valueKey = new Array();
				
				var i = 0;
				for( i = 0; i < newValue.length; i++)
				{
					var idItem = newValue[ i][0];
					var valueItem = newValue[ i][1];

					target.value[ idItem] = valueItem;
					target.valueKey.push( idItem);
				}
			}
			else	// string, int oder float
			{
				target.value = newValue;					
			}
		}
		else
		{
			target.value = null;
		}		
	}

	SetValue( this, value);								 

	// Add hangt ein WertePaar an
	// das assoziative Array und
	// das SchluesselArray an, vorausgesetzt
	// this.value wurde nicht schon vorher mit 
	// einem String, Int oder Float gelegt.
	function Add(	name, value)
	{
		if( ! this.value)	// ist noch null
		{
			this.value = new Array();
			this.valueKey = new Array();
		}
		else
		{
			if( !bArray) 
			{
				throw " value ist kein Array !!!";
				// wenn es kein Array ist aber 
				// eine this.value gleich true ist, 
				// dann ist es ein String, Int oder Float					
			}
		}

		this.valueKey.push( name);			
		this.value[this.valueKey[this.valueKey.length-1]] = value;
	}
	
	// findet heraus ob der Browser auf der Clientseite 
	// das setzen von Cookies unterstuetzt und ob der Leser
	// dies auch erlaubt bzw. Cookies deaktiviert sind
	
	function AreCookiesEnabled()
	{
		// unterstuetzt der browser cookies
		if( window.navigator.cookieEnabled)
		{
			// setzt ein cookie mit einer Lebenszeit von 10 Sekunden
			var utcstring = getUTCStringPlus( 10);
			document.cookie = "areCookiesEnabled=yes; expires=" + utcstring;
			
			// sieh nach ob das Cookie gesetzt werden konnte
			if( GetCookieValue( "areCookiesEnabled"))
			{
				return true;
			}
		}
		// dieser browser kann keine cookies bzw. es wurde ihm verboten
		return false;
	}

	// getUTCStringPlus holt sich die aktuelle Zeit, addiert 
	// n Sekunden dazu, bzw. zieht diese ab. Nimmt nur diesen 
	// zukunftigen oder vergangenen Zeitpunkt und liefert
	// den dazugehörenden UTCString zurueck
	// UTC = Universal Coordinated Time = koordinierte Weltzeit
	// UTC-Format: Tue, 10 Feb 2004 14:58:07 UTC
	
	function getUTCStringPlus( secounds)
	{
		var date = new Date();
		date.setUTCSeconds( date.getUTCSeconds() + parseInt( secounds));
		return date.toUTCString();
	}
	

	// GetCookieValue sieht nach ob es ein bestimmtes Cookie mit
	// dem angegebenen Name auf der Clientseite gibt und liefert
	// es gegebenen Falls zurück. Falls das Cookie nicht existiert
	// wird null zurück gegeben. 
	
	function GetCookieValue( name)
	{
		// einzelne Cookies sind durch Semikolons von einander getrennt
		var aCookie = document.cookie.split("; ");
		for (var i=0; i < aCookie.length; i++)
		{
			// ein Name/Value Paar ist durch ein Istgleichzeichen ("=") von einander getrennt
			var aCrumb = aCookie[i].split("=");
			if( name == aCrumb[0]) 
			{
				if( this.bExOr42)
					return Decode( aCrumb[1]);
				else
					return aCrumb[1];
			}
		}
		// das angeforderte Cookie gibt es nicht
		return null;
	}
	
	// SetCookie setzt this.name, this.value und
   // this.expires auf die gewünschten Werte und
   // ruft SetDocumentCookie auf. Alle Parameter sind
   // optional und der letzte Parameter expires 
   // hält die Lebenszeit des Cookies in Sekunden. 
   // Falls expires negativ ist und value leer, 
   // wird das Cookie gelöscht. s.h. Function Remove()
   //
   // Falls expires nicht gesetzt wird entsteht
   // automatisch ein Cookie, dass solange lebt,
   // wie die Browsersession geöffnet bleibt.
  
   function SetCookie( name, value, expires)
   {
		(name) ? this.name = name + "" : this.name = this.name;
		(value) ? this.value = value + "" : this.value = this.value;
		(expires) ? this.expires = expires + "" : this.expires = this.expires;

		return SetDocumentCookie( this);
   }

	// GetCookie bekommt von GetCookieValue den Wert des Cookies
	// Names this.name. Es können vier verschiedene Fälle auftreten
	//
	//	document.cookie = "
	// userinfo=123";	(1. Fall)
	// userinfo=123|e~Tue, 10 Feb 2004 14:58:07 UTC; expires=Tue, 10 Feb 2004 14:58:07 UTC";   (2. Fall)
	//	userinfo=id~123|vip~yes";   (3. Fall)
	// userinfo=id~123|vip~yes|e~Tue, 10 Feb 2004 14:58:07 UTC; expires=Tue, 10 Feb 2004 14:58:07 UTC";   (4. Fall)
	//
	//	je nachdem was im Cookie steht wird ein Array oder ein String zurück geliefert
	// Falls es sich um ein Cookie mit beschränkter Lebenszeit handelt wird diese ausgelesen
	// und in this.expires als Sekundendifferenz zu heute abgelegt.
	
   function GetCookie( name)
   {
		if( name)
			this.name = name;

		var value = GetCookieValue( this.name);
		// gibt es ein Cookie in document.cookie mit dem Namen this.name
		if( value)
		{
			// todo spacer unescapen()
			if( value.indexOf("|") >= 0)
			{
				var a1 = value.split("|");			
				
				var i = 0;
 
 				this.value = new Array();
				this.valueKey = new Array();

				for( i = 0; i < a1.length; i++)
				{
					if( a1[i].indexOf("~") >= 0)
					{
						var a2 = a1[i].split("~");
						if( a2[0] == "e")	 // 2. u. 4. Fall mit expires e~Tue, 10 Feb ...
						{
							var expires = new Date( a2[1]);
							var today = new Date();
							
							this.expires = Math.round( ( expires.getTime() - today.getTime()) / 1000);
						}
						else	// 3. u. 4. Fall mit a2[0]="id" bzw. a2[0]="vip";
						{
							this.value[a2[0]] = unescape( a2[1]);
							this.valueKey.push(a2[0]);
						}
					}
					else	//	 document.cookie = "userinfo=123|e~Tue, 10 Feb 2004 14:58:07 UTC" mit a1[i]=123;
					{
						this.value = unescape( a1[i]);
					}
				}
			}
			else // document.cookie = "userinfo=123";
			{
				this.value = unescape( value);
			}
			return this.value;
		}
		else
		{
			return false;
			throw "es gibt keinen Cookie mit dem Name this.name";
		}	
   }
   
	// ExOr42 bekommt einen String,
	// geht diesen zeichenweise durch und
	// verodert die ASCII-Werte der einzelnen Zeichen mit 42,
	// anschliessend werden die veroderten Werte in ASCII-Zeiche
	// zurückverwandelt und der verschlüsselte String zurück gegeben
	// ist für die ASCII-Werte 0-256 getestet worden
		
  	function ExOr42( s)
	{
		var tmp = '';
		var i;
		for ( i = 0; i < s.length; i++)
		{
			tmp += String.fromCharCode( s.charCodeAt(i) ^ 42);
		}		
		return tmp;		
	}

	function ASCIIToHex( str)
	{
		var aLetter = new Array( "0", "1", "2","3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F");
		var res = ""; var i = 0;
		for( i = 0; i < str.length; i++)
		{
			var num = str.charCodeAt(i);
			var fl = (num - (num % 16)) / 16;
			var ll = num % 16;
					
			res += "%" + aLetter[fl] + aLetter[ll];
		}
		return res;
	}

	function Encode( str)
	{
		str = ASCIIToHex( str);
		str = ExOr42( str);
		return encodeURIComponent( str);
	}   
   
   function Decode( str)
   {
		str = decodeURIComponent( str);
		str = ExOr42( str);
		return unescape( str);
   }
   
   // Es wird das Cookie Namens this.name löscht
   // liefert true/false, gelöscht oder fehler zurück
   function Remove()
	{
		var res = this.SetCookie( this.name , "", -120);
		this.name = "";
		this.value = null;
		this.expires = "";
		return res;
	}

   function Delete()
   {
      var aCookie = document.cookie.split("; ");
      for (var i=0; i < aCookie.length; i++)
      {
	var aCrumb = aCookie[i].split("=");

	if( aCrumb[0] == this.name)
	{
	   var sCookie = aCrumb[0] + "=''; expires=Fri, 31 Dec 1999 23:59:59 GMT; path=/; domain=.nickles.de";
	   document.cookie = sCookie;
	}
      }
   }
   
   
   // baut einen String aus den Membern der Klasse 
   // zusammen, schreibt diesen String in document.cookie
   // und liefert true falls gelungen 
   function SetDocumentCookie( target)
   {
		if( ! target.name)
			throw "es wurde keine Name vergeben";
			
		var sCookie = "";
		var sValue = "";
		var sExpires = "";
		
		// LöLschenouml;schen zulassen (value = "" expires = -120)		
		if( ! target.value && target.expires > 0 && ! target.valueKey.length)
			throw "es ist kein Wert für Value, dennoch aber eine Lebenszeit angegeben";

		// kein value und kein expires, falsche eingebe
		if( ! target.value && ! target.expires)
			throw "kein Value und keine Lebenszeit angegeben total falsche Voraussetztungen fuer alles";
		
		if( target.bArray)	// ist value ein Array oder keins // todo
		{
			var i;
			for( i = 0; i < target.valueKey.length; i++)
			{
				if( i > 0) 
					sValue += "|";
					
				var escapedValue = target.value[target.valueKey[i]] + "";
				escapedValue = escapedValue.replace(  /~/g, "%7E");
				escapedValue = escapedValue.replace( /\|/g, "%7C");					
				escapedValue = escapedValue.replace(  /=/g, "%3D");
				escapedValue = escapedValue.replace( /;/g, "%3B");					
				sValue += target.valueKey[i] + "~" + escapedValue;						
			}			
		}
		else
		{
			var escapedValueTemp = target.value + "";
			escapedValueTemp = escapedValueTemp.replace(  /~/g, "%7E"); 
			escapedValueTemp = escapedValueTemp.replace( /\|/g, "%7C");
			escapedValueTemp = escapedValueTemp.replace(  /=/g, "%3D");
			escapedValueTemp = escapedValueTemp.replace( /;/g, "%3B");					
			sValue = escapedValueTemp;
		}

		sCookie  += sValue;
			
		if( target.expires)
		{
			var utcstring = getUTCStringPlus( target.expires);
			sValue += "|e~" + utcstring;
			sExpires = "; expires=" + utcstring;
		}

		if( target.bExOr42)		
		{
			sValue = Encode( sValue);
		}
		sCookie = target.name + "=" + sValue + sExpires;
		document.cookie = sCookie;

		// hat geklappt		
		return true;
   }

   this.Remove = Remove;	
   this.Delete = Delete;	   
   this.SetCookie = SetCookie;	
	this.GetCookie = GetCookie;
	this.AreCookiesEnabled = AreCookiesEnabled;
	this.Add = Add;

}
