/**
 * COVERFLOW
 * Erweiterung des Scripts ImageFlow
 * !! prototype.js > 1.6 wird benoetigt !!
 */

 
 /**
 * SNM - Changelog
 *
 * Version: 1.1 (26.04.09)
 * Erweitert um neue Paramter.
 *
 * Version: 1.2 (15.02.10)
 * Interne HTML-Struktur geaendert,
 * erweitertes Ein- und Ausgabeverfahren.
 *
 * Version: 1.3 (01.07.10)
 * Anzeige ueber mehrere Jahre erweitert.
 */
 

/*
Name:       ImageFlow
Version:    1.1 (March 13 2008)
Author:     Finn Rudolph
Support:    http://finnrudolph.de/ImageFlow

Licence:    ImageFlow is licensed under a Creative Commons 
            Attribution-Noncommercial 3.0 Unported License 
            (http://creativecommons.org/licenses/by-nc/3.0/).

            You are free:
                + to Share - to copy, distribute and transmit the work
                + to Remix - to adapt the work

            Under the following conditions:
                + Attribution. You must attribute the work in the manner specified by the author or licensor 
                  (but not in any way that suggests that they endorse you or your use of the work). 
                + Noncommercial. You may not use this work for commercial purposes. 

            + For any reuse or distribution, you must make clear to others the license terms of this work.
            + Any of the above conditions can be waived if you get permission from the copyright holder.
            + Nothing in this license impairs or restricts the author's moral rights.

Credits:    This script is based on Michael L. Perrys Cover flow in Javascript [1].
            The reflections are generated server-sided by a slightly hacked version 
            of Richard Daveys easyreflections [2] written in PHP. The mouse wheel 
            support is an implementation of Adomas Paltanavicius JavaScript mouse 
            wheel code [3]. It also uses the domReadyEvent from Tanny O'Haley [4].

            [1] http://www.adventuresinsoftware.com/blog/?p=104#comment-1981
            [2] http://reflection.corephp.co.uk/v2.php
            [3] http://adomas.org/javascript-mouse-wheel/
            [4] http://tanny.ica.com/ICA/TKO/tkoblog.nsf/dx/domcontentloaded-for-browsers-part-v
*/



