/*
   SiteComponents version:
   6.6.4.1, tag SC_6_6_4_1, created Tue Oct 27 21:28:23 +0100 2009
   $Name:  $
   
   Disclaimer
   
   While we make every effort to ensure that this code is fit for its intended
   purpose, we make no guarantees as to its functionality. CoreTrek AS will
   accept no responsibility for the loss of data or any other damage or
   financial loss caused by use of this code.
   
   Copyright
   
   This programming code is copyright of CoreTrek AS. Permission to run this
   code is given to approved users of CoreTrek's publishing system CorePublish.
   
   This source code may not be copied, modified or otherwise repurposed for use
   by a third party without the written permission of CoreTrek AS.
   
   Contact webmaster@coretrek.com for information.
  
*/

/*

    ============================================================================
    IMPORTANT! This javascript is dependent on Prototype. If Scriptaculous is
               available the tooltip will use some nice effects.
    ============================================================================

    SiteComponents slideshowtile.js

    Adds navigation to the slideshow tile.
    
*/

var SlideshowTile = Class.create({

    initialize: function(element) {
        this.element = $(element);
        
        this.current = 0;
        this.images = element.select('div.slideshow-image');
        
        this.navigation = this.element.select('.slideshow-navigation').first();
        
        if(typeof this.navigation != 'undefined') {
            this.thumbnailContainer = this.element.select('.slideshow-thumbnails').first();
            this.thumbnails = this.thumbnailContainer.childElements();
            this.navigation.show();
            this.setActiveThumb(this.images[this.current]);
        } else {
            this.navigation = null;
        }
        
        this.addListeners();
    },
    
    addListeners: function() {
        // If there is any navigation divs we add listeners to the navigation
        // buttons. If there are none, the tile is set do automatically
        // toggle images at a given interval.
        this.images.each(function(element) {
            element.down('img').observe('click', this.nextListener.bindAsEventListener(this));
        }.bind(this));
        
        if(this.navigation != null) {
            this.element.select('a.slideshow-previous').first()
	            .observe('click', this.previousListener.bindAsEventListener(this));
	        this.element.select('a.slideshow-next').first()
	            .observe('click', this.nextListener.bindAsEventListener(this));
	        
	        this.thumbnailContainer.show();
	        this.thumbnailContainer.select('a').each(function(element) {
	           element.observe('click', this.thumbnailListener.bindAsEventListener(this));
	        }.bind(this));
        } else {
            this.interval = this.element.select('div.slideshow-interval').first().innerHTML;
            
            new PeriodicalExecuter(this.periodicalExecutor.bind(this), this.interval);
        }
    },
    
    /**
     * Navigate to the next image
     */
    previous: function() {
        var previous = this.current;
        var next = this.current - 1;
        
        if(next < 0) {
           next = this.images.size() - 1;
        }
        
        this.fadeFromTo(previous, next);
    },
    
    /**
     * Navigate to the previous image
     */ 
	next: function() {
	    var previous = this.current;
	    var next = this.current + 1;
	    
	    if(next >= this.images.size()) {
	       next = 0;
	    }
	    
	    this.fadeFromTo(previous, next);
    },
    
    /**
     * Navigate to a given element id. The element must be an image container
     * element
     */
    showElementId: function(elementId) {
        var i = 0;
        this.images.each(function(image) {
            if(image.id == elementId) {
                throw $break;
            }
            i++;
        });
        
        var previous = this.current;
        var next = i;
        
        try {
            this.fadeFromTo(previous, next);
        } catch (err) {
            // An error will occur if the loop above did not find any matches..
            // Should not happen, but with IE6 you cannot be sure 
        }
    },
    
    setActiveThumb: function(to) {
        // return if there are no thumbnails (updating on interval)
        if(typeof this.thumbnails == "undefined") {
            return;
        }
       	
        var idKey = to.id.substring(to.id.lastIndexOf('-') + 1);
        
        this.thumbnails.each(function(thumb) {
            var href = thumb.down().readAttribute('href');
            var thumbIdKey = href.substring(href.lastIndexOf("#show_image_") + 12);
            
            if(thumb.hasClassName('active')) {
                thumb.removeClassName('active');
            } else if(idKey == thumbIdKey) {
                thumb.addClassName('active');
            }
        }.bind(this));
    },
    
    /**
     * Fade from a given image container to a new one. This method should only
     * be used inside this class. Use either next(), previous() or
     * showElementId() to toggle images.
     */
    fadeFromTo: function(from, to) {
        if(from == to) {
            return;
        }
        
        toImage = this.images[to];
        fromImage = this.images[from];
        
        // If another transition is in progress, cancel this before
        // invoking a new one
        var queuedEffects = Effect.Queues.get('slideshow');
        if(queuedEffects.effects.length > 0) {
            queuedEffects.each(function(eff) {
                eff.cancel();
                if(eff.element == this.images[this.current]) {
                    eff.element.setOpacity(1);
                    eff.element.show();
                } else {
                    eff.element.hide();
                    this.current = from;
                    this.images[from].show();
                    this.images[from].setOpacity(1);
                }
                
            }.bind(this));
        }
        
        this.setActiveThumb(toImage);
        
        try {
            var toDimensions = Element.getHiddenElementDimensions(toImage);
            
            new Effect.Opacity(fromImage, {
                to: 0.0,
                from: 1.0,
                duration: 0.3,
                queue: {
                    scope: 'slideshow'
                },
                afterFinish: function() {
                    this.eff = new Effect.Morph(fromImage, {
                        duration: .1,
                        style: {
                            height: toDimensions.height + 'px'
                        },
                        queue: {
                            scope: 'slideshow'
                        },
                        afterFinish: function() {
                            this.eff = new Effect.Appear(toImage, {
                                duration: .3,
                                queue: {
                                    scope: 'slideshow'
                                },
                                afterUpdate: function(effect) {
                                    if(effect.currentFrame == 0) {
                                        fromImage.hide();
                                        fromImage.setOpacity(1.0);
                                        fromImage.setStyle({ height: 'auto' });
                                        
                                        // Lets check if the image has been
                                        // enhanced, if it has we need to
                                        // reinitialize the elements
                                        try {
                                            var ratings = toImage.select("div.rating-container");
                                            if(ratings.size() > 0) {
                                                ratings.each(function(element) {
                                                    if(typeof element.enhancer == 'object') {
                                                        element.enhancer.reinitializeElements();
                                                    }
                                                });
                                            }
                                        } catch (err) {
                                            // Something went wrong trying to
                                            // reinitialize the element
                                        }
                                        
                                    }
                                }.bind(this)
                            });
                        }
                    });

                }.bind(this)
            });
            
	    } catch (e) {
	        // No scriptaculous - hide/show without effect
	        fromImage.hide();
	        toImage.show();   
	    }
	    
	    this.current = to;
	},
	
	// ========================================================================
    // Event listeners
	
	nextListener: function(event) {
        event.stop();
        
        this.next();
	}, 
	
	previousListener: function(event) {
        event.stop();
        
        this.previous();
    },
    
    thumbnailListener: function(event) {
        event.stop();
        
        var href = event.findElement('a').readAttribute('href');
        var imageContainerId = 'image-' + this.element.id + '-' + href.substring(href.lastIndexOf("#show_image") + 12);
        
        this.showElementId(imageContainerId);
    },
    
    periodicalExecutor: function(pe) {
        this.next();
    }

});

