/**
* Class used for the rotation articlelist tile.
*
* Supports periodical execution of rotation, navigation with previous/next links and article links.
*
* If navigation menu is used, the navigation link matching the article that is shown is marked as active with a css class, and it's
* also possible to click on links to switch to matching article.
*
* Clicking on navigation links will stop periodical execution.
*
*/

var RotationArticlelist = Class.create({
	/**
	* @param interval - Number of seconds used in periodical executor. If 0 is given, periodical execution is not used.
	*/
    initialize: function(element,interval) {
    	this.element = element;
    	this.interval = interval;
    	this.tileId = element.id.substring(5);

    	this.articleCounter = 0;
    	
    	// Get all article-divs with correct class-name
    	this.articles = $$('div.rotation-article'); 
    	
    	// Set the first rotation article div to be current
    	this.currentArticle = this.articles.first();

    	// Get navigation menu if set (previous/next links)
    	this.navigation = this.element.select('div.navigation-menu').first(); 
    	
    	
    	
    	// Check if navigation bar is set
    	if(typeof this.navigation == 'undefined' || this.navigation ==  null) {
    		// We now that navigation isn't added, so the variable must be set to null
            this.navigation = null;
        }
        else {
        	// Get all article links with correct class-name
        	// These links is inside the div for navigation menu
    	    this.articleLinks = this.navigation.select('a.rotation-article-link');
    	    this.setActiveArticleLink();
        }
    
    	// Add listeners
    	this.addListeners();
    	
    },
    
    /**
    *	Function used to add listeners to elements
    */
    addListeners: function() {
    	// Start periodical executer with given interval. Interval like 0 indicates that periodical execution should not happen

    	this.startPeriodicalExecutor();
    	
    	// Navigation listener (article and previous/next links) if set
        if(this.navigation != null) {
        	// If navigation is added we must have listener to previous and next links
        	
        	// Listener for previous link
        	$$('a.rotation-previous-link').first()
                .observe('click', this.previousArticleListener.bindAsEventListener(this));
            
            // Listener for next link
            $$('a.rotation-next-link').first()
                .observe('click', this.nextArticleListener.bindAsEventListener(this));
         
            /*
             * Add the onhover for the mouse to pause the rolling.
             * Because of 3 overlying divs the event listener must be added to prev, next, naivigationbuttons and the pause icon)
             */
            
            /*
             * Add the event to all the rotation images
             */
            this.rotationArticle = this.element.select('div.rotation-article'); 
            //Event listener for the pictures, this needs start and stop
            if(this.rotationArticle != null){
            		this.rotationArticle.each(function(element){
            			element.observe('mouseenter',this.stopRotation.bindAsEventListener(this))
            			element.observe('mouseleave',this.startRotation.bindAsEventListener(this));
            		}.bind(this));
            }
            
            //event listener for the prev
            $$('span.previous').first()
        	.observe('mouseenter',this.stopRotation.bindAsEventListener(this));

            $$('span.previous').first()
        	.observe('mouseleave',this.startRotation.bindAsEventListener(this));
            
            //event listener for the next
            $$('span.next').first()
        	.observe('mouseenter',this.stopRotation.bindAsEventListener(this));

            $$('span.next').first()
        	.observe('mouseleave',this.startRotation.bindAsEventListener(this));

            
            //event listener for the navigationicons
            $$('div.navigation-menu').first()
        	.observe('mouseenter',this.stopRotation.bindAsEventListener(this));
            
            $$('div.navigation-menu').first()
        	.observe('mouseleave',this.startRotation.bindAsEventListener(this));
            
            //event listener for the pause icon
            $$('div.pause').first()
        	.observe('mouseenter',this.stopRotation.bindAsEventListener(this));            

            $$('div.pause').first()
        	.observe('mouseleave',this.startRotation.bindAsEventListener(this));            
            
            // Article links listener to each link if set
            if(this.articleLinks != null) {
            	this.articleLinks.each(function(element) {
                   element.observe('click', this.articleLinkListener.bindAsEventListener(this));
                }.bind(this));
            }
        }
    },
    
    /**
    *	Function used to mark active article link,and it's parent li, with a given css class.
    *	This is done based on the id for current article element.
    *
    *	If no article links should be display, the function does nothings and returns.
    * 
    */
    setActiveArticleLink: function() {
    	// Return if there are no article links
        if(typeof this.articleLinks == "undefined" || this.articleLinks == null) {
            return;
        }
        
        var currentArticleElementID = this.currentArticle.identify();
        
        var currentArticleUniqueID = currentArticleElementID.substring(currentArticleElementID.lastIndexOf('-') + 1);
        
        // Loop through article links to see if we find matching a link with matching id
        this.articleLinks.each(function(articleLink) {
        	var articleLinkElementID = articleLink.identify();
        	var uniqueArticleLinkID = articleLinkElementID.substring(articleLinkElementID.lastIndexOf('-') + 1);
           	
        	var parentLi = articleLink.up('li.list-link');
        	
        	// Set css class on active article link
        	if(currentArticleUniqueID == uniqueArticleLinkID){
        		articleLink.addClassName('active');
        		parentLi.addClassName('active');
        	}
        	// Remove active css class if article link not active
        	else if(articleLink.hasClassName('active')) {
        		articleLink.removeClassName('active');
        		
        		if(parentLi.hasClassName('active')) {
        		  parentLi.removeClassName('active');
        		}
        	}
        });
    },
    
    /**
    *	Function used to stop the periodical execution
    *	It's used if some of the click listeners triggers
    */
    stopPeriodicalExecutor: function() {
    	// stop periodical executer if it's defined
    	if(typeof this.pe != "undefined") {
            this.pe.stop();
        }
    	
    	//show the pause icon if there is an rotation:
    	if(this.interval > 0){
            $$('div.pause').first().setStyle({ display: 'block'});
    	}
    },
    
    /**
     *	Function used to start the periodical execution
     */ 
    startPeriodicalExecutor: function() {
    	//Allway hide the pause icon, even if there is no rotation
    	$$('div.pause').first().setStyle('display: none');
    	 
    	if(this.interval > 0){
        		this.pe = new PeriodicalExecuter(this.periodicalExecutor.bind(this), this.interval);
    	}
    },
    
    /**
     *	Function used to stop the rotation and shows the pause symbol
     *	It's used if the mouse hovers above the "mousevent" div
     */
     stopRotation: function(event) {
     	 Event.stop(event);
         this.stopPeriodicalExecutor();
     },    
     
     /**
      *	Function used to start the rotation and hide the pause symbol
     *	It's used if the mouse hovers above the "mousevent" div
      */
      startRotation: function(event) {
    	  
    	  Event.stop(event);
              this.startPeriodicalExecutor();
      },
    
    /**
    *	Function that get the next article to show and calls to the functions that displays an article element
    */
    nextArticle: function() {
    	var nextArticleElement = this.currentArticle.next();
    	// If we can't get the next article element, use the first in articles array
     	if(nextArticleElement == null || nextArticleElement.hasClassName('rotation-article') == false) {
    		nextArticleElement = this.articles.first();
    	}

    	this.changeRotationArticle(nextArticleElement);
    	
    },
    
    /**
    *	Function that get the previous article to show and calls to the functions that displays an article element
    */
    previousArticle: function() {
    	
    	var previousArticleElement = this.currentArticle.previous();
    	
    	if(previousArticleElement == null  || previousArticleElement.hasClassName('rotation-article') == false) {
    		previousArticleElement = this.articles.last();
    	}
    	
    	this.changeRotationArticle(previousArticleElement);
    },
    
    /**
    * Rotate to a given article element.
    *
    * This is done by fading from from element to the next one.
    *
    * @param toArticleElement - The article element that should be set visible
    */
    changeRotationArticle: function(toArticleElement) {
        
    	if (toArticleElement == this.currentArticle) return;
    	
        // Create effects for fading between the elements
        // We run this in parallel so that the from article (current article) can fade and disappear at the same
        // time that the next article is appearing and made visible
        
        new Effect.Parallel([
                             
                             // For now, current article is previous article (Current article is reset to the new visible article below)
                             // Make it disappear
                             new Effect.Fade(this.currentArticle, {sync: true}), 
                             // Make the new article appear
                             new Effect.Appear(toArticleElement, {sync: true}) 
                         ], { queue: { position: 'end', scope: 'rotatingbanner' , limit: 1}  });    	

        // Reset current article to be article that is set visible
        this.currentArticle = toArticleElement; 
        
        // Mark active article link
        this.setActiveArticleLink();
        
    },
    
    
    // ========================================================================
    // Event listeners
    
    /**
    * Listener used to switch to next article.
    * When using this, periodical executor is stopped.
    */
    nextArticleListener: function(event) {
        event.stop();

        // Periodical execution should be stopped
        this.stopPeriodicalExecutor();
        
        // Switch to next article
        this.nextArticle();
    }, 
    
    /**
    * Listener used to switch to previous article.
    * When using this, periodical executor is stopped.
    */
    previousArticleListener: function(event) {
        event.stop();
        
        // Periodical execution should be stopped
        this.stopPeriodicalExecutor();
        
        // Switch to previous article
        this.previousArticle();
    },
    
    /**
    * Listener used to switch to a specific article, determined by clicked article link.
    * When using this, periodical executor is stopped.
    */
    articleLinkListener: function(event) {
        event.stop();
        
        // Find the unique id to article element we want to show
        var clickedArticleLinkElementID = event.findElement('a').identify();
        
        // Get the div element that represents wanted article element
        var articleElementToShowID = clickedArticleLinkElementID.replace('nav-link-','rotation-article-');
        
        var articleElementToShow = $(articleElementToShowID);

        if(articleElementToShow != null) {
        	// Periodical execution should be stopped
        	this.stopPeriodicalExecutor();
        	this.changeRotationArticle(articleElementToShow);
        }
        
    },
    
    /**
    * Set next article to display
    */
    periodicalExecutor: function(pe) {
        this.nextArticle();
    }
  
});
