var SwapImage = new Class({

    /**
    * Public function initialize
    * Constructor. Sets up each swapimage on the page. Each swapimage wrapper
    * element must have the class 'swapimage' and contain one or more elements
    * with classes 'swapimage-thumb' and only one element with the class
    * 'swapimage-canvas'
    */
    initialize: function() {
        
        $$('.swapimage').each(function(swapimage) {
        
            var canvas = swapimage.getElement('.swapimage-canvas');
            
            // Create and cache a spinner for this canvas
            canvas.spinner = new Element('img', {'src': '/images/big-loader.gif',
                                               'class': 'swapimage-spinner'});

            $$('.swapimage-link').each(function(thumb) {
            
                /*if(thumb.hasClass('hidden')) {
                
                    swapimage.hiddenThumb = thumb;
                    thumb.exhibit = canvas.getElement('.swapimage-exhibit');
                    thumb.exhibit.set('tween', {link: 'cancel', duration: 'normal'});
                }*/ // don't need this as this is for the gallery
            
                var href = thumb.getProperty('href');
                thumb.meta = href.substring(href.indexOf('?') + 1).parseQueryString();
            
                // Add fx options
                thumb.set('tween', {link: 'cancel', duration: 'short'});

                // Add mouseover/out events
                thumb.addEvent('mouseover', this.linkMouseOverHandler);
                thumb.addEvent('mouseout', this.linkMouseOutHandler);
                
                // Add mouseclick event
                thumb.addEvent('click', this.linkMouseClickHandler.bindWithEvent(this, [thumb, canvas, swapimage]));
            
            }, this);

        }, this);
    },
    
    /**
    * Private function thumbMouseOverHandler
    * Fades a swapimage-thumb to 50% opacity onmouseover
    *
    * @param evt Event Mootools event object
    */
    linkMouseOverHandler: function(evt) {

        $$(evt.target).fade(0.5);
    },
    
    /**
    * Private function thumbMouseOutHandler
    * Fades a swapimage-thumb to 100% opacity onmouseout
    *
    * @param evt Event Mootools event object
    */
    linkMouseOutHandler: function(evt) {
    
        $$(evt.target).fade(1);
    },
    
    /**
    * Private function thumbMouseClickHandler
    * Shows a loaded image in the swapimage-canvas or initiates a preload of an
    * image whilst immediately showing a loading spinner.
    *
    * @param evt Event Mootools event object
    * @param thumb HTMLELement The thumbnail that was clicked
    * @param canvas HTMLElement The swapimage canvas to show the image in
    */
    linkMouseClickHandler: function(evt, thumb, canvas, swapimage) {
    
        // Invalidate the current loading exhibit
        canvas.currentExhibit = null;
    
        // Make thumb that was clicked on hidden
        
		/*thumb.addClass('hidden');
        swapimage.hiddenThumb.replaces(thumb);
        swapimage.hiddenThumb.removeClass('hidden');
        swapimage.hiddenThumb = thumb;
    */
        // Remove current exhibit
        //canvas.empty();

        // Has a preloaded exhibit element been cached?
        if(thumb.exhibit) {

            // Ensure current exhibit is hidden before it is injected
            //thumb.exhibit.fade('hide');
        
            // Inject this exhibit replacing either another exhibit or a spinner
            thumb.exhibit.replaces(canvas.getFirst());
            
            thumb.exhibit.fade('in');
            
        } else {
        
            // Add loading spinner
            canvas.spinner.replaces(canvas.getFirst());
            
            switch(thumb.meta.type) {
            
                default:
                case 'image':
                
                    canvas.currentExhibit = new Element('img', {'src': '/img/' + thumb.meta.src,
                                                                'alt': thumb.meta.title});
                break;
                case 'xhtml':
                
                    canvas.currentExhibit = new Element('div');
                
                    // Load this HTML content into the canvas
                    canvas.currentExhibit.load('/xhtml/' + thumb.meta.src);
                
                break;
            }
            
            canvas.currentExhibit.set('tween', {link: 'cancel', duration: 'normal'});
            
            this.imageIsLoaded.delay(1000, this, [canvas.currentExhibit, thumb, canvas]);
        }
        
        // Stop the anchor href being navigated to!
        evt.preventDefault();
    },
    
    /**
    * Private function imageIsLoaded
    * Periodically checks if an exhibit has been loaded and injects the exhibit 
    * into the canvas if it has.
    *
    * @param evt Event Mootools event object
    * @param image HTMLElement The exhibit being preloaded
    * @param thumb HTMLELement The thumbnail that was clicked
    * @param canvas HTMLElement The swapimage canvas to show the image in
    */
    imageIsLoaded: function(exhibit, thumb, canvas) {
    
        var isLoaded = false;

        // Determine if the content has been preloaded
        switch(thumb.meta.type) {
            
            default:
            case 'image':
            
                if(exhibit.complete) {
                
                    isLoaded = true;
                }

            break;
            case 'xhtml':
            
                if(exhibit.getChildren().length) {
                
                    isLoaded = true;
                }
            
            break;
        }
    
        // Inject if is loaded
        if(isLoaded == true) {
        
            // Cache
            thumb.exhibit = exhibit;
            
            // Check the exhibit we've loaded is in fact the exhibit we currently want to see
            if(canvas.currentExhibit == exhibit) {
            
                canvas.currentExhibit = null;
                
                // Ensure current exhibit is hidden before it is injected
                exhibit.fade('hide');
                
                // Insert into the canvas, replacing the spinner
                exhibit.replaces(canvas.getFirst());
                
                exhibit.fade('in');
            }

        } else {
        
            // Check again soon
            this.imageIsLoaded.delay(1000, this, [exhibit, thumb, canvas]);
        }
    }
});
