    /**
      * These options are used to define the jump-steps      
      * of the jump buttons.
      */
    function ImageLooopButtonsConfig () {

        // Set the negative jump steps of the navigation buttons
        this.ljButtonPrev = -1;
        this.ljButtonPrev5 = -5;
        this.ljButtonPrev10 = -10;

        // Set the positive jump steps of the navigation buttons
        this.ljButtonNext = 1;
        this.ljButtonNext5 = 5;
        this.ljButtonNext10 = 10;
    }

    /**
     * These options change the look&feel of the looopWindow
     */
    function ImageLooopDesignConfig() {
    
            // Enter width of looopWindow here. Use 400 min!
            // And please don't forget to adopt the value of
            // this.lengthOfSelectBoxMsg appropriately
            this.widthX = "550";
    
            // Enter height of looopWindow here
            this.heightY = "400";	
    		
            // Enter css parameter for the looopWindow border. e.g.: thin solid #FFE384
            this.setBorder = "thin solid #FFE384";
    
            // Enter the background color of looopWindow here
            this.bgcolor = "#EAEAEA";
    
            // Enter the background image path of looopWindow here
            //this.bgImgPath = "images/switcher/default_bg.gif";
    
            // Enter css parameter to repeat the background image. e.g.: repeat
            this.repeatBg = "no-repeat";
    
            // Enter position of looopWindow here
            // !! If you change this setting, please use the complete left, top, 
            // margin-left, margin-top and position variables!!
            //
            // e.g.: 
            // this.position = "left: 10px; top: 10px; margin-left: 0px; margin-top: 0px; position: relative;";
            //
            // To center the looopWindow within the VISIBLE area,
            // enter  this.position = "default";
            // In this case you do not need to care about this.positionPosition
            // as it will be set to "absolute" anyway
            //
            this.position = "default";
            this.positionPosition = "absolute";
    
            // Set the position of the close-button in the looopWindow area
            this.closeBtPosition = "top: 0px; right: 465px;";
    
            // This option activates or deactivates navigation buttons.
            this.showNavButtons = true;
    
            // This option activates or deactivates navigation selectbox.
            this.showSelectBox = true;
    
            // This option sets the length of the text within the navigation selectbox
            this.lengthOfSelectBoxMsg = 100;
    }
	
	// **************************************************************************************************
	// **************************************************************************************************
	// No need to touch anything below (SetOutputCSS for position modification only)
	// **************************************************************************************************
	// **************************************************************************************************
	function ImageLooopModel( designConfig, buttonsConfig ) {
		this.looopJumperInit = false;
		
		this.arrUrlList = new Array();
		
		this.arrIdList = new Array();
		
		this.arrCurrentIndex = 0;

		this.allDivs;
		
		this.selectBox = null;

		this.elBtnMakeOwn;

		this.elBtnClose;
		
		this.elBtnFirst;
		
		this.elBtnLast;	
		
		/******************************************** private methods ***********************************************/
		/**
		 * this method is used to set new internal idx.
		 */
		var setCurrentIdx = function( self, idx ) {
		    self.arrCurrentIndex = parseInt( idx );
		};
		
		var appendAttributeToTag = function ( element, name, value ) {
			var newAttr = document.createAttribute( name );
			newAttr.nodeValue = value;
			element.setAttributeNode( newAttr );
		};
		
		var parseActionId = function (elm) {
			var action = elm.id;
			
			if (action != null) 
			    return action;
			
			return elm.parentNode.id;
		};
		
		var changeCurrentIndex = function ( self, newIdx ) {
			if( newIdx >= self.arrUrlList.length 
			    || newIdx < 0 ) 
					  return false;
			
			self.arrCurrentIndex = newIdx;
		};
		
	       /**
		* This function can only be called from the init() function.
		*
		* @global array arrIdList must be allready filled
		*/
		var initSelectNav = function( self ) {
			if (  self.looopJumperInit) return;

			var looopSelectorDiv = document.getElementById( "ljButtonSelect" );
		  
			if( looopSelectorDiv == null ) return alert( "please add an empty <div> with id=ljButtonSelect. this div is used to declare a select-box." );
			
			self.selectBox = document.createElement("select");

                        if( !designConfig.showSelectBox ) return;

			appendAttributeToTag(self.selectBox, "name", "loooplist");
			appendAttributeToTag(self.selectBox, "size", "1");
			
			self.selectBox.onchange = function() { self.onChangeSelectionOfSelectBox( self.selectBox ); return false; };
			
			looopSelectorDiv.appendChild( self.selectBox );

			for( i in self.arrIdList ) {
			       var selectOption = document.createElement("option");
			       
			       var absoluteJumpPos = i;
			       appendAttributeToTag(selectOption, "value", absoluteJumpPos);
			       
			       var maxLength = designConfig.lengthOfSelectBoxMsg + 3;
			       
			       var trimedContent = self.arrIdList[i] ;
			       
			       if( trimedContent.length > maxLength )
				   trimedContent = trimedContent.substring(0, designConfig.lengthOfSelectBoxMsg) + "...";
				   
			       var content = document.createTextNode( trimedContent );
			       
			       selectOption.appendChild( content );
			       self.selectBox.appendChild( selectOption );
			}		
		};
		
		
       /**
		* This function can only be called from the init() function.
		* It fills the both global arrays arrUrlList and arrIdList.
		*
		* @global array arrUrlList ist empty
		* @global array arrIdList
		* @visibility private
		*/
		var initLoopArrays = function (self) {			
			if (  self.looopJumperInit) return;
		
			var elList = document.getElementsByName("looopMember");
			
			for (var i = 0; i < elList.length; ++i) {
				var sHref = elList[i].href;
				if (sHref.charAt(sHref.length-1)!='/') sHref+="/";
				
				self.arrUrlList[i] = sHref;
				self.arrIdList[i]   = elList[i].id;
			}
		};
		
       /**
		* This function can only be called from the init() function.
		* 
		* @visibility private
		*/
		var initOnclickFunctions = function ( self ) {
			if (  self.looopJumperInit) return;

            self.elBtnClose.onclick = function() { self.onButtonClose(); return false; };

			self.elBtnFirst.onclick = function() { self.onButtonJumpAbsolut(0); return false; };
			
			var lastElement = self.arrUrlList.length - 1 ;
			self.elBtnLast.onclick = function() { self.onButtonJumpAbsolut(lastElement); return false; };
			
			for( i in buttonsConfig ) {
			   var navi =document.getElementById( i );
			   navi.onclick = function() { self.looopJumperBtnClicked(this); return false; };
			}
		};
		
       /**
		* This function can only be called from the init() function.
		*
		* @visibility private
		*/
		var initAllDivs = function ( self ) {
			if ( self.looopJumperInit) return;
		
			// hardcoded divs :::
			self.allDivs = new Array(
				document.getElementById("looopWindow"),
				self.elBtnMakeOwn, self.elBtnClose, self.elBtnFirst, self.elBtnLast
			);
			
			// configured divs :::
			for( i in buttonsConfig ) {
			      self.allDivs.push( document.getElementById(i) );
			}
		};
		
				var showHideDiv = function (el, bShow) {
			try {
				if (bShow && el.style.visibility!="visible")
					el.style.visibility="visible";
				if (!bShow && el.style.visibility!="hidden")
					el.style.visibility="hidden";
			}
			catch (e) {
				alert("A problem is occured ::: " + e.message+" : "+el+","+bShow);
			}
		};

		var showHideDivs = function (elList, bShow) {
			for (i in  elList ) {
				if (elList[i] == null) 
					continue;
					
				showHideDiv(elList[i],bShow);
			}
		};
		
/********************************************************** public methods ********************************************/
		
		this.init = function() {
		   if (  this.looopJumperInit ) return;
		   
		   this.elBtnFirst = document.getElementById("ljButtonPrevAll");
		   this.elBtnLast = document.getElementById("ljButtonNextAll");
		   this.elBtnMakeOwn = document.getElementById("ljMakeOwn");
		   this.elBtnClose = document.getElementById("looopWindowClose");
		   
		   initLoopArrays( this );
		   initOnclickFunctions( this );
		   initSelectNav( this );
		   initAllDivs( this );	    

		   this.looopJumperInit=true;
		};
		
		
        /**
		 * Opens a looopWindow with an index as parameter.
		 *
		 * @global array arrUrlList
		 */
        this. openLooopWindowWithIdx = function ( idx ) {
            
            this.onButtonJumpAbsolut( idx );
			
			showHideDivs( this.allDivs, true);
			
			this.showHideButtons(this.allDivs, true);
		};
		
		/**
		 * Opens a looopWindow with an archor as parameter.
		 *
		 * @global array arrUrlList
		 */
		this. openLooopWindowWithAnchor = function ( elAnchor ) {
			for ( i in this.arrUrlList ) {
				if (this.arrUrlList[i] == elAnchor.href) {
					setCurrentIdx( this, i );
					break;
				}
			}
			
			this.openLooopWindowWithIdx( this.arrCurrentIndex );
		};
		
		this.openLooopWindow = function(elAnchor) {
			//Window.location.hash="toplooop";
		
			this.init();
			
			if( !elAnchor || elAnchor == null ) {
			    var newIdx = Math.round( Math.random() * this.arrUrlList.length - 1 ) ;
			    return this.openLooopWindowWithIdx( newIdx );
			}
			
			var value = parseInt( elAnchor + "" );
			
			if( !isNaN( value ) ) 
			     return this.openLooopWindowWithIdx( value );
			
			this.openLooopWindowWithAnchor( elAnchor );
		};
		
		this.looopJumperBtnClicked = function (elm) {
			var action = parseActionId(elm);
			
			if( action == null ) return false;
			
			var value = parseInt( buttonsConfig[ action ] );
			
			if( value == undefined || isNaN(value) ) 
			     return false;
			
			return this.onButtonJump(value);
		};

		/**
		  * @param integer step number of steps to jump
		  * @global integer arrCurrentIndex current index in the array of elements
		  */
		this.onButtonJump = function (step) {
			var nextPossiblePos = this.arrCurrentIndex + step;
		
			if( this.arrUrlList.length < nextPossiblePos ) return false;
			
			this.arrCurrentIndex += step;
			this.switchLooop( );
			
			return true;
		};
		
		this.onButtonClose = function() {
		    showHideDivs(this.allDivs,false);
		    return true;
		};
		
		this.onChangeSelectionOfSelectBox = function ( selectBox ) {
		    if( !designConfig.showSelectBox ) return;
		
		    var optionNode = selectBox.options[ selectBox.selectedIndex ];
	  
		    var jumpTo = parseInt( optionNode[ 'value' ] );
		    this.onButtonJumpAbsolut(jumpTo);
		};
		
		/**
		  * @param integer newIdx new position in the array
		  * @global integer arrCurrentIndex current index in the array of elements
		  */
		this.onButtonJumpAbsolut = function ( newIdx ) {
			changeCurrentIndex( this, newIdx ) ;
			this.switchLooop( );
			
			return true;
		};
		
		this.showHideButtons = function () {
			for( i in  buttonsConfig ) {
			     var out = "";
			
			     var naviElement = document.getElementById( i );
			     var step = buttonsConfig[i];
			     
			     var possible  = false;
			     
			     var sum =  this.arrCurrentIndex + step;
			     if( step < 0 )
				   possible = sum >= 0;
			     
			     else if( step > 0 ) 
				   possible = sum < this.arrUrlList.length;
			     
			     else return;
					     
			     var showIt = (possible && designConfig.showNavButtons);
					     
			     out += " show it ::: " + showIt + " == " + possible + " (" +   step + " ? " + this.arrCurrentIndex + ") = " + sum +  "\n";		     
			     
			     showHideDiv(naviElement,  showIt);
			}
			
			showHideDiv(this.elBtnFirst, (designConfig.showNavButtons 
									    && (this.arrCurrentIndex!=0)) );
									    
			showHideDiv(this.elBtnLast, (designConfig.showNavButtons 
									    && (this.arrCurrentIndex!=this.arrUrlList.length-1)));
		};
		
		this.switchLooop = function ( ) {
			this.showHideButtons();
			
			var arrUrlListLength = this.arrUrlList.length;
			//var looopW = designConfig.widthX - 103; // value from switcher v1.3
			//var looopH = designConfig.heightY - 52; // value from switcher v1.3
			//var looopW = designConfig.widthX - 60;
			var looopW = designConfig.widthX - 60;
			var looopH = designConfig.heightY - 60; // before: 50

			if (this.arrCurrentIndex>=arrUrlListLength)
				this.arrCurrentIndex=arrUrlListLength-1;

			if (this.arrCurrentIndex<0)
				this.arrCurrentIndex=0;
				
			var uri = window.location.pathname + "";
			var docPos = uri.lastIndexOf( "/" );
					
			var embedUri = window.location.protocol + "//"+ window.location.host + "/plugin/imagelooop/view.html";
			var embedUrl = embedUri + "?url="+this.arrUrlList[this.arrCurrentIndex]+"&w="+looopW+"&h="+looopH;

			iframeLooop.location.href = embedUrl;

			// title-tags of buttons
			this.elBtnFirst.firstChild.firstChild.setAttribute("title", this.arrIdList[0]);

			this.elBtnLast.firstChild.firstChild.setAttribute("title", this.arrIdList[arrUrlListLength-1]);
			 
			 
			for( i in  buttonsConfig ) {
			     var naviElement = document.getElementById( i );
			     
			     var jumpStep = parseInt( buttonsConfig[ i ] );
			     if( isNaN(jumpStep) ) continue;
			     
			     var newIdx = Math.max(this.arrCurrentIndex + jumpStep, 0);
			     
			     naviElement .firstChild.firstChild.setAttribute( "title", 
						    this.arrIdList[ newIdx ] );
			}
			
			if( designConfig.showSelectBox )
			     this.selectBox.selectedIndex = this.arrCurrentIndex;
		};
	}	
	
	var imageLooopDesignConfig = new ImageLooopDesignConfig();
    var imageLooopModel = new ImageLooopModel(imageLooopDesignConfig, new ImageLooopButtonsConfig());
	var cur_looop;
    var cur_anchor;
    
	function getLooop(_looop, _anchor) {
        
        cur_looop = _looop;
        cur_anchor = _anchor;
        
        var oLooopWin = document.getElementById("looopWindow"); 
        if(oLooopWin) {
        
            setLooopPos(oLooopWin);            
            openLooopWindow(cur_looop); 
            
        } else if(ajGetXmlRequester()) {            
            
            var sParam = "wxnav=500&hynav=350";
            var sUrl = "/ajx/looop/show.do";
		    var pid = Math.round(Math.random() * 100);
					
		    ajSendRequest(sUrl, sParam, 0, pid, "catchLooop");
        }
        
        location.href = "#"+_anchor;
    }
    
    function catchLooop(response) {   
    
        response = unescape(response);
                
        document.getElementById("divLooop").innerHTML = response;
        
        var oLooopWin = document.getElementById("looopWindow"); 
        
        setLooopPos(oLooopWin);
        
        openLooopWindow(cur_looop);        
    }
    
    function setLooopPos(oLooopWin) {
        
        var oAnchor = document.getElementById(cur_anchor);
        var iTop = getParentProps(oAnchor, "offsetTop") + oAnchor.offsetHeight;
 	           
        oLooopWin.style.position = "absolute";
        oLooopWin.style.left = 131;
        oLooopWin.style.top = iTop+30;     
        
        //oLooopWin.style = "left: 100px; top: 100px; margin-left: 0px; margin-top: 0px; position: absolute;";   
    }

	function openLooopWindow(elAnchor) {    
		imageLooopModel.openLooopWindow( elAnchor );
	}
	

