// (c) EIKONA AG, it.x informationssysteme gmbh, Alle Rechte vorbehalten.

if(!CoverFlow) {
	
	var CoverFlowElement = Class.create({
		initialize: function(data) {
			data = Object.extend({
				id: null,
				imageUri: null,
				metaData1: null,
				metaData2: null,
				onClick: null,
				width: null,
				height: null
			}, data ||  {});
			
			this.id = data.id;
			this.imageUri = data.imageUri;
			this.metaData1 = data.metaData1;
			this.metaData2 = data.metaData2;
			this.onClick = data.onClick;
			this.width = data.width;
			this.height = data.height;
		}
		
	});
		
		
	var CoverFlow = Class.create({
	
		/********************************************
		 *	Konstruktor
		 *
		 *	param HTMLDivElement 
		 *	 
		 ********************************************/
		initialize: function(container, width, height, file, options) {
			
			this.id = "cf";
			
			this.CoverFlowContainer = $(container);
			this.CoverFlowContainer.style.width = width + 'px';
			this.CoverFlowContainer.style.height = height + 'px';
			var containerId = this.CoverFlowContainer.identify();
			
			// Standardwerte
			this.options = Object.extend({
				caption:	true,
				scrollbar:	true,
				scrollbarFadeIn: false,
				scrollbarFadeOut: false,
				scrollbarWidth: width,
				scrollOffsetRight: 15,
				scrollOffsetLeft: 15,
				scrollSliderWidth: 'dynamic',
				mousewheel: true,
				keystrokes: true,
				elementPrefix: 'cf-pic-',
				arrowLeft: new Element('img', { id: containerId.concat('-arrowleft'), 'class': 'cf-arrowleft', src: 'portal/pics/layout/scroll_pfeil_links.gif' }),
				arrowRight: new Element('img', { id: containerId.concat('-arrowright'), 'class': 'cf-arrowright', src: 'portal/pics/layout/scroll_pfeil_rechts.gif' }),
				imageZoom: 1,
				reflectionHeight: 0.5, // Sets the height of the reflection in % of the source image
				focus: 4, // Sets the numbers of images on each side of the focussed one
				xstep: 150,
				top: 0,
				left: 0,
				className: 'cf-coverflow'
			}, options || {});
			
			this.CoverFlowContainer.addClassName(this.options.className);
			
			this.activeObjectCallbacks = new Array();
			
			this.ImageContainer = new Element('div', { id: containerId.concat('-images'), 'class': 'cf-images' });
			
			// Neue Container anhängen
			this.CoverFlowContainer.insert(this.ImageContainer);
			
			if (this.options.caption == true){
				this.CaptionContainer	= new Element('div', { id: containerId.concat('-captions'), 'class': 'cf-caption' });
				this.CoverFlowContainer.insert(this.CaptionContainer);
			}
			
			if (this.options.scrollbar == true){
				this.ScrollbarContainer	= new Element('div', { id: containerId.concat('-scrollbars'), 'class': 'cf-scrollbar' }).update(' ');
				
				this.SliderContainer	= new Element('div', { id: containerId.concat('-slider'), 'class': 'cf-slider' }).update(' ');
				
				this.ArrowLeftContainer		= this.options.arrowLeft;
				this.ArrowRightContainer	= this.options.arrowRight;
				
				this.ScrollbarContainer.insert(this.SliderContainer);
				this.ScrollbarContainer.insert(this.ArrowLeftContainer);
				this.ScrollbarContainer.insert(this.ArrowRightContainer);
				
				$(container).insert(this.ScrollbarContainer);
				
				this.ScrollbarContainer.style.visibility	= 'visible';
				
				// Den Scroller überwachen
				Event.observe(this.ArrowLeftContainer, 'click', this._handleLeftArrow.bindAsEventListener(this));
				Event.observe(this.ArrowRightContainer, 'click', this._handleRightArrow.bindAsEventListener(this));
				
				Event.observe(this.ScrollbarContainer, 'click', this._handleScrollbarContainer.bindAsEventListener(this));
				
				Event.observe(document, 'mousemove',	this._drag.bindAsEventListener(this));
				Event.observe(document, 'mouseup',		this._dragstop.bindAsEventListener(this));
				
				// Versehentliches markieren beim Scrollen im IE verhindern
				Event.observe(document, 'selectstart', function (e) {
					if (this.dragging == true)
						e.stop();
				}.bindAsEventListener(this) );
				// Versehentliches markieren beim Scrollen im Mozilla und Safari verhindern
				this.CoverFlowContainer.style.MozUserSelect = 'none';
				this.CoverFlowContainer.style.KhtmlUserSelect = 'none';
				
				// damit wir die Events auch wieder deregestrieren können
				this.scrollbarFadeInListener = this._showScrollbar.bindAsEventListener(this);
				this.scrollbarFadeOutListener = this._hideScrollbar.bindAsEventListener(this);
				
				// Soll die Scrollbar bei MouseOver eingeblendet werden?
				if (this.options.scrollbarFadeIn){
					// Statusflags die der CF zur Überwachung der MouseOver/Out-Events benötigt
					this.scrollerIsFading = false;
					this.scrollerIsVisible = false;
					
					// Scroller soll zuerst nicht gesehen werden
					this.ScrollbarContainer.setOpacity(0);
					
					// Event registrieren
					Event.observe(this.ImageContainer, 'mouseover', this.scrollbarFadeInListener);
				}else
					this.scrollerIsVisible = true;
				
				// Soll die Scrollbar bei MouseOut ausgeblendet werden?
				if (this.options.scrollbarFadeOut)
					Event.observe(this.ImageContainer, 'mouseout', this.scrollbarFadeOutListener);
			}
			
									
			
			// Die Bühne merken
			this.Stage				= new Object();
			this.Stage.offsetX		= this.CoverFlowContainer.offsetLeft;
			this.Stage.offsetY		= this.CoverFlowContainer.offsetTop;
			this.Stage.Width		= width;
			this.Stage.Height		= height;
			this.Stage.AspectRatio	= this.Stage.Width / Math.max(1, this.Stage.Height);
			this.Stage.Scale		= 1;
			
			// Anderer Dinge für Berechungen merken
			this.Scroller				= new Object();
			this.Scroller.offsetLeft	= this.options.scrollOffsetLeft;
			this.Scroller.offsetRight	= this.options.scrollOffsetRight;
			this.Scroller.Width			= this.options.scrollbarWidth - this.Scroller.offsetLeft - this.Scroller.offsetRight;
			
			// Objekte im CoverFlow
			this.CFObjekte			= new Object();
			this.CFObjekte.anzahl	= 0;
			
			// Für den Fall es gibt mehrere CoverFlows sollte der Umgebung
			// eine Möglichkeit der Unterscheidung gegeben werden
			this.hasFocus = false;
			
			// Leer initialisieren		
			this.clear();
			
			// Startsequenz aus window.onLoad
			this.ImageContainer.style.visibility		= 'visible';
			this.ImageContainer.style.height			= height + 'px';
			
			
			// Die Events registrieren
			// Mausrad überwachen
			if (this.options.mousewheel == true){
				Event.observe(this.CoverFlowContainer, 'DOMMouseScroll', this._wheel.bindAsEventListener(this));	// Scroll-Rad für alle Browser
				Event.observe(this.CoverFlowContainer, 'mousewheel', this._wheel.bindAsEventListener(this));		// Scroll-Rad für IE6/7
			}

			// Tastatur überwachen
			if (this.options.keystrokes == true)
				Event.observe(document, 'keydown',		this._handleKeyCode.bindAsEventListener(this));
				
			// Die Bilder laden
			if (file)
				this.loadXML(file);
		
		},
		
		/********************************************
		 *	Fügt dem CoverFlow ein Element hinzu
		 *
		 *	param Objekt
		 *
		 ********************************************/
		addElement: function(obj) {
			var attributes = {
				src:		obj.imageUri,
				id:			this.options.elementPrefix.concat(obj.id),
				width:		obj.width,
				height:		obj.height,
				w:			obj.width,
				h:			obj.height
			};
			
			if (obj.metaData1)
				attributes.alt = obj.metaData1;
			if (obj.metaData2)
				attributes.alt += '<br/>' + obj.metaData2;
			
			attributes.title = '';
				
			var image = new Element('img', attributes);
			image.systemid = obj.id;
			
			image.action = null;
			if (typeof obj.onClick == 'function')
				image.action = function(e) { obj.onClick(); };
			else if (obj.onClick && typeof obj.onClick == 'string')
			{
				var targetUri = obj.onClick;
				image.action = function() { document.location = targetUri; }
			}
						
			this.ImageContainer.insert(image);
			this.CFObjekte.anzahl++;
		},
	
		
		/********************************************
		 *	Entfernt ein Element aus dem CoverFlow
		 *
		 *	param Objekt
		 *
		 ********************************************/
		removeElement: function(id) {
			var element = $(this.options.elementPrefix.concat(id));
			if (element && element.parentNode == this.ImageContainer)
			{
				this.CFObjekte.anzahl--;
				element.remove();
			}
		},
		
		updateElement: function(id, obj) {
			var element = $(this.options.elementPrefix.concat(id));
			if (element && element.parentNode == this.ImageContainer)
			{
				if (obj.imageUri)
					element.src = obj.imageUri; 
				if (obj.width)
					element.w = obj.width;
				if (obj.height)
					element.h = obj.height;
			}
		},
		
		// Entfernt alle Elemente aus dem Coverflow.
		clear: function() {
			/* Reset global variables */
			this.caption_id		= 0;
			this.new_caption_id	= 0;
			this.current		= 0;
			this.target			= 0;
			this.mem_target		= 0;
			this.timer			= 0;
			this.array_images	= new Array();
			
			this.dragging	= false;
			this.dragobject	= null;
			this.dragOffset	= 0
			this.MouseX		= 0;
			this.new_posx	= 0;
			
			this.ImageContainer.update();
			this.CFObjekte.anzahl = 0;
		},
		
		getActiveElementId: function() {
			return this._activeObjectId;
		},
		
		
		/********************************************
		 *	lädt die Objekte für den CoverFlow
		 *
		 *	param URI
		 *
		 ********************************************/
		loadXML: function(uri) {
			
			new Ajax.Request(uri, {
					onSuccess: function(transport) {
						
						this.parseXMLDocument(transport.responseXML);
						
					}.bind(this)
				}
			);
		},
		
		parseXMLString: function(xml) {
			var result = false;
			
			if (document.implementation && document.implementation.createDocument) {
				var parser = new DOMParser();
				var xmlDoc = parser.parseFromString(xml, "text/xml");
			}
			else if (window.ActiveXObject) {
				var xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
				xmlDoc.async = "false";
				xmlDoc.loadXML(xml);
			}
			
			if (xmlDoc) {
				this.parseXMLDocument(xmlDoc);
				result = true;
			}
			
			return result;
		},
		
		parseXMLDocument: function(xml) {
			var rootNode	= xml.getElementsByTagName("cfCovers")[0];
			var max			= rootNode.childNodes.length;
			
			for (var index = 0; index < max; index++) {
				
				var cfElement = rootNode.childNodes.item(index);
				
				if (cfElement.nodeType == 1) {
					var element = new CoverFlowElement({
						id: cfElement.getAttribute('id'),
						imageUri: cfElement.getAttribute('imageUri'),
						metaData1: cfElement.getAttribute('metaData1'),
						metaData2: cfElement.getAttribute('metaData2'),
						onClick: cfElement.getAttribute('onClickUri'),
						width: cfElement.getAttribute('width'),
						height: cfElement.getAttribute('height')
					});
					this.addElement(element);
				}
			}
			this.refresh(true);
		},
		
		/********************************************
		 *	setzt den Coverflow auf angegebene Durch-
		 *  sichtigkeit
		 ********************************************/
		setOpacity: function(opacity) {
			this.CoverFlowContainer.setOpacity(opacity);
		},
		
		
		
		/********************************************
		 *	setzt die Instanz des CF aktiv, d.h. es
		 *  kann gescrollt, gedragt gekeyt werden
		 ********************************************/
		setFocus: function() {
			this.hasFocus = true;
		},
		
				
		/********************************************
		 *	deaktiviert den CF
		 ********************************************/
		removeFocus: function() {
			this.hasFocus = false;
		},
		
		show: function() {
			this.CoverFlowContainer.setStyle({ visibility: 'visible' });
			this.setFocus();
		},
		
		hide: function() {
			this.CoverFlowContainer.setStyle({ visibility: 'hidden' });
			this.removeFocus();
		},
		
		registerActiveObjectCallback: function(callback) {
			this.activeObjectCallbacks.push(callback);
		},
		
		removeActiveObjectCallback: function(callback) {
			this.activeObjectCallbacks = this.activeObjectCallbacks.without(callback);
		},
		
		removeAllActiveObjectCallbacks: function(callback) {
			this.activeObjectCallbacks = new Array();
		},
		
		centerPosition: function(position) {
			if (position < 0)
				position = this.CFObjekte.anzahl + position;
			else if (position >= this.CFObjekte.anzahl)
				position = this.CFObjekte.anzahl - 1;
			if (position >= 0 && position < this.CFObjekte.anzahl)
				this._glideTo(-position * this.options.xstep, position);
		},
		
		/********************************************
		 *	Kernfunktionen die das Positionieren und
		 *	andere Funktionen des CF übernimmt
		 *
		 ********************************************/
		_step: function() {
			
			switch (this.target < this.current - 1 || this.target > this.current + 1){
				
				case true:
					this._moveTo(this.current + (this.target - this.current) / 3);
					window.setTimeout(this._step.bind(this), 25);
					this.timer = 1;
					break;
					
				default:
					if (this.dragging == false) {
						this._activeObjectId = this.ImageContainer.childNodes[this.caption_id].systemid;
						this._updateActiveObject(this._activeObjectId);
					}
					this.timer = 0;
					break;
			}
		},
		
		_glideTo: function(x, new_caption_id) {
			// Animate gliding to new x position
			this.target		= x;
			this.mem_target	= x;
			
			if (this.timer == 0){
				window.setTimeout(this._step.bind(this), 25);
				this.timer = 1;
			}
			
			// Display new caption
			this.caption_id	= new_caption_id;
			this.caption = this.ImageContainer.childNodes.item(this.array_images[this.caption_id]).getAttribute('alt');
			
			if (!this.caption)
				this.caption = '&nbsp;';
			
			if (this.CaptionContainer)
				this.CaptionContainer.innerHTML = this.caption;
			
			// Set scrollbar slider to new position
			if (this.dragging == false && this.SliderContainer && this.max > 1)
				this.SliderContainer.setStyle({ left: ''.concat(this.Scroller.offsetLeft + (new_caption_id * ((this.Scroller.Width - this.conf_slider_width) / (this.max - 1))), 'px') });
		},
		
		_moveTo: function (x) {
			this.current	= x;
			var zIndex		= this.max;
					
			/* Main loop */
			for (var index = 0; index < this.max; index++) {
				
				var image			= this.ImageContainer.childNodes.item(this.array_images[index]);
				var current_image	= - this.options.xstep * index;
			
				/* Don't display images that are not conf_focussed */
				if ((current_image + this.max_conf_focus) < this.mem_target || (current_image - this.max_conf_focus) > this.mem_target) {
					
					image.style.visibility	= 'hidden';
					image.style.display		= 'none';
					
				} else {
					
					var z = Math.sqrt(10000 + x * x) + 100;
					var xs = x / z * this.size + this.size;
	
					/* Still hide images until they are processed, but set display style to block */
					image.style.display = 'block';
					
					/* Process new image height and image width */
					var new_img_h = (image.h / image.w * image.pc) / z * this.size * this.options.imageZoom;
					switch ( new_img_h > this.max_height ) {
						case false:
							var new_img_w = image.pc / z * this.size;
							xs = xs - new_img_w * (this.options.imageZoom - 1) / 2;
							new_img_w = new_img_w * this.options.imageZoom;
							break;
						
						default:
							new_img_h = this.max_height;
							var new_img_w = image.w * new_img_h / image.h;
							break;
					}
					
					// debug
					//new_img_h = 100; new_img_w = 100;
					
					//var new_img_top = (this.images_width * 0.34 - new_img_h) + this.options.top + ((new_img_h / (this.options.reflectionHeight + 1)) * this.options.reflectionHeight);
					var new_img_top = this._getYPos(x, new_img_w, new_img_h);
					
					/* Set new image properties */
					//image.style.left = this._getXPos(- this.options.xstep * index) + 'px';
					image.style.left = xs - (image.pc / 2) / z * this.size + this.options.left + 'px';
					
					if(new_img_w && new_img_h){
						image.style.height	= new_img_h + 'px';
						image.style.width	= new_img_w + 'px';
						image.style.top		= new_img_top + 'px';
					}
					
					image.style.visibility = 'visible';
			
					/* Set image layer through zIndex */
					switch ( x < 0 ) {
						
						case true:
							zIndex++;
							break;
	
						default:
							zIndex = zIndex - 1;
							break;
						}
					
					/* Change zIndex and onclick function of the focussed image */
					switch ( image.i == this.caption_id ) {
						
						case false:
							image.onclick = function() {
								// da wir hier this und image-this haben muss getrickst werden
								var args = $A(arguments);
								args.shift();
								this._glideTo(args[0], args[1]);
							}.bindAsEventListener(this, image.x_pos, image.i)				
							break;
			
						default:
							zIndex = zIndex + 1;
							image.onclick = image.action;
							break;
						}
	
					image.style.zIndex = zIndex;
				}
				
				x += this.options.xstep;
			}
		},
	
		/* Main function */
		refresh: function(onload) {
			
			/* Cache global variables, that only change on refresh */
			this.images_width		= this.Stage.Width * this.Stage.Scale;
			
			this.max_conf_focus		= this.options.focus * this.options.xstep;
			this.size				= this.images_width * 0.5;
			this.max_height			= Math.max(this.images_width * 0.51, this.Stage.Height);
			
			// Anzahl der Bilder in kleine Abschnitte auf dem Scrollbar  "mappen"
			this.Scroller.Step		= (this.Scroller.Width - this.conf_slider_width) / (this.max - 1);
			
			/* Change imageflow div properties */
			//this.CoverFlowContainer.style.height = this.max_height + 'px';
			
			/* Change images div properties */
			this.ImageContainer.style.height = this.Stage.Height + 'px';
			
			/* Change captions div properties */
			if (this.CaptionContainer){
				this.CaptionContainer.style.width		= this.Stage.Width + 'px';
				this.CaptionContainer.style.marginTop	= - (90 * this.Stage.Scale) + 'px';
			}
			
			/* Change scrollbar div properties */
			if (this.ScrollbarContainer){
				this.ScrollbarContainer.style.marginTop	= this.Stage.Scale * 23 + 'px';
				this.ScrollbarContainer.style.marginLeft = (this.Stage.Width/2 - this.options.scrollbarWidth/2) + 'px';
				this.ScrollbarContainer.style.width = this.Stage.Scale * this.options.scrollbarWidth + 'px';
				
				/* Set slider attributes */
				this.SliderContainer.onmousedown	= function(e) {	this._dragstart(e); }.bindAsEventListener(this);
				
				// Breite des Slider setzen ('dynamic' = 0!, alles andere ist ein gesetzter Wert)
				if (parseInt(this.options.scrollSliderWidth) > 0)
					this.conf_slider_width = this.options.scrollSliderWidth;
				else
					this.conf_slider_width = Math.max(16, (this.Scroller.Width) / Math.max(1, this.CFObjekte.anzahl));
				
				this.SliderContainer.style.width = this.conf_slider_width + "px";
			}
			
			/* Cache EVERYTHING! */
			this.max = this.ImageContainer.childNodes.length;
			this.array_images = new Array();
			
			var i = 0;
			for (var index = 0; index < this.max; index++) {
				
				var image = this.ImageContainer.childNodes.item(index);
				
				if (image.nodeType == 1) {
					
					this.array_images[i] = index;
					
					/* Set image onclick by adding i and x_pos as attributes! */
					image.x_pos	= -i * this.options.xstep;
					image.i		= i;
					Event.stopObserving(image, 'click');
					Event.observe(image, 'click', function() {
						var args = $A(arguments);
						args.shift();
						if (args[0] != this.target)
							this._glideTo(args[0], args[1]);
					}.bindAsEventListener(this, image.x_pos, i));
					
					/* Add width and height as attributes ONLY once onload */
					if (onload == true) {
						if (!image.w)
							image.w = image.width;
						if (!image.h)
							image.h = image.height;
					}
					
					/* Check source image format. Get image height minus reflection height! */
					switch ((image.w + 1) > (image.h / (this.options.reflectionHeight + 1))) {
						
						/* Landscape format */
						case true:
							image.pc = 118;
							break;
		
						/* Portrait and square format */
						default:
							image.pc = 100;
							break;
					}
					
					/* Set ondblclick event */
					if (image.action)
						image.ondblclick = image.action;
					else
						image.ondblclick = null;
					
					i++;
				}
			}
			
			this.max = this.array_images.length;
		
			/* Display images in current order */
			if (this.CFObjekte.anzahl > 0) {
				if (this.caption_id >= this.CFObjekte.anzahl) {
					this.caption_id = this.CFObjekte.anzahl - 1;
					this.current = -this.caption_id * this.options.xstep;
				}
				
				this._moveTo(this.current);
				this._glideTo(this.current, this.caption_id);
				this.show();
			}
			else {
				this._updateActiveObject(null);
				this.hide();
			}
		},
		
		_showScrollbar: function(event) {
			
			if (!this.scrollerIsVisible && this.hasFocus && this.CFObjekte.anzahl > 1) {
				this.scrollerIsVisible = true;
				
				if (this._fadeEffect)
					this._fadeEffect.cancel();
				
				this._fadeEffect = new Effect.Opacity(this.ScrollbarContainer, { from: 0, to: 0.6 });
			}
		},
		
		_hideScrollbar: function(event) {
			var objBoundingBox = Object.extend(this.CoverFlowContainer.getDimensions(), this.CoverFlowContainer.cumulativeOffset());
			var bitInnerhalb = ((Event.pointerX(event) >= objBoundingBox.left && Event.pointerX(event) <= objBoundingBox.left + objBoundingBox.width) && (Event.pointerY(event) >= objBoundingBox.top && Event.pointerY(event) <= objBoundingBox.top + objBoundingBox.height));
			
			if (!bitInnerhalb && this.scrollerIsVisible && this.hasFocus) {
				this.scrollerIsVisible = false;
				
				if (this._fadeEffect)
					this._fadeEffect.cancel();
				
				this._fadeEffect = new Effect.Opacity(this.ScrollbarContainer, { from: 0.6, to: 0 });
			}
		},
		
		// mathematische Funktion die die X-Position der Bilder
		// ermittelt
		/*
		_getXPos: function (i){
			
			//var x =	Math.pow(i, 2);
			var x = xs - (image.pc / 2) / z * this.size + this.options.left;

			
			return x;
		},
		*/
		
		// mathematische FUnktion die die Y-Position der Bilder
		// anhand Ihrer X-Koordinate ermittelt
		_getYPos: function (x, imageWidth, imageHeight){
			
			// Parabolisch
			//x = 0.01 * (x - 0.5 * imageWidth);			// X koordinate aufarbeiten (mittige Bildausrichtung, etc.)
			//var y = Math.pow(x, 2) * -0.5 + 40;
			
			// Standard
			var y = (this.images_width * 0.34 - imageHeight) + this.options.top + ((imageHeight / (this.options.reflectionHeight + 1)) * this.options.reflectionHeight);
			
			//debug:$('textbox').textContent = $('textbox').textContent.concat("x/y: ", x, "/", y, "\n");
			
			return y;	// immer die negierte Koordinate zurückgeben -> 0/0 ist oben links!
		},
		
		_updateActiveObject: function(systemid) {
			this.activeObjectCallbacks.each(function(callback) {
				callback(systemid);
			});
		},
		
		// Maus Actions Dragging, Mausrad und so
		
		/* Handle the wheel angle change (delta) of the mouse wheel */
		_handle: function(delta) {
			
			var change = false;
			
			switch (delta > 0) {
				
				case true:
					if(this.caption_id >= 1) {
						this.target			= this.target + this.options.xstep;
						this.new_caption_id	= this.caption_id - 1;
						change				= true;
					}
					break;
		
				default:
					if(this.caption_id < (this.max - 1)) {
						this.target			= this.target - this.options.xstep;
						this.new_caption_id	= this.caption_id + 1;
						change				= true;
					}
					break;
			}
		
			/* Glide to next (mouse wheel down) / previous (mouse wheel up) image */
			if (change == true)
				this._glideTo(this.target, this.new_caption_id);
		},
	
		_goToImage: function(pos) {
			
			var x_pos = -pos * this.options.xstep;
			
			this._glideTo(x_pos, pos);
		},
	
		/* Event handler for mouse wheel event */
		_wheel: function(event) {
			
			if (this.hasFocus) {	
				var delta = 0;
				
				if (!event)
					event = window.event;
				
				if (event.wheelDelta)
					delta = event.wheelDelta / 120;
				else if (event.detail)
					delta = - event.detail / 3;
				
				if (delta)
					this._handle(delta);
				
				if (event.preventDefault)
					event.preventDefault();
				
				event.returnValue = false;
			}
		},
			
		
		/* This function is called to drag an object (= slider div) */
		_dragstart: function(e) {
			
			if (this.hasFocus) {
				
				var MouseX = Event.pointerX(e);
				
				// das DraggableObject setzen (es wird mit NULL gegengeprüft)
				this.dragobject = this.SliderContainer;
				// den Unterschied festhalten den der Mauszeiger zum Linken X des Sliders bei Dragging Start hatte
				var sliderCO = this.SliderContainer.cumulativeOffset();
				this.dragOffset	= MouseX - sliderCO.left;
			}
			
		},
	
		
		/* This function is called to stop dragging an object */
		/* nicht zu verwechseln mit "TruckStop" */
		_dragstop: function() {
			
			if (this.hasFocus) {
				this.dragobject	= null;
				this.dragging	= false;
			}
			
		},
	
		
		/* This function is called on mouse movement and moves an object (= slider div) on user action */
		_drag: function(e) {
			
			var MouseX = Event.pointerX(e);	// Mouse-X
			
			if(this.hasFocus && this.dragobject != null) {
				
				this.dragging = true;

				// linke x-Koordinate des Sliders
				var scrollbarCO = this.ScrollbarContainer.cumulativeOffset();
				var sliderMargins = parseInt(this.SliderContainer.getStyle('marginLeft')) + parseInt(this.SliderContainer.getStyle('marginRight'));
				this.new_posx = MouseX - this.dragOffset - scrollbarCO.left - sliderMargins - this.Scroller.offsetLeft;
				
				// zur Grenzwerte ermitteln (zur Slider Mitte)
				var leftBoundary = 0;
				var rightBoundary = this.Scroller.Width  - this.conf_slider_width;
				
				var slider_pos		= Math.max(leftBoundary, Math.min(this.new_posx, rightBoundary));
				
				var step_width		= (slider_pos) / ((this.Scroller.Width - this.conf_slider_width) / (this.max - 1));
				
				var image_number	= Math.round(step_width);
				
				var new_target		= - this.options.xstep * image_number;
				var new_caption_id	= image_number;
				
				this.SliderContainer.setStyle({ left: ''.concat(slider_pos + this.Scroller.offsetLeft, 'px') });

				this._glideTo(new_target, new_caption_id);
			}
		},
		
		_handleKeyCode: function(event) {
			
			if (this.hasFocus){
				
				var charCode  = event.keyCode;
				
				switch (charCode) {
					
					case Event.KEY_RIGHT:
						this._handle(-1);
						break;
					
					case Event.KEY_LEFT:
						this._handle(1);
						break;
					
					case Event.KEY_UP:
						this._glideTo(0, 0);
						break;
					
					case Event.KEY_DOWN:
						this._glideTo(- (this.CFObjekte.anzahl - 1) * this.options.xstep, this.CFObjekte.anzahl - 1);
						break;
				}
			}
		},
				
		_handleLeftArrow: function() {
			this._handle(1);
		},
				
		_handleRightArrow: function() {
			this._handle(-1);
		},
						
		_handleScrollbarContainer: function(event) {
			var clickedElement = Event.element(event);
			var clickedX = Event.pointerX(event);
			
			// wurde auf den Scrollbar geklickt (und nicht auf den Slider)?
			if (clickedElement == this.ScrollbarContainer){
				var slider = Object.extend({ width: this.SliderContainer.getWidth() }, this.SliderContainer.cumulativeOffset());
				
				if (clickedX < slider.left)
					this._handle(1);
				else if (clickedX > slider.left + slider.width)
					this._handle(-1);
			}
		}
		
	});
}