/* ImageFlow constructor */
function cfImageFlow () {

	/* Setting option defaults */
	this.defaults = {
		aspectRatio:        1.964,          /* Aspect ratio of the ImageFlow container (width divided by height) */
		captions:           true,           /* Toggle captions */
		imageCursor:        'default',      /* Cursor type for all images - default is 'default' */
		ImageFlowID:        'imageFlow',    /* Default id of the ImageFlow container */
		imageFocusM:        1.2,            /* Multiplicator for the focussed image size in percent */
		imageFocusMax:      2,              /* Max number of images on each side of the focussed one */
		imagesHeight:       0.67,           /* Height of the images div container in percent (D:0.67) */
		imagesM:            1.0,            /* Multiplicator for all images in percent */
		onClick:            function() { eval(this.attributes["onclick"].value); },   /* Onclick behaviour */
		opacity:            false,          /* Toggle image opacity */
		opacityArray:       [10,8,6,4,2],   /* Image opacity (range: 0 to 10) first value is for the focussed image */
		percentLandscape:   150,            /* Scale landscape format */
		percentOther:       120,            /* Scale portrait and square format */
		preloadImages:      true,           /* Toggles loading bar (false: requires img attributes height and width) */
		reflections:        true,           /* Toggle reflections */
		reflectionGET:      '&bgc=000000',  /* Pass variables via the GET method to the reflect_.php script */
		reflectionP:        0.8,            /* Height of the reflection in percent of the source image */
		reflectionPNG:      false,          /* Toggle reflect2.php or reflect3.php */
		scrollbarP:         0.6,            /* Width of the scrollbar in percent */
		slider:             true,           /* Toggle slider */
		sliderCursor:       'e-resize',     /* Slider cursor type - default is 'default' */
		sliderWidth:        14,             /* Width of the slider in px */
		startID:            1,              /* Glide to this image ID on startup */
		startAnimation:     false,          /* Animate images moving in from the right on startup */
		xStep:              160,            /* Step width on the x-axis in px */
        addImgPaddingTop:   120,            /* Beeinflusst den oberen Abstand der Coverbilder */
        addTextPaddingSide: 10,             /* Beeinflusst den linken und rechten Abstand des Covertextes */
        dataUpdateMode:     true,           /* Zeigt zusaetzliche Buttons fuer dynamisches Datenhandling an */
        startYear:          2010,           /* Stellt das Zeitscalajahr ein */
        endYear:            2010,
        showYears:          1               /* Gibt an, wie viele Jahre ab dem Startdatum angezeigt werden sollen */
	};

	/* Closure for this */
	var thisObject = this;


	/* Initiate ImageFlow */
	this.init = function (options) {
		/* Evaluate options */
		var optionsArray = new Array('aspectRatio', 'captions', 'imageCursor', 'imagesM', 'ImageFlowID', 'imageFocusM', 'imageFocusMax', 'imagesHeight', 'onClick', 'opacity', 'opacityArray', 'percentLandscape', 'percentOther', 'preloadImages', 'reflections', 'reflectionGET', 'reflectionP', 'reflectionPNG', 'scrollbarP', 'slider', 'sliderCursor', 'sliderWidth', 'startID', 'startAnimation', 'xStep', 'addImgPaddingTop', 'addTextPaddingSide', 'dataUpdateMode', 'startYear', 'endYear', 'showYears');
		var max = optionsArray.length;
		for (var i = 0; i < max; i++) {
			var name = optionsArray[i];
			this[name] = (options !== undefined && options[name] !== undefined) ? options[name] : thisObject.defaults[name];
		}

		/* Try to get ImageFlow div element */
		var ImageFlowDiv = $(thisObject.ImageFlowID);
        
		if (ImageFlowDiv) {
			/* Set it global within the ImageFlow scope */
			ImageFlowDiv.style.visibility = 'visible';
			this.ImageFlowDiv = ImageFlowDiv;

			/* Try to create XHTML structure */
			if (this.createStructure()) {
            
				this.imagesDiv = $(thisObject.ImageFlowID+'_images');
				this.captionDiv = $(thisObject.ImageFlowID+'_caption');
				this.scrollbarDiv = $(thisObject.ImageFlowID+'_scrollbar');
				this.sliderDiv = $(thisObject.ImageFlowID+'_slider');
                this.loaderDiv = $(thisObject.ImageFlowID+'_loading');

                this.formSlide = $(thisObject.ImageFlowID+'_formSlide');
                this.formSlideFieldset = $(thisObject.ImageFlowID+'_formSlideFieldset');
                this.formSlideHiddenStart = $(thisObject.ImageFlowID+'_formSlideHiddenStart');
                this.formSlideHiddenEnd = $(thisObject.ImageFlowID+'_formSlideHiddenEnd');
                this.formSlideBtLeft = $(thisObject.ImageFlowID+'_formSlideBtLeft');
                this.formSlideBtRight = $(thisObject.ImageFlowID+'_formSlideBtRight');
                this.formSlideBtLeftBg = $(thisObject.ImageFlowID+'_formSlideBtLeftBg');
                this.formSlideBtRightBg = $(thisObject.ImageFlowID+'_formSlideBtRightBg');
                this.formSlideLeftText = $(thisObject.ImageFlowID+'_formSlideLeftText');
                this.formSlideRightText = $(thisObject.ImageFlowID+'_formSlideRightText');
                this.formSlidePoint = $(thisObject.ImageFlowID+'_formSlideScalaPoint');

				this.indexArray = [];
				this.current = 0;
				this.imageID = 0;
				this.target = 0;
				this.memTarget = 0;
				this.firstRefresh = true;
				this.firstCheck = true;
				this.busy = false;
                
                var diffYear = this.endYear - this.startYear;
                this.maxShownDays = (diffYear <= 0 ? 1 : diffYear) * 365;

				/* Toggle Slider */
				if (this.slider === false) {
					this.scrollbarDiv.style.display = 'none';
				}
                else if (this.dataUpdateMode === true) {
                    this.formSlide.style.display = 'block';
                    this.formSlide.style.visibility = 'visible';
                }
                
                /* Dem Formular Funktionen zuweisen */
                var controlHandles = [this.formSlideBtLeft, this.formSlideBtRight];
                new Control.Slider(controlHandles, this.formSlideFieldset, {
                    increment: 1,
                    range: $R(1, thisObject.maxShownDays),
                    values: $R(1, thisObject.maxShownDays),
                    sliderValue: [1, thisObject.maxShownDays],
                    onSlide: function(v) {
                        var workingDate = new Date();
                        var convertDateObj = null;
                        var pixelModLeft = $("cfPicContainer_formSlideBtLeft").positionedOffset().left;
                        var pixelModRight = $("cfPicContainer_formSlideFieldset").getWidth() - $("cfPicContainer_formSlideBtRight").positionedOffset().left - 5;
                        //thisObject.formSlideBtLeftBg.setStyle({width: (pixelModLeft) + 'px'});
                        //thisObject.formSlideBtRightBg.setStyle({width: (pixelModRight) + 'px'});
                        $("cfPicContainer_formSlideBtLeftBg").style.width = (pixelModLeft) + 'px';
                        $("cfPicContainer_formSlideBtRightBg").style.width = (pixelModRight) + 'px';                        

                        var leftSliderYear = thisObject.startYear + Math.floor(v[0] / 365);
                        var leftSliderDay = v[0] - (Math.floor(v[0] / 365) * 365);
                        var rightSliderYear = thisObject.startYear + Math.floor(v[1] / 365);
                        var rightSliderDay = v[1] - (Math.floor(v[1] / 365) * 365);
                        
                        convertDateObj = thisObject.getDateFromDay(leftSliderDay, leftSliderYear);
                        $(thisObject.formSlideLeftText).innerHTML = convertDateObj.d + '.' + convertDateObj.m + '.' + convertDateObj.y;
                        convertDateObj = thisObject.getDateFromDay(rightSliderDay, rightSliderYear);
                        $(thisObject.formSlideRightText).innerHTML = convertDateObj.d + '.' + convertDateObj.m + '.' + convertDateObj.y;
                    },
                    onChange: function(v) {
                        var pixelModLeft = $("cfPicContainer_formSlideBtLeft").positionedOffset().left;
                        var pixelModRight = $("cfPicContainer_formSlideFieldset").getWidth() - $("cfPicContainer_formSlideBtRight").positionedOffset().left - 5;
                        //thisObject.formSlideBtLeftBg.setStyle({width: (pixelModLeft) + 'px'});
                        //thisObject.formSlideBtRightBg.setStyle({width: (pixelModRight) + 'px'});
                        $("cfPicContainer_formSlideBtLeftBg").style.width = (pixelModLeft) + 'px';
                        $("cfPicContainer_formSlideBtRightBg").style.width = (pixelModRight) + 'px';
              
                        var workingDate = new Date();
                        var convertDateObj = null;
                        
                        var leftSliderYear = thisObject.startYear + Math.floor(v[0] / 365);
                        var leftSliderDay = v[0] - (Math.floor(v[0] / 365) * 365);
                        var rightSliderYear = thisObject.startYear + Math.floor(v[1] / 365);
                        var rightSliderDay = v[1] - (Math.floor(v[1] / 365) * 365);
                        
                        // Neuen Wert fuer das Startdatum setzen
                        convertDateObj = thisObject.getDateFromDay(leftSliderDay, leftSliderYear);
                        thisObject.formSlideHiddenStart.value = Date.UTC(convertDateObj.y, convertDateObj.m-1, convertDateObj.d-1);
                        
                        // Neuen Wert fuer das Enddatum setzen
                        convertDateObj = thisObject.getDateFromDay(rightSliderDay, rightSliderYear);
                        thisObject.formSlideHiddenEnd.value = Date.UTC(convertDateObj.y, convertDateObj.m-1, convertDateObj.d);
                        
                        // RESET
                        thisObject.indexArray = [];
                        thisObject.indexArrayText = [];
                        
                        var node = null;
                        for (var i = 0;i < thisObject.imagesDiv.childNodes.length; i++) {
                            node = thisObject.imagesDiv.childNodes[i];
                            if (node && node.nodeType == 1 && (node.nodeName == 'IMG' || node.nodeName == 'DIV')) {
                                //Effect.Fade(node, {duration:1.5});
                                node.hide();
                            }
                        }
                        
                        // RELOAD
                        thisObject.refresh();
                    }
                });
                
                /* Den Punkt auf heutiges Datum schieben */
                var workingDate = new Date();
                this.formSlidePoint.style.left = ((thisObject.formSlide.getWidth() / thisObject.maxShownDays) * workingDate.getDOY()) - 0.025 - (thisObject.formSlidePoint.getWidth() / 2) + "px";

				/* Set height of the ImageFlow container and center the loading bar */
				var width = this.ImageFlowDiv.offsetWidth;
				var height = Math.round(width / thisObject.aspectRatio);
				//document.getElementById(thisObject.ImageFlowID+'_loading_txt').style.paddingTop = ((height * 0.5) -22) + 'px';
				ImageFlowDiv.style.height = height + 'px';

				/* Init loading progress */
				this.loadingProgress();
			}
		}
	};


	/* Create HTML Structure */
	this.createStructure = function() {
    
		/* Create images div container */
		var imagesDiv = document.createElement('div');
        
		imagesDiv.setAttribute('id', thisObject.ImageFlowID+'_images');
		imagesDiv.setAttribute('class', 'images');
		imagesDiv.setAttribute('className', 'images');

		/* Shift all images into the images div */
        var nodeImgBox = null;
		var max = this.ImageFlowDiv.childNodes.length;

		for (var index = 0; index < max; index++) {
        
			nodeImgBox = this.ImageFlowDiv.childNodes[index];
			if (nodeImgBox && nodeImgBox.nodeType == 1 && nodeImgBox.nodeName == 'DIV') {
                
                var genPicContainer = new Element("div", {
                    "name":nodeImgBox.getAttribute("name"),
                    "className":"genPicContainer"
                });
                
                boxmax = nodeImgBox.childNodes.length;
           		var node = null;
                for (var index2 = 0; index2 < boxmax; index2++) {
                    node = nodeImgBox.childNodes[index2];
                    
                    // Nach dem Bild suchen
                    if (node && node.nodeType == 1 && node.nodeName == 'IMG') {
        				/* Add 'reflect.php?img=' */
        				if (thisObject.reflections === true) {
        					var version = '2';
        					if (thisObject.reflectionPNG === true) {
        						version = '3';
        					}
        					var src = node.getAttribute('src',2);
        					src =  '/js/coverflow/cflow_reflectv'+version+'.php?img='+src+thisObject.reflectionGET;
        					node.setAttribute('src',src);
        				}

        				var imageNode = node.cloneNode(true);
        				genPicContainer.appendChild(imageNode);
                    }
                    
                    // Nach seinem Textblock suchen
                    if (node && node.nodeType == 1 && node.nodeName == 'DIV' && node.className == 'pictext') {
                        var textNode = node.cloneNode(true);
        				genPicContainer.appendChild(textNode);
                    }
                }
                
                // Neu generierte Bildbox der Bilderflowbox zuordnen
                imagesDiv.appendChild(genPicContainer);
			}
		}

		/* Create loading text container */
		var loadingP = document.createElement('p');
		var loadingText = document.createTextNode(' ');
		loadingP.setAttribute('id',thisObject.ImageFlowID+'_loading_txt');
		loadingP.appendChild(loadingText);

		/* Create loading div container */
		var loadingDiv = document.createElement('div');
		loadingDiv.setAttribute('id',thisObject.ImageFlowID+'_loading');
		loadingDiv.setAttribute('class','loading');
		loadingDiv.setAttribute('className','loading');
        
        // Padding Workaround
        var loadingDivBarBorder = new Element('div', {
            'class': 'loadingbarborder'
        });

		/* Create loading bar div container inside the loading div */
		var loadingBarDiv = document.createElement('div');
		loadingBarDiv.setAttribute('id',thisObject.ImageFlowID+'_loading_bar');
		loadingBarDiv.setAttribute('class','loading_bar');
		loadingBarDiv.setAttribute('className','loading_bar');
        
        loadingDivBarBorder.appendChild(loadingBarDiv);
		loadingDiv.appendChild(loadingDivBarBorder);
        loadingDiv.appendChild(loadingP);
        
		/* Create captions div container */
		var captionDiv = document.createElement('div');
		captionDiv.setAttribute('id',thisObject.ImageFlowID+'_caption');
		captionDiv.setAttribute('class','caption');
		captionDiv.setAttribute('className','caption');

		/* Create slider div container inside the scrollbar div */
		var scrollbarDiv = document.createElement('div');
		scrollbarDiv.setAttribute('id',thisObject.ImageFlowID+'_scrollbar');
		scrollbarDiv.setAttribute('class','scrollbar');
		scrollbarDiv.setAttribute('className','scrollbar');
        
        // Div Background Button Left
        var scrollbarDivContainer = new Element('div', {
            'id': thisObject.ImageFlowID+'_scrollbarContainer',
            'className': 'scrollbarContainer'
        });
        
		var sliderDiv = document.createElement('div');
		sliderDiv.setAttribute('id',thisObject.ImageFlowID+'_slider');
		sliderDiv.setAttribute('class','slider');
		sliderDiv.setAttribute('className','slider');
        
        scrollbarDivContainer.appendChild(sliderDiv);
		scrollbarDiv.appendChild(scrollbarDivContainer);
        
        /* Erstellen der DataUpdateForm */
        // Form
        var workingDate = new Date();
		var formSlide = new Element('form', {
            'id': thisObject.ImageFlowID+'_formSlide'
        });
        // Fieldset
        var formSlideFieldset = new Element('fieldset', {
            'id': thisObject.ImageFlowID+'_formSlideFieldset'
        });
        // Input Hidden Start
        var formSlideHiddenStartValue = new Element('input', {
            'id': thisObject.ImageFlowID+'_formSlideHiddenStart',
            'name': thisObject.ImageFlowID+'_formSlideHiddenStart',
            'type': 'hidden',
            'value': Date.UTC(thisObject.startYear, 0, 1)
        });
        // Input Hidden End
        var formSlideHiddenEndValue = new Element('input', {
            'id': thisObject.ImageFlowID+'_formSlideHiddenEnd',
            'name': thisObject.ImageFlowID+'_formSlideHiddenEnd',
            'type': 'hidden',
            'value': Date.UTC((thisObject.endYear), 0, 1)
        });
        // Input Button Left
        var formSlideBtLeft = new Element('input', {
            'id': thisObject.ImageFlowID+'_formSlideBtLeft',
            'type': 'button'
        });
        // Div Background Button Left
        var formSlideBtLeftBg = new Element('div', {
            'id': thisObject.ImageFlowID+'_formSlideBtLeftBg',
            'className': 'slideButtonBg'
        });
        var formSlideBtLeftBgBorder = new Element('div', {
            'className': 'slideButtonLeftBgBorder'
        });
        // Input Button Right
        var formSlideBtRight = new Element('input', {
            'id': thisObject.ImageFlowID+'_formSlideBtRight',
            'type': 'button'
        });
        // Div Background Button Reft
        var formSlideBtRightBg = new Element('div', {
            'id': thisObject.ImageFlowID+'_formSlideBtRightBg',
            'className': 'slideButtonBg'
        });
        var formSlideBtRightBgBorder = new Element('div', {
            'className': 'slideButtonRightBgBorder'
        });
        // Div Left Textinfo
        var formSlideLeftText = new Element('div', {
            'id': thisObject.ImageFlowID+'_formSlideLeftText'
        });
        // Div Right Textinfo
        var formSlideRightText = new Element('div', {
            'id': thisObject.ImageFlowID+'_formSlideRightText'
        });
        
        var workingDate = new Date();
        var convertDateObj = null;
                        
        var leftStartYear = thisObject.startYear;
        var leftStartDay = 1;
        var rightStartYear = thisObject.endYear;
        var rightStartDay = 1;
        
        convertDateObj = thisObject.getDateFromDay(leftStartDay, leftStartYear);           
        formSlideLeftText.innerHTML = convertDateObj.d + '.' + convertDateObj.m + '.' + convertDateObj.y;
        
        convertDateObj = thisObject.getDateFromDay(rightStartDay, rightStartYear);           
        formSlideRightText.innerHTML = convertDateObj.d + '.' + convertDateObj.m + '.' + convertDateObj.y;

        // Div Point
        var formSlidePoint = new Element('div', {
            'id': thisObject.ImageFlowID+'_formSlideScalaPoint'
        });
        
        // Formular zusammenbauen
        formSlideFieldset.appendChild(formSlideLeftText);
        formSlideFieldset.appendChild(formSlideRightText);
        formSlideFieldset.appendChild(formSlidePoint);
        formSlideFieldset.appendChild(formSlideHiddenStartValue);
        formSlideFieldset.appendChild(formSlideHiddenEndValue);
        formSlideBtLeftBg.appendChild(formSlideBtLeftBgBorder);
        formSlideFieldset.appendChild(formSlideBtLeftBg);
        formSlideBtRightBg.appendChild(formSlideBtRightBgBorder);
        formSlideFieldset.appendChild(formSlideBtRightBg);
        formSlideFieldset.appendChild(formSlideBtLeft);
        formSlideFieldset.appendChild(formSlideBtRight);
        formSlide.appendChild(formSlideFieldset);
        
        // Formular dem Scroll-Div hinzufuegen
        scrollbarDivContainer.appendChild(formSlide);

		/* Update document structure and return true on success */
		var success = false;
		if (thisObject.ImageFlowDiv.appendChild(imagesDiv) &&
			thisObject.ImageFlowDiv.appendChild(loadingDiv) &&
			thisObject.ImageFlowDiv.appendChild(captionDiv) &&
			thisObject.ImageFlowDiv.appendChild(scrollbarDiv))
		{
			/* Remove image nodes outside the images div */
			for(index = 0; index < max; index++)
			{
				node = this.ImageFlowDiv.childNodes[index];
				if (node && node.nodeType == 1 && (node.nodeName == 'IMG'
                    )) {// || (node.nodeName == 'DIV' && node.classname == 'pictext')
					this.ImageFlowDiv.removeChild(node);
				}
			}
			success = true;
		}
		return success;
	};


	/* Manages loading progress and calls the refresh function */
	this.loadingProgress = function() {
    
		var p = thisObject.loadingStatus();
		if (p < 100 || thisObject.firstCheck === true && thisObject.preloadImages === true) {
			/* Insert a short delay if the browser loads rapidly from its cache */
			if (thisObject.firstCheck === true && p == 100) {
				thisObject.firstCheck = false;
				window.setTimeout(thisObject.loadingProgress, 100);
			}
			else {
				window.setTimeout(thisObject.loadingProgress, 40);
			}
		}
		else {      
			/* Hide loading elements */
			document.getElementById(thisObject.ImageFlowID+'_loading_txt').style.display = 'none';
			document.getElementById(thisObject.ImageFlowID+'_loading').style.display = 'none';

			/* Refresh ImageFlow on window resize - delay adding this event for the IE */
			window.setTimeout(thisObject.addResizeEvent, 1000);

			/* Initialize Mouse and key support */
			thisObject.initMouseWheel();
			thisObject.MouseDrag.init();
			thisObject.Key.init();

			/* Call refresh function */
			thisObject.refresh(true);

			/* Unhide scrollbar elements */
			document.getElementById(thisObject.ImageFlowID+'_scrollbar').style.visibility = 'visible';

			/* Glide to start image */
			var startID = thisObject.startID-1;
			if (startID < 0 ) {
				startID = 0;
			}
			if (startID > thisObject.max) {
				startID = thisObject.max -1;
			}
			thisObject.glideTo(startID);

			/* Animate images moving in from the right */
			if(thisObject.startAnimation === true) {
				thisObject.moveTo(5000);
			}
		}
	};


	/* Returns loaded images in percent, sets loading bar width and loading text */
	this.loadingStatus = function() {
		var max = thisObject.imagesDiv.childNodes.length;
		var i = 0, completed = 0;
		var image = null;
		for (var index = 0; index < max; index++) {
			image = thisObject.imagesDiv.childNodes[index].getElementsByTagName("img")[0];
			if (image && image.nodeType == 1 && image.nodeName == 'IMG') {
				if (image.complete === true) {
					completed++;
				}
				i++;
			}
		}
		var finished = Math.round((completed/i)*100);
		var loadingBar = document.getElementById(thisObject.ImageFlowID+'_loading_bar');
		loadingBar.style.width = finished+'%';

		var loadingP = document.getElementById(thisObject.ImageFlowID+'_loading_txt');
		var loadingTxt = document.createTextNode('Bilder werden geladen ... '+completed+'/'+i);
		loadingP.replaceChild(loadingTxt,loadingP.firstChild);
		return finished;
	};


	/* Cache EVERYTHING that only changes on refresh or resize of the window */
	this.refresh = function() {
		/* Cache global variables */
		this.iWidth = thisObject.imagesDiv.offsetWidth;
		this.maxHeight = Math.round(thisObject.iWidth / thisObject.aspectRatio);
		this.maxFocus = thisObject.imageFocusMax * thisObject.xStep;
		this.size = thisObject.iWidth * 0.5;
		this.sliderWidth = thisObject.sliderWidth * 0.5;
		this.scrollbarWidth = (thisObject.iWidth - ( Math.round(thisObject.sliderWidth) * 2)) * thisObject.scrollbarP;
		this.imagesDivHeight = Math.round(thisObject.maxHeight * thisObject.imagesHeight);

		
		/* Change imageflow div properties */
		thisObject.ImageFlowDiv.style.height = thisObject.maxHeight + 'px';

		/* Change images div properties */
		thisObject.imagesDiv.style.height =  thisObject.imagesDivHeight + 'px';

		/* Change captions div properties */
		thisObject.captionDiv.style.width = thisObject.iWidth + 'px';
		thisObject.captionDiv.style.marginTop = Math.round(thisObject.iWidth * 0.02) + 'px';

		/* Change scrollbar div properties */
		//thisObject.scrollbarDiv.style.width = thisObject.scrollbarWidth + 'px';
		//thisObject.scrollbarDiv.style.marginTop = Math.round(thisObject.iWidth * 0.02) + 'px';
		//thisObject.scrollbarDiv.style.marginLeft = Math.round(thisObject.sliderWidth + ((thisObject.iWidth - thisObject.scrollbarWidth)/2)) + 'px';

		/* Set slider attributes */
		//thisObject.sliderDiv.style.cursor = thisObject.sliderCursor;
		//thisObject.sliderDiv.onmousedown = function () { thisObject.MouseDrag.start(this); return false;};

		/* Set the reflection multiplicator */
		var multi = (thisObject.reflections === true) ? thisObject.reflectionP + 1 : 1;

		/* Set image attributes */
		var max = thisObject.imagesDiv.childNodes.length;
		var i = 0;
        var imax = 0;
        var j = 0;
		var image = null;
        
		for (var index = 0; index < max; index++) {
			imageBox = thisObject.imagesDiv.childNodes[index];
            if (thisObject.inTime(imageBox)) {
            
                var max2 = imageBox.childNodes.length;
                for (var index2 = 0; index2 < max2; index2++) {
                    image = imageBox.childNodes[index2];
                    if (image !== null && image.nodeType == 1 && image.nodeName == 'IMG') {
                    
                        this.indexArray[i] = index;

                        /* Set image attributes to store values */
                        image.url = image.getAttribute('longdesc');
                        imageBox.xPosition = (-i * thisObject.xStep);
                        imageBox.i = i;

                        /* Add width and height as attributes only once */
                        if (thisObject.firstRefresh) {
                            if (image.getAttribute('width') !== null && image.getAttribute('height') !== null) {
                                imageBox.w = image.getAttribute('width');
                                /* BUGFIX > IE6 IE7 werten hier falsch aus! */
                                //image.h = image.getAttribute('height') * multi;
                                imageBox.h = image.getAttribute('height');
                            }
                            else{
                                imageBox.w = image.width;
                                imageBox.h = image.height;
                            }
                        }
                        /* Check source image format. Get image height minus reflection height! */
                        if((imageBox.w) > (imageBox.h / (thisObject.reflectionP + 1)))
                        {
                            /* Landscape format */
                            imageBox.pc = thisObject.percentLandscape;
                            imageBox.pcMem = thisObject.percentLandscape;
                        }
                        else
                        {
                            /* Portrait and square format */
                            imageBox.pc = thisObject.percentOther;
                            imageBox.pcMem = thisObject.percentOther;
                        }

                        /* Set image cursor type */
                        image.style.cursor = thisObject.imageCursor;
                        i++;
                        imax++;
                    }
                }
                
                Effect.Appear(imageBox, {duration:1.5});
            }
		}
		this.max = thisObject.indexArray.length;

		/* Reset variable */
		if (thisObject.firstRefresh)	{
			thisObject.firstRefresh = false;
		}

        /* Check whether the image position to display is in view area */
        if (thisObject.imageID >= imax) {
            thisObject.imageID = imax - 1;
        }
        
		/* Display images in current order */
		thisObject.glideTo(thisObject.imageID);
		thisObject.moveTo(thisObject.current);
	};


	/* Main animation function */
	this.moveTo = function(x) {
    
		this.current = x;
		this.zIndex = thisObject.max;

		/* Main loop */
		for (var index = 0; index < thisObject.max; index++) {
			var imageBox = thisObject.imagesDiv.childNodes[thisObject.indexArray[index]];
            var picObj = imageBox.getElementsByTagName("img")[0];
            var textObj = imageBox.getElementsByTagName("div")[0];
            
			var currentImageBox = index * -thisObject.xStep;

			/* Don't display imageBoxs that are not conf_focussed */
            if (thisObject.inTime(imageBox)) {
                if ((currentImageBox + thisObject.maxFocus) < thisObject.memTarget || (currentImageBox - thisObject.maxFocus) > thisObject.memTarget) {
                    imageBox.style.visibility = 'hidden';
                    imageBox.style.display = 'none';
                }
                else {
                    var z = (Math.sqrt(10000 + x * x) + 100) * thisObject.imagesM;
                    var xs = x / z * thisObject.size + thisObject.size;

                    /* Still hide images until they are processed, but set display style to block */
                    imageBox.style.display = 'block';

                    /* Process new imageBox height and imageBox width */
                    var newImageH = (imageBox.h / imageBox.w * imageBox.pc) / z * thisObject.size;
                    var newImageW = 0;
                    
                    /* Den Transparenzwert berechnen, um rechte und linke Objekte auszublenden */
                    var focusOpacity = 2 / (z / 1000) / 7 - 0.35;
                    textObj.style.opacity = focusOpacity;
                    textObj.style.filter = 'alpha(opacity=' + (focusOpacity * 100) + ')';
                    
                    switch (newImageH > thisObject.maxHeight) {
                        case false:
                            newImageW = imageBox.pc / z * thisObject.size;
                            break;

                        default:
                            newImageH = thisObject.maxHeight;
                            newImageW = imageBox.w * newImageH / imageBox.h;
                            break;
                    }

                    var newImageTop = (thisObject.imagesDivHeight - newImageH) + ((newImageH / (thisObject.reflectionP + 1)) * thisObject.reflectionP) + thisObject.addImgPaddingTop;

                    /* Set new imageBox properties */
                    imageBox.style.left = xs - (imageBox.pc / 2) / z * thisObject.size + 'px';
                    
                    if (newImageW && newImageH) {
                        imageBox.style.height = newImageH + 'px';
                        imageBox.style.width = newImageW + 'px';
                        imageBox.getElementsByTagName("img")[0].style.width = newImageW + 'px';
                        imageBox.style.top = newImageTop + 'px';
                        
                        textObj.style.top = (newImageH * (thisObject.reflectionP / 2 - 0.05) * -1) + 'px';
                    }
                    imageBox.style.visibility = 'visible';

                    /* Set imageBox layer through zIndex */
                    switch (x < 0) {
                        case true:
                            this.zIndex++;
                            break;

                        default:
                            this.zIndex = thisObject.zIndex - 1;
                            break;
                    }

                    /* Change zIndex and onclick function of the focussed imageBox */
                    switch (imageBox.i == thisObject.imageID) {
                        case false:
                            imageBox.onclick = function() {
                                thisObject.glideTo(this.i);
                            };
                            break;

                        default:
                            this.zIndex = thisObject.zIndex + 1;
                            if (imageBox.url !== '') {
                                imageBox.onclick = thisObject.onClick;
                            }
                            break;
                    }
                    imageBox.style.zIndex = thisObject.zIndex;
                }
                x += thisObject.xStep;
            }
		}
	};


	/* Initializes image gliding animation */
	this.glideTo = function(boxID) {
    
		/* Calculate new image position target */
		var x = -boxID * thisObject.xStep;
		this.target = x;
		this.memTarget = x;
		this.imageID = boxID;

		/* Display new caption */
        /*
		var caption = thisObject.imagesDiv.childNodes[boxID].getAttribute('alt');
		if (caption === '' || thisObject.captions === false) {
			caption = '&nbsp;';
		}
		thisObject.captionDiv.innerHTML = caption;
                    */
        
		/* Set scrollbar slider to new position */
		if (thisObject.MouseDrag.busy === false) {
            if (thisObject.updateDataMode === true) {
                this.newSliderX = (boxID * thisObject.scrollbarWidth) / (thisObject.max-1) - thisObject.MouseDrag.newX;
                thisObject.sliderDiv.style.marginLeft = (thisObject.newSliderX - thisObject.sliderWidth) + 'px';
            }
        }

		/* Only process if opacity or a multiplicator for the focussed image has been set */
		if(thisObject.opacity === true || thisObject.imageFocusM !== thisObject.defaults.imageFocusM) {
			/* Set opacity for centered image */
			thisObject.setOpacity(thisObject.imagesDiv.childNodes[boxID], thisObject.opacityArray[0]);
			thisObject.imagesDiv.childNodes[boxID].pc = thisObject.imagesDiv.childNodes[boxID].pc * thisObject.imageFocusM;

			/* Set opacity for the other images that are displayed */
			var opacityValue = 0;
			var rightID = 0;
			var leftID = 0;
			var last = thisObject.opacityArray.length;

			for (var i = 1; i < (thisObject.imageFocusMax+1); i++) {
				if ((i+1) > last) {
					opacityValue = thisObject.opacityArray[last-1];
				}
                else {
					opacityValue = thisObject.opacityArray[i];
				}

				rightID = boxID + i;
				leftID = boxID - i;

				if (rightID < thisObject.max) {
					thisObject.setOpacity(thisObject.imagesDiv.childNodes[rightID], opacityValue);
					thisObject.imagesDiv.childNodes[rightID].pc = thisObject.imagesDiv.childNodes[rightID].pcMem;
				}
				if (leftID >= 0) {
					thisObject.setOpacity(thisObject.imagesDiv.childNodes[leftID], opacityValue);
					thisObject.imagesDiv.childNodes[leftID].pc = thisObject.imagesDiv.childNodes[leftID].pcMem;
				}
			}
		}

		/* Animate gliding to new x position */
		if (thisObject.busy === false) {
			window.setTimeout(thisObject.animate, 50);
			thisObject.busy = true;
		}
	};


	/* Animates image gliding */
	this.animate = function()
	{
		switch (thisObject.target < thisObject.current-1 || thisObject.target > thisObject.current+1)
		{
			case true:
				thisObject.moveTo(thisObject.current + (thisObject.target-thisObject.current)/3);
				window.setTimeout(thisObject.animate, 50);
				thisObject.busy = true;
				break;

			default:
				thisObject.busy = false;
				break;
		}
	};


	/* Set image opacity */
	this.setOpacity = function(object, value) {
		if(thisObject.opacity === true) {
			object.style.opacity = value/10;
			object.style.filter = 'alpha(opacity=' + value*10 + ')';
		}
	};
    
    
    /* Zeit aus Node-Attribute "Name" auslesen und mit "jetzt" vergleichen */
    this.inTime = function(node) {
        if (node && node != 'undefined' && node != null) {

            var nodeNameValue = node.getAttribute('name');
            
            if (nodeNameValue && nodeNameValue != 'undefined' && nodeNameValue != null) {
                nodeNameVals = nodeNameValue.split('_');
                nodeStartDate = nodeNameVals[1];
                nodeEndDate = nodeNameVals[2];
                
                showStartDate = thisObject.formSlideHiddenStart.value;
                showEndDate = thisObject.formSlideHiddenEnd.value;
                
                // Ein Einzeldatum
                if (nodeStartDate == nodeEndDate &&
                    nodeStartDate <= showStartDate &&
                    nodeEndDate >= showEndDate) {
                    return true;
                }
                
                // Liegt genau zwischen Start und Ende
                if (nodeStartDate >= showStartDate &&
                    nodeEndDate <= showEndDate) {
                    return true;
                }
                
                // Noch in der Laufzeit
                if (nodeStartDate != nodeEndDate &&
                    nodeEndDate >= showStartDate &&
                    nodeStartDate <= showEndDate) {
                    return true;
                }
            }
        }
        
        return false;
    };
    
    
    this.getDateFromDay = function(dayNr, year) {
        var accumulate    = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 333, 365];
        var accumulateLY  = [0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 334, 365];
        
        var daySpan = null;
        if (thisObject.isLeapYear(year)) {
            daySpan = accumulateLY;
        }
        else {
            daySpan = accumulate;
        }
        
        var dayMon = 0;
        for (var m=0; m < daySpan.length; m++) {
            if (dayNr <= daySpan[m]) {
                dayMon = dayNr - daySpan[m-1];
                break;
            }
        }
        
        if (isNaN(dayMon) || dayMon == 0) {
            dayMon = 1;
        }
        
        if (isNaN(m) || m == 0) {
            m = 1;
        }
        
        return {'d':dayMon, 'm':m, 'y':year};
    };
    
    
    this.isLeapYear = function(year) {
        if ((year/4)   != Math.floor(year/4))   return false;
        if ((year/100) != Math.floor(year/100)) return true;
        if ((year/400) != Math.floor(year/400)) return false;
        return true;
    };


    
    
   /**
    * INPUT-EVENT-FUNCTIONS
    */

           

	/* Initialize mouse wheel support */
	this.initMouseWheel = function()
	{
		if(window.addEventListener)
		{
			thisObject.ImageFlowDiv.addEventListener('DOMMouseScroll', thisObject.eventMouseWheel, false);
		}
		thisObject.ImageFlowDiv.onmousewheel = thisObject.eventMouseWheel;
	};


	/* Event handler for mouse wheel events */
	this.eventMouseWheel = function(event)
	{
		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)
		{
			thisObject.handleMouseWheel(delta);
		}
		if (event.preventDefault)
		{
			event.preventDefault();
		}
		event.returnValue = false;
	};


	/* Handle the wheel angle change (delta) of the mouse wheel */
	this.handleMouseWheel = function(delta)
	{
		var change = false;
		var newImageID = 0;
		if(delta > 0)
		{
			if(thisObject.imageID >= 1)
			{
				newImageID = thisObject.imageID -1;
				change = true;
			}
		}
		else {
			if (thisObject.imageID < (thisObject.max-1)) {
				newImageID = thisObject.imageID +1;
				change = true;
			}
		}

		/* Glide to next (mouse wheel down) / previous (mouse wheel up) image */
		if (change === true)
		{
			thisObject.glideTo(newImageID);
		}
	};


	/* MouseDrag */
	this.MouseDrag =
	{
		object: null,
		objectX: 0,
		mouseX: 0,
		newX: 0,
		busy: false,

		/* Init mouse event listener */
		init: function()
		{
			thisObject.addEvent(thisObject.ImageFlowDiv,'mousemove',thisObject.MouseDrag.drag);
			thisObject.addEvent(thisObject.ImageFlowDiv,'mouseup',thisObject.MouseDrag.stop);
			thisObject.addEvent(document,'mouseup',thisObject.MouseDrag.stop);

			/* Avoid text and image selection while dragging  */
			thisObject.ImageFlowDiv.onselectstart = function ()
			{
				var selection = true;
				if (thisObject.MouseDrag.busy === true)
				{
					selection = false;
				}
				return selection;
			};
		},

		start: function(o)
		{
			thisObject.MouseDrag.object = o;
			thisObject.MouseDrag.objectX = thisObject.MouseDrag.mouseX - o.offsetLeft + thisObject.newSliderX;

		},

		stop: function()
		{
			thisObject.MouseDrag.object = null;
			thisObject.MouseDrag.busy = false;
		},

		drag: function(e)
		{
			var posx = 0;
			if (!e)
			{
				e = window.event;
			}
			if (e.pageX)
			{
				posx = e.pageX;
			}
			else if (e.clientX)
			{
				posx = e.clientX + document.body.scrollLeft	+ document.documentElement.scrollLeft;
			}
			thisObject.MouseDrag.mouseX = posx;

			if(thisObject.MouseDrag.object !== null)
			{
				var newX = (thisObject.MouseDrag.mouseX - thisObject.MouseDrag.objectX) + thisObject.sliderWidth;

				/* Make sure, that the slider is moved in proper relation to previous movements by the glideTo function */
				if(newX < ( - thisObject.newSliderX))
				{
					newX = - thisObject.newSliderX;
				}
				if(newX > (thisObject.scrollbarWidth - thisObject.newSliderX))
				{
					newX = thisObject.scrollbarWidth - thisObject.newSliderX;
				}

				/* Set new slider position */
				var step = (newX + thisObject.newSliderX) / (thisObject.scrollbarWidth / (thisObject.max-1));
				var imageID = Math.round(step);
				thisObject.MouseDrag.newX = newX;
				thisObject.MouseDrag.object.style.left = newX + 'px';
				if (thisObject.imageID !== imageID) {
					thisObject.glideTo(imageID);
				}
				thisObject.MouseDrag.busy = true;
			}
		}
	};


	/* Key support */
	this.Key =
	{
		/* Init key event listener */
		init: function()
		{
			document.onkeydown = function(event){ thisObject.Key.handle(event); };
		},

		/* Handle the arrow keys */
		handle: function(event)
		{
			var charCode  = thisObject.Key.get(event);
			switch (charCode)
			{
				/* Right arrow key */
				case 39:
					thisObject.handleMouseWheel(-1);
					break;

				/* Left arrow key */
				case 37:
					thisObject.handleMouseWheel(1);
					break;
			}
		},

		/* Get the current keycode */
		get: function(event)
		{
			event = event || window.event;
			return event.keyCode;
		}
	};


	/* Adds events */
	this.addEvent = function( obj, type, fn )
	{
		if (obj.addEventListener)
		{
			obj.addEventListener( type, fn, false );
		}
		else if (obj.attachEvent)
		{
			obj["e"+type+fn] = fn;
			obj[type+fn] = function() { obj["e"+type+fn]( window.event ); };
			obj.attachEvent( "on"+type, obj[type+fn] );
		}
	};


	/* Adds functions to the window.onresize event - can not be done by addEvent */
	this.addResizeEvent = function()
	{
		var otherFunctions = window.onresize;
		if(typeof window.onresize != 'function')
		{
			window.onresize = function()
			{
				thisObject.refresh();
			};
		}
		else
		{
			window.onresize = function(){
				if (otherFunctions)
				{
					otherFunctions();
				}
				thisObject.refresh();
			};
		}
	};
};


/**
 * JavaScript Extensions
 */
 
Date.prototype.getDOY = function() {
    var onejan = new Date(this.getFullYear(), 0, 1);
    return Math.ceil((this - onejan) / 86400000);
};
