/*
 * Yet Another Media Gallery v1.0.1 - Jordy Boezaard - http://www.bitterzoetmedia.nl/
 *
 * Displays a full screen media gallery (with iOS support)
 *
 * TERMS OF USE
 * 
 * Open source under the BSD License. 
 * 
 * Copyright © 2011 Jordy Boezaard
 * All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without modification, 
 * are permitted provided that the following conditions are met:
 * 
 * Redistributions of source code must retain the above copyright notice, this list of 
 * conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright notice, this list 
 * of conditions and the following disclaimer in the documentation and/or other materials 
 * provided with the distribution.
 * 
 * Neither the name of the author nor the names of contributors may be used to endorse 
 * or promote products derived from this software without specific prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 *  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
 *  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 *  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 
 * OF THE POSSIBILITY OF SUCH DAMAGE. 
 *
*/
(function($)
{
    var MediaItem = function()
    {
        this.Title = null;
        this.Url = null;
        this.Width = null;
        this.Height = null;
        this.ThumbnailUrl = null;
        this.CacheStatus = CacheStatus.NotCached;
        this.IsYouTube = false;
    }
    
    var MediaSet = function()
    {
        this.title = null;
        this.description = null;
        this.mediaItemArray = new Array();
        this.currentlyDisplayedItem = -1;
    };
    
    var EventData = function()
    {
        this.instanceData = null;
        this.data = null;
    }
    
    var ZoomModes = 
    {
        FullScreen:     'FULL_SCREEN',
        FitOnScreen:    'FIT_ON_SCREEN'
    }
    
    var CacheStatus = 
    {
    	NotCached:		'NOT_CACHED',
    	Caching:		'CACHING',
    	Cached:			'CACHED'
    }
    
    var methods =
    {
        init:                               function(options)
                                            {
                                                return this.each(function()
                                                {
                                                    var $this = $(this);
                                                    var data = $this.data('yamg');

                                                    // If the plugin hasn't been initialized yet
                                                    if (!data)
                                                    {
														// Create data object
                                                        $(this).data('yamg', {
                                                            // Properties
                                                            target:                             $this,
                                                            mediaSets:                          new Array(),
                                                            yamgContainer:                      null,
                                                            hudInactivityTimeout:               null,
                                                            activeMediaSet:                     null,
                                                            mediaSetTabActivated:               true,
                                                            currentlyScrolledToThumbnail:       -1,
                                                            currentZoomMode:                    ZoomModes.FitOnScreen,
                                                            
                                                            // image location
                                                            yamgImageFolder:                    '/workspace/img/yamg/',
                                                            
                                                            // iOS
                                                            iOsStartTouchPosition:				null,
                                                            iOsCurrentTouchPosition:			null,
                                                            iOsMoveThreshold:					100,
                                                            iOsGestureTouchEndTimeout:			1000,
                                                            iOsLastGestureTime:					false,
                                                            iOsNumberOfFingersExitGesture:		3,
                                                            
                                                            // Margins
                                                            mediaStripThumbnailRightMargin:     5,
                                                            mediaStripNavigationWidth:          20,
                                                            
                                                            // Captions
                                                            controlZoomCaption:                 'Verander zoom mode',
                                                            controlExitCaption:                 'Sluiten',
                                                            mediaStripTabActiveCaption:         'Verbergen',
                                                            mediaStripTabInactiveCaption:       'Toon alle media',
                                                            
                                                            // Opacity
                                                            hudOpacity:                         .7,
                                                            mediaStripOpacity:                  .7,
                                                            mediaStripThumbnailOpacity:         .6,
                                                            
                                                            // Durations
                                                            fadeInYAMGDuration:                 500,
                                                            fadeOutYAMGDuration:                1500,
                                                            fadeInItemNavDuration:              500,
                                                            fadeOutItemNavDuration:             500,
                                                            fadeInLoadingDuration:              500,
                                                            fadeOutLoadingDuration:             500,
                                                            fadeInMediaItemDuration:            500,
                                                            fadeOutMediaItemDuration:           500,
                                                            fadeInHudDuration:                  500,
                                                            fadeOutHudDuration:                 1000,
                                                            fadeInMediaStripTabDuration:        0,
                                                            fadeOutMediaStripTabDuration:       1000,
                                                            fadeInMediaStripNavDuration:        500,
                                                            fadeOutMediaStripNavDuration:       1000,
                                                            slideUpMediaStripTabDuration:       1000,
                                                            slideDownMediaStripTabDuration:     500,
                                                            slideMediaStripThumbnailDuration:   300,
                                                            
                                                            // Easings
                                                            slideUpMediaStripTabEasing:         'easeOutBounce',
                                                            slideDownMediaStripTabEasing:       'easeOutBounce',
                                                            slideMediaStripThumbnailsEasing:    'easeOutQuad',
                                                            fadeOutGalleryEasing:               'easeOutQuad',
                                                            
                                                            // Durations
                                                            hudInactivityFadeOutTimeout:        4000,
                                                            cachedImageRecheckDuration:         100,
                                                        });
                                                    }
                                                    
                                                    methods.createMediaSets.apply(this);
                                                });
                                            },
                            
        createMediaSets:                    function()
                                            {
                                                // Get the instance of yamg
                                                var $this = $(this);
                                                var data = $this.data('yamg');
                                                
                                                var listChildren = $this.children();

                                                var eventData = null;
                                                
                                                $.each(listChildren, function()
                                                {
                                                    var tagName = this.tagName.toLowerCase();
                                                    
                                                    if (tagName == 'dt')
                                                    {
                                                        // Create new mediaset
                                                        var mediaSet = new MediaSet();
                                                        mediaSet.title = $(this).html();
                                                        
                                                        data.mediaSets.push(mediaSet);
                                                        
                                                        // Update event data
                                                        eventData = new EventData();
                                                        eventData.instanceData = data;
                                                        eventData.data = mediaSet;
                                                        
                                                        // Click event
                                                        $(this).bind('click.yamg', eventData, eventHandlers.mediaSetThumbnailClicked);
                                                    }
                                                    else if (tagName == 'dd')
                                                    {
                                                        var mediaSet = data.mediaSets[data.mediaSets.length - 1];
                                                        
                                                        // Update event data
                                                        eventData.instanceData = data;
                                                        eventData.data = mediaSet;
                                                        
                                                        if ($(this).hasClass('description') == true)
                                                        {
                                                            // Update media set
                                                            mediaSet.description = $(this).html();
                                                        }
                                                        else if ($(this).hasClass('mediaList') == true)
                                                        {
                                                            // Update media set
                                                            var listItems = $(this).children('ol').children('li');
                                                            
                                                            $.each(listItems, function ()
                                                            {
                                                                // New Media Item
                                                                var mediaItem = new MediaItem();
                                                            
                                                                // Get links
                                                                var links = $(this).children('a');
                                                                
                                                                $.each(links, function(){
                                                                    
                                                                    var rel = $(this).attr('rel').toLowerCase();
                                                                    
                                                                    if (rel == "mediaitem")
                                                                    {
                                                                        mediaItem.Title = $(this).text();
                                                                        mediaItem.Url = $(this).attr('href');
                                                                        mediaItem.Width = $(this).attr('width');
                                                                        mediaItem.Height = $(this).attr('height');
                                                                        mediaItem.IsYouTube = false;
                                                                    }
                                                                    else if (rel == "mediaitemyoutube")
                                                                    {
                                                                        mediaItem.Title = $(this).text();
                                                                        mediaItem.Url = $(this).attr('href');
                                                                        mediaItem.Width = 0;
                                                                        mediaItem.Height = 0;
                                                                        mediaItem.IsYouTube = true;
                                                                    }
                                                                    else if (rel == "mediaitemthumbnail")
                                                                    {
                                                                        mediaItem.ThumbnailUrl = $(this).attr('href');
                                                                    }
                                                                });
                                                                
                                                                // Check if both the picture and thumbnail are defined
                                                                if (mediaItem.Url != null && mediaItem.ThumbnailUrl != null)
                                                                {
                                                                    mediaSet.mediaItemArray.push(mediaItem);
                                                                }
                                                            });
                                                        }
                                                        else if ($(this).hasClass('thumbnail') == true)
                                                        {
                                                            // Click event
                                                            $(this).children('img').bind('click.yamg', eventData, eventHandlers.mediaSetThumbnailClicked);
                                                        }
                                                    }
                                                });
                                                
                                                return this;
                                            },
                                            
        displayGallery:                     function()
                                            {
                                                // Get the instance of yamg
                                                var $this = $(this);
                                                var data = $this.data('yamg');
                                                
                                                // Get current media set
                                                var mediaSet = data.activeMediaSet;
                                                
                                                // Create galleryContainer
                                                data.yamgContainer = $('<div/>', {
                                                                        'class':     'yamgContainer',
                                                                        css:    {
                                                                                    opacity: 0
                                                                                }
                                                                    })
                                                                    .append(
                                                                        $('<div/>', {
                                                                            'class':      'yamgStage'
                                                                        })
                                                                        .append(
                                                                            $('<div/>', {
                                                                                'class':      'yamgMediaItemContainer'
                                                                            })
                                                                            .append(
                                                                                $('<div/>', {
                                                                                    'class':      'yamgMediaItem',
                                                                                    css:        {
                                                                                                    opacity: 0
                                                                                                }
                                                                                })
                                                                            )
                                                                        )
                                                                        .append(
                                                                            $('<div/>', {
                                                                                'class':      'yamgMediaItemLoading',
                                                                                css:    {
                                                                                    opacity: 0
                                                                                }
                                                                            })
                                                                        )
                                                                        .append(
                                                                            $('<div/>', {
                                                                                'class':      'yamgMediaItemNavigation'
                                                                            })
                                                                            .append(
                                                                                $('<div/>', {
                                                                                    'class':      'yamgMediaItemNavigationLeft',
                                                                                    css:    {
                                                                                        opacity: 0
                                                                                    }
                                                                                })
                                                                            )
                                                                            .append(
                                                                                $('<div/>', {
                                                                                    'class':      'yamgMediaItemNavigationRight',
                                                                                    css:    {
                                                                                        opacity: 0
                                                                                    }
                                                                                })
                                                                            )
                                                                        )
                                                                    )
                                                                    .append(
                                                                        $('<div/>', {
                                                                            'class':      'yamgDescription yamgHud',
                                                                            css:        {
                                                                                            opacity: data.hudOpacity
                                                                                        },
                                                                            html:       '<h1>' + mediaSet.title + '</h1><p>' + mediaSet.description + '</p>'
                                                                        })
                                                                    )
                                                                    .append(
                                                                        $('<div/>', {
                                                                            'class':      'yamgControls yamgHud',
                                                                            css:        {
                                                                                            opacity: data.hudOpacity
                                                                                        }
                                                                        })
                                                                        .append(
                                                                            $('<img/>', {
                                                                                'class':  'yamgZoomControl',
                                                                                src:    data.yamgImageFolder + 'controlZoom.gif',
                                                                                title:  data.controlZoomCaption
                                                                            })
                                                                        )
                                                                        .append(
                                                                            $('<img/>', {
                                                                                'class':  'yamgExitControl',
                                                                                src:    data.yamgImageFolder + 'controlExit.gif',
                                                                                title:  data.controlExitCaption
                                                                            })
                                                                        )
                                                                    )
                                                                    .append(
                                                                        $('<div/>', {
                                                                            'class':      'yamgMediaStrip yamgHud',
                                                                            css:        {
                                                                                            opacity: data.mediaStripOpacity,
                                                                                            bottom: 0
                                                                                        }
                                                                        })
                                                                        .append(
                                                                            $('<div/>', {
                                                                                'class':      'yamgMediaStripTab',
                                                                                text:       data.mediaStripTabActiveCaption,
                                                                                css:        {
                                                                                                opacity: data.mediaStripTabOpacity,
                                                                                            }
                                                                            })
                                                                        )
                                                                        .append(
                                                                            $('<div/>', {
                                                                                'class':      'yamgMediaStripThumbnails'
                                                                            })
                                                                        )
                                                                        .append(
                                                                            $('<div/>', {
                                                                                'class':      'yamgMediaStripNavigation yamgMediaStripNavigationLeft',
                                                                                css:        {
                                                                                                opacity: 0
                                                                                            }
                                                                            })
                                                                        )
                                                                        .append(
                                                                            $('<div/>', {
                                                                                'class':      'yamgMediaStripNavigation yamgMediaStripNavigationRight',
                                                                                css:        {
                                                                                                opacity: 0
                                                                                            }
                                                                            })
                                                                        )
                                                                    )
                                                                    .appendTo('body');
        
                                                
                                                // Calculate Yamg Container Size
                                                methods.calculateYamgContainerSize.apply(this);
                                                
                                                // Create thumbnails
                                                $.each(mediaSet.mediaItemArray, function(index ){
                                                    $('<div/>', {
                                                        'class':    'yamgMediaStripThumbnail'
                                                    })
                                                    .append(
                                                        $('<img/>', {
                                                            src:    $(this)[0].ThumbnailUrl,
                                                            title:  $(this)[0].Title,
                                                            click:  function()
                                                                    {
                                                                        methods.gotoMediaItem.apply($this, [index ]);
                                                                    },
                                                            load:	function()
		                                                            {
		                                                            	methods.updateMediaStripThumbnails.apply($this);
		                                                            }
                                                        })
                                                    )
                                                    .appendTo('div.yamgMediaStripThumbnails');
                                                });                                                
                                                
                                                
                                                // Set event handlers
                                                data.yamgContainer.find('.yamgMediaItemNavigationLeft').bind('mouseenter.yamg', { duration: data.fadeInItemNavDuration, targetOpacity : 1 }, eventHandlers.fadeItemMouseEnterLeave);
                                                data.yamgContainer.find('.yamgMediaItemNavigationLeft').bind('mouseleave.yamg', { duration: data.fadeOutItemNavDuration, targetOpacity : 0 }, eventHandlers.fadeItemMouseEnterLeave);
                                                data.yamgContainer.find('.yamgMediaItemNavigationRight').bind('mouseenter.yamg', { duration: data.fadeInItemNavDuration, targetOpacity : 1 }, eventHandlers.fadeItemMouseEnterLeave);
                                                data.yamgContainer.find('.yamgMediaItemNavigationRight').bind('mouseleave.yamg', { duration: data.fadeOutItemNavDuration, targetOpacity : 0 }, eventHandlers.fadeItemMouseEnterLeave);
                                                
                                                data.yamgContainer.find('.yamgMediaItemNavigationLeft').bind('click.yamg', data, eventHandlers.mediaItemNavPreviousClick);
                                                data.yamgContainer.find('.yamgMediaItemNavigationRight').bind('click.yamg', data, eventHandlers.mediaItemNavNextClick);
                                                
                                                data.yamgContainer.bind('mousemove.yamg', data, eventHandlers.yamgContainerMouseMove);
                                                data.yamgContainer.bind('mouseleave.yamg', data, eventHandlers.yamgContainerMouseLeave);
                                                
                                                data.yamgContainer.find('.yamgMediaStripTab').bind('mouseenter.yamg', { duration: data.fadeInMediaStripTabDuration, targetOpacity : 1 }, eventHandlers.fadeItemMouseEnterLeave);
                                                data.yamgContainer.find('.yamgMediaStripTab').bind('mouseleave.yamg', { duration: data.fadeOutMediaStripTabDuration, targetOpacity : data.mediaStripTabOpacity }, eventHandlers.fadeItemMouseEnterLeave);
                                                data.yamgContainer.find('.yamgMediaStripTab').bind('click.yamg', data, eventHandlers.mediaStripTabClick);
                                                
                                                data.yamgContainer.find('.yamgZoomControl').bind('click.yamg', data, eventHandlers.controlZoomClick);
                                                data.yamgContainer.find('.yamgExitControl').bind('click.yamg', data, eventHandlers.controlExitClick);
                                                
                                                
                                                var mediaStripNavLeftEventData = new EventData();
                                                mediaStripNavLeftEventData.data = { direction: 'left' };
                                                mediaStripNavLeftEventData.instanceData = data;
                                                
                                                var mediaStripNavRightEventData = new EventData();
                                                mediaStripNavRightEventData.data = { direction: 'right' };
                                                mediaStripNavRightEventData.instanceData = data;
                                                
                                                data.yamgContainer.find('.yamgMediaStripNavigationLeft').bind('click.yamg', mediaStripNavLeftEventData, eventHandlers.mediaStripNavigationClick);
                                                data.yamgContainer.find('.yamgMediaStripNavigationRight').bind('click.yamg', mediaStripNavRightEventData, eventHandlers.mediaStripNavigationClick);
                                                
                                                $(window).bind('resize.yamg', data, eventHandlers.windowResize);
                                                $(window).bind('keyup.yamg', data, eventHandlers.windowKeyUp);
                                                
                                                // iOS events
                                                data.yamgContainer.bind('touchstart', data, eventHandlers.yamgContainerTouchStart);
                                                data.yamgContainer.bind('touchmove', data, eventHandlers.yamgContainerTouchMove);
                                                data.yamgContainer.bind('touchend', data, eventHandlers.yamgContainerTouchEnd);                                                
                                                
                                                data.yamgContainer.bind('gesturechange', data, eventHandlers.yamgContainerOnGestureChange);
                                                data.yamgContainer.bind('gestureend', data, eventHandlers.yamgContainerOnGestureEnd);

                                                // Fade in gallery
                                                data.yamgContainer.fadeTo(data.fadeInYAMGDuration, 1, function(){
                                                	// Go to the first media item
                                                	methods.gotoMediaItem.apply($this, [0]);
                                                });

												// Set html and body to fullscreen
												$('body').addClass('yamgFullScreen');
												$('html').addClass('yamgFullScreen');
                                                	
                                                // Toggle media strip navigation
                                                methods.toggleMediaStripNavigation.apply(this);
                                                
												// Reposition controls
												methods.positionControls.apply($this);

                                                return this;
                                            },
                                            
		calculateYamgContainerSize:			function()
											{
                                                // Get the instance of yamg
                                                var $this = $(this);
                                                var data = $this.data('yamg');
                                                
												// Size container
										        data.yamgContainer.height($(window).height());
											
												return this;
											},

		preloadMediaItem:					function (mediaItemIndex)
											{
                                                // Get the instance of yamg
                                                var $this = $(this);
                                                var data = $this.data('yamg');
												
                                                // Get current media set
                                                var mediaSet = data.activeMediaSet;
                                                
                                                // Get media item data
                                                var mediaItemData = mediaSet.mediaItemArray[mediaItemIndex];

												// Set cache status
                                                mediaItemData.CacheStatus = CacheStatus.Caching;
                                                
                                                // Cache
                                                switch (mediaItemData.Url.substr(-3))
                                                {
                                                    case 'jpg':
                                                    case 'gif':
                                                    case 'png':
														var pic = new Image();
														pic.onload = 	function ()
																		{
																			mediaItemData.CacheStatus = CacheStatus.Cached;
																		};
														pic.src = mediaItemData.Url;
														
														break;
												}
												
												return this;
											},

        gotoMediaItem:                      function(mediaItemIndex)
                                            {
                                                // Get the instance of yamg
                                                var $this = $(this);
                                                var data = $this.data('yamg');
                                                
                                                // Get current media set
                                                var mediaSet = data.activeMediaSet;
                                                
                                                // Skip loading for youtube items
                                                if (mediaSet.mediaItemArray[mediaItemIndex].IsYouTube == false)
                                                {
                                                    // Show loading if not cached
                                                    if (mediaSet.mediaItemArray[mediaItemIndex].CacheStatus != CacheStatus.Cached)
                                                    {
	                                                    if (mediaSet.mediaItemArray[mediaItemIndex].CacheStatus == CacheStatus.NotCached)
	                                                    {
	                                                        // Show load indicator
	                                                        data.yamgContainer.find('.yamgMediaItemLoading').fadeTo(data.fadeInLoadingDuration, 1);
	                                                        
	                                                        // Cache image
	                                                        methods.preloadMediaItem.apply(this, [mediaItemIndex]);
                                                        }
                                                        
                                                        // Set timeout
                                                        setTimeout(function()
                                                        {
                                                    	    methods.gotoMediaItem.apply($this, [mediaItemIndex])
                                                        }, data.cachedImageRecheckDuration);
                                                        
                                                        return;
                                                    }
                                                }
                                                
                                                // Hide load indicator if shown
                                                if (data.yamgContainer.find('.yamgMediaItemLoading').css('opacity') > 0)
                                                {
                                                	data.yamgContainer.find('.yamgMediaItemLoading').fadeTo(data.fadeOutLoadingDuration, 0);
                                                }
                                                
                                                // Set currently shown item
                                                mediaSet.currentlyDisplayedItem = mediaItemIndex;
                                                
                                                // Get container media item
                                                var mediaItemDiv = data.yamgContainer.find('.yamgMediaItem');

                                                // Fade out current
                                                if (mediaItemDiv.children().length > 0)
                                                {
                                                    methods.fadeOutMediaItem.apply(this);
                                                }
                                                else
                                                {
                                                    methods.fadeInMediaItem.apply(this);
                                                }
                                                
                                                return this;
                                            },
        
        fadeOutMediaItem:                   function()
                                            {
                                                // Get the instance of yamg
                                                var $this = $(this);
                                                var data = $this.data('yamg');
                                                
                                                // Get container media item
                                                var mediaItemDiv = data.yamgContainer.find('.yamgMediaItem');

                                                mediaItemDiv.fadeTo(data.fadeOutMediaItemDuration, 0, function()
                                                {
                                                    methods.fadeInMediaItem.apply(data.target);
                                                });
                                                
                                                return this;
                                            },
                                            
        fadeInMediaItem:                    function()
                                            {
                                                // Get the instance of yamg
                                                var $this = $(this);
                                                var data = $this.data('yamg');
                                                
                                                // Get active media set
                                                var mediaSet = data.activeMediaSet;
                                                
                                                // Get container media item
                                                var mediaItemDiv = data.yamgContainer.find('.yamgMediaItem');
                                                
                                                // Clear div
                                                mediaItemDiv.html('');
                                                
                                                // Set new media item
                                                var mediaItemData = mediaSet.mediaItemArray[mediaSet.currentlyDisplayedItem];
                                                
                                                var mediaItem = null;
                                                
                                                if (mediaItemData.IsYouTube == true)
                                                {
                                                    // Create youtube iFrame
                                                    mediaItem = $('<iframe/>', {
                                                        src:                mediaItemData.Url,
                                                        css:                {
                                                                            position:   'relative',
                                                                            top:        -10,
                                                                            left:       -300
                                                                            /*,
                                                                            height:     390,
                                                                            width:      640*/
                                                                        },
                                                        frameborder:    '0',
                                                        title:          mediaItemData.Title
                                                    });
                                                }
                                                else
                                                {
                                                    // Create image node
                                                    switch (mediaItemData.Url.substr(-3))
                                                    {
                                                        case 'jpg':
                                                        case 'gif':
                                                        case 'png':
                                                            mediaItem = $('<img/>', {
                                                                src:    mediaItemData.Url,
                                                                css:    {
                                                                            position:   'relative',
                                                                            top:        -10,
                                                                            left:       -300,
                                                                            height:     mediaItemData.Height,
                                                                            width:      mediaItemData.Width
                                                                        },
                                                                title:  mediaItemData.Title
                                                            });
                                                        
                                                            break;
                                                    }
                                                }
                                                
                                                mediaItemDiv.append(mediaItem);
                                                
                                                // Calculate and set item dimensions
                                                methods.setMediaItemSizeAndOffset.apply(this);
                                                
                                                // Fade in new
                                                mediaItemDiv.fadeTo(data.fadeInMediaItemDuration, 1);
                                                
                                                // Highlight thumbnail
                                                methods.highlightMediaStripThumbnail.apply(this, [mediaSet.currentlyDisplayedItem]);
                                                
                                                // Scroll media strip
                                                methods.mediaStripScrollToThumbnail.apply(this, [mediaSet.currentlyDisplayedItem]);
                                                
                                                                
                                                return this;
                                            },
                                            
        setMediaItemSizeAndOffset:          function()
                                            {
                                                // Get the instance of yamg
                                                var $this = $(this);
                                                var data = $this.data('yamg');
                                                
                                                // Get media item
                                                var mediaItem = data.yamgContainer.find('div.yamgMediaItem').children();
                                                
                                                // Get dimensions
                                                var containerWidth = data.yamgContainer.width();
                                                var containerHeight = data.yamgContainer.height();
                                                
                                                var itemWidth = mediaItem.width();
                                                var itemHeight = mediaItem.height();
                                                
                                                var ratioWidth = containerWidth / itemWidth;
                                                var ratioHeight = containerHeight / itemHeight;
                                                
                                                var newItemDimPos = { width: 0, height: 0, left: 0, top: 0 };
                                                
                                                if (data.currentZoomMode == ZoomModes.FullScreen)
                                                {
                                                    // Calculate new position and media item dimensions
                                                    if (ratioWidth == 1 && ratioHeight == 1)
                                                    {
                                                        // Use real size
                                                        newItemDimPos.width = itemWidth;
                                                        newItemDimPos.height = itemHeight;
                                                    }
                                                    else if (ratioWidth > 1
                                                            || ratioHeight > 1)
                                                    {
                                                        // At least one dimension needs zoom
                                                        if (ratioWidth > ratioHeight)
                                                        {
                                                            newItemDimPos.width = itemWidth * ratioWidth;
                                                            newItemDimPos.height = itemHeight * ratioWidth;
                                                            
                                                            newItemDimPos.top = Math.round((newItemDimPos.height - containerHeight) / 2) * -1;
                                                        }
                                                        else
                                                        {
                                                            newItemDimPos.width = itemWidth * ratioHeight;
                                                            newItemDimPos.height = itemHeight * ratioHeight;
                                                            
                                                            newItemDimPos.left = Math.round((newItemDimPos.width - containerWidth) / 2) * -1;
                                                        }
                                                    }
                                                    else
                                                    {
                                                        if (ratioWidth > ratioHeight)
                                                        {
                                                            newItemDimPos.width = itemWidth * ratioWidth;
                                                            newItemDimPos.height = itemHeight * ratioWidth;
                                                            
                                                            newItemDimPos.top = Math.round((newItemDimPos.height - containerHeight) / 2) * -1;
                                                        }
                                                        else
                                                        {
                                                            newItemDimPos.width = itemWidth * ratioHeight;
                                                            newItemDimPos.height = itemHeight * ratioHeight;
                                                            
                                                            newItemDimPos.left = Math.round((newItemDimPos.width - containerWidth) / 2) * -1;
                                                        }
                                                    }
                                                }
                                                else if (data.currentZoomMode == ZoomModes.FitOnScreen)
                                                {
                                                    if (ratioWidth <= ratioHeight)
                                                    {
                                                        newItemDimPos.width = itemWidth * ratioWidth;
                                                        newItemDimPos.height = itemHeight * ratioWidth;
                                                            
                                                        newItemDimPos.top = Math.round((containerHeight - newItemDimPos.height) / 2);
                                                    }
                                                    else if (ratioWidth > ratioHeight)
                                                    {
                                                        newItemDimPos.width = itemWidth * ratioHeight;
                                                        newItemDimPos.height = itemHeight * ratioHeight;
                                                        
                                                        newItemDimPos.left = Math.round((containerWidth - newItemDimPos.width) / 2);
                                                    }
                                                }
                                                
                                                // Set new position and dimensions
                                                mediaItem.css({
                                                    width:  newItemDimPos.width,
                                                    height: newItemDimPos.height,
                                                    top:    newItemDimPos.top,
                                                    left:   newItemDimPos.left
                                                });
                                                
                                                return this;
                                            },
                                            
        showHud:                            function()
                                            {
                                                // Get the instance of yamg
                                                var $this = $(this);
                                                var data = $this.data('yamg');
                                                
                                                // Media Strip
                                                var huds = data.yamgContainer.find('div.yamgHud');
                                                
                                                huds    .stop()
                                                        .clearQueue()
                                                        .fadeTo(data.fadeInHudDuration, data.hudOpacity);

                                                return this;
                                            },
                                            
        hideHud:                            function()
                                            {
                                                // Get the instance of yamg
                                                var $this = $(this);
                                                var data = $this.data('yamg');
                                                
                                                var huds = data.yamgContainer.find('div.yamgHud');
                                                
                                                huds    .stop()
                                                        .clearQueue()
                                                        .fadeTo(data.fadeOutHudDuration, 0);
                                                        
                                                return this;
                                            },
                                            
        toggleMediaStrip:                   function(forceActivationStatus)
                                            {
                                                // Get the instance of yamg
                                                var $this = $(this);
                                                var data = $this.data('yamg');
                                                
                                                var mediaStrip = data.yamgContainer.find('div.yamgMediaStrip');
                                                var mediaStripTab = data.yamgContainer.find('div.yamgMediaStripTab');
                                                
                                                // Forced status?
                                                var targetActivationStatus = (forceActivationStatus != null) ? forceActivationStatus : !data.mediaSetTabActivated;
                                                
                                                // Is the media strip activated?
                                                if (targetActivationStatus == true)
                                                {
                                                    // Activate the media strip
                                                    mediaStrip.animate({
                                                        bottom:     	0
                                                    }, 
                                                    {
                                                        duration:       data.slideUpMediaStripTabDuration,
                                                        easing:         data.slideUpMediaStripTabEasing,
                                                        complete:       function ()
                                                                        {
                                                                            mediaStripTab.html(data.mediaStripTabActiveCaption);
                                                                        }
                                                    });
                                                }
                                                else
                                                {
                                                    // Detivate the media strip
                                                    mediaStrip.animate({
                                                        bottom:     	-55
                                                    }, 
                                                    {
                                                        duration:       data.slideDownMediaStripTabDuration,
                                                        easing:         data.slideDownMediaStripTabEasing,
                                                        complete:       function ()
                                                                        {
                                                                            mediaStripTab.html(data.mediaStripTabInactiveCaption);
                                                                        }
                                                    });
                                                }
                                                
                                                data.mediaSetTabActivated = targetActivationStatus;
                                                
                                                return this;
                                            },
                                            
        toggleMediaStripNavigation:         function ()
                                            {
                                                // Get the instance of yamg
                                                var $this = $(this);
                                                var data = $this.data('yamg');
                                                
                                                var mediaStripThumbnails = data.yamgContainer.find('div.yamgMediaStripThumbnails');
                                                var mediaStripNavigation = data.yamgContainer.find('div.yamgMediaStripNavigation');
                                                
                                                var containerWidth = data.yamgContainer.find('div.yamgMediaStrip').width();
                                                
                                                if (mediaStripThumbnails.width() > containerWidth - (data.mediaStripNavigationWidth * 2) + data.mediaStripThumbnailRightMargin)
                                                {
                                                    mediaStripNavigation    .stop()
                                                                            .clearQueue()
                                                                            .removeClass('yamgMediaStripNavigationInactive')
                                                                            .fadeTo(data.fadeInMediaStripNavDuration, 1);
                                                }
                                                else
                                                {
                                                    mediaStripNavigation    .stop()
                                                                            .clearQueue()
                                                                            .addClass('yamgMediaStripNavigationInactive')
                                                                            .fadeTo(data.fadeInMediaStripNavDuration, 0);
                                                }
                                                
                                                return this;
                                            },
                                            
        updateMediaStripThumbnails:         function()
                                            {
                                                // Get the instance of yamg
                                                var $this = $(this);
                                                var data = $this.data('yamg');
                                                
                                                // Calculate width all thumbnails
                                                var totalWidth = 2; // border ?
                                                var thumbnails = data.yamgContainer.find('div.yamgMediaStripThumbnail');
                                                
                                                $.each(thumbnails, function()
                                                {
                                                    totalWidth += $(this).outerWidth(true);
                                                });
                                                
                                                // Set width of container div
                                                data.yamgContainer.find('div.yamgMediaStripThumbnails').width(totalWidth);
                                                
                                                return this;
                                            },
                                            
        highlightMediaStripThumbnail:       function(mediaItemIndex)
                                            {
                                                // Get the instance of yamg
                                                var $this = $(this);
                                                var data = $this.data('yamg');
                                                
                                                // Get all thumbnails
                                                var thumbnails = data.yamgContainer.find('div.yamgMediaStripThumbnail');
                                                
                                                // Remove active class
                                                thumbnails.css('opacity', data.mediaStripThumbnailOpacity).removeClass('yamgMediaStripThumbnailActive');
                                                
                                                $(thumbnails[mediaItemIndex])   .addClass('yamgMediaStripThumbnailActive')
                                                                                .css('opacity', 1);
                                                
                                                return this;
                                            },
                                            
        mediaStripScrollToThumbnail:        function(mediaItemIndex)
                                            {
                                                // Get the instance of yamg
                                                var $this = $(this);
                                                var data = $this.data('yamg');
                                                
                                                // mediaItemIndex
                                                if (mediaItemIndex == undefined 
                                                    || mediaItemIndex == null)
                                                {
                                                    mediaItemIndex = data.activeMediaSet.currentlyDisplayedItem;
                                                }
                                                
                                                // Thumbnails container
                                                var thumbnailContainer = data.yamgContainer.find('div.yamgMediaStripThumbnails');
                                                
                                                // Get container width
                                                var containerWidth = data.yamgContainer.width();
                                                
                                                // Calculate offset selected thumbnail
                                                var offsetLeft = 0;
                                                var widthThumbnail = 0;
                                                
                                                var thumbnails = data.yamgContainer.find('div.yamgMediaStripThumbnail');
                                                
                                                $.each(thumbnails, function(index)
                                                {
                                                    if (index == mediaItemIndex)
                                                    {
                                                        // Save width
                                                        widthThumbnail = $(this).outerWidth(true);
                                                        
                                                        return false;
                                                    }
                                                    
                                                    offsetLeft += $(this).outerWidth(true);
                                                });
                                                
                                                // Calculate center offset
                                                var centerOffset = Math.round((containerWidth - widthThumbnail) / 2);
                                                
                                                var targetLeft = 0;
                                                if (offsetLeft <= centerOffset)
                                                {
                                                    targetLeft = data.mediaStripNavigationWidth;
                                                }
                                                else if (offsetLeft > centerOffset)
                                                {
                                                    targetLeft = centerOffset - offsetLeft;
                                                    
                                                    if (targetLeft + thumbnailContainer.width() - widthThumbnail < containerWidth - widthThumbnail - data.mediaStripNavigationWidth)
                                                    {
                                                        // Don't scroll further
                                                        targetLeft = containerWidth - thumbnailContainer.width() - data.mediaStripNavigationWidth + data.mediaStripThumbnailRightMargin + 1;
                                                        
                                                        if (targetLeft > data.mediaStripNavigationWidth)
                                                        {
                                                            targetLeft = data.mediaStripNavigationWidth;
                                                        }
                                                    }
                                                }
                                                
                                                
                                                // Set scrolled to thumbnail
                                                data.currentlyScrolledToThumbnail = mediaItemIndex;
                                                
                                                // Animate
                                                thumbnailContainer.animate(
                                                    {
                                                        left:     targetLeft
                                                    }, 
                                                    {
                                                        duration:       data.slideMediaStripThumbnailDuration,
                                                        easing:         data.slideMediaStripThumbnailsEasing
                                                    });
                                                
                                                return this;
                                            },
                                            
        scrollMediaStrip:                   function(direction)
                                            {
                                                // Get the instance of yamg
                                                var $this = $(this);
                                                var data = $this.data('yamg');
                                             
                                                // Calculate how many thumbnails are displayed
                                                var thumbnailContainerWidth = data.yamgContainer.find('div.yamgMediaStripThumbnails').width();
                                                var averageSizeThumb = thumbnailContainerWidth / data.activeMediaSet.mediaItemArray.length;
                                                var numberOfThumbs = Math.floor(data.yamgContainer.width() / averageSizeThumb);
                                                
                                                // Calculate new index
                                                var mediaItemIndex = data.currentlyScrolledToThumbnail;
                                             
                                                // Direction
                                                switch (direction)
                                                {
                                                    case 'left':
                                                        mediaItemIndex -= numberOfThumbs;
                                                        break;
                                                        
                                                    case 'right':
                                                        mediaItemIndex += numberOfThumbs;
                                                        break;
                                                }
                                                
                                                // Check min & max index
                                                if (mediaItemIndex < 0)
                                                {
                                                    mediaItemIndex = 0;
                                                }
                                                else if (mediaItemIndex >= data.activeMediaSet.mediaItemArray.length)
                                                {
                                                    mediaItemIndex = data.activeMediaSet.mediaItemArray.length - 1;
                                                }
                                                
                                                // Scroll to thumbnail
                                                methods.mediaStripScrollToThumbnail.apply(this, [mediaItemIndex]);
                                                
                                                return this;
                                            },
                                            
        positionControls:                   function()
                                            {
                                                // Get the instance of yamg
                                                var $this = $(this);
                                                var data = $this.data('yamg');
                                                
                                                var controls = data.yamgContainer.find('.yamgControls');
                                                var offsetLeft = Math.round((data.yamgContainer.width() - controls.width()) / 2);

                                                controls.css('left', offsetLeft);
                                                
                                                return this;
                                            },
                                            
        toggleZoomMode:                     function()
                                            {
                                                // Get the instance of yamg
                                                var $this = $(this);
                                                var data = $this.data('yamg');
                                                
                                                // Change zoom mode
                                                if (data.currentZoomMode == ZoomModes.FullScreen)
                                                {
                                                    data.currentZoomMode = ZoomModes.FitOnScreen;
                                                }
                                                else if (data.currentZoomMode == ZoomModes.FitOnScreen)
                                                {
                                                    data.currentZoomMode = ZoomModes.FullScreen;
                                                }
                                                
                                                methods.gotoMediaItem.apply(this, [data.activeMediaSet.currentlyDisplayedItem]);
                                                
                                                return this;
                                            },
                                            
        exitGallery:                        function()
                                            {
                                                // Get the instance of yamg
                                                var $this = $(this);
                                                var data = $this.data('yamg');
                                                
                                                data.activeMediaSet = null;
                                                
                                                // Make content scrollable again
                                                $('html').removeClass('yamgFullScreen');
                                                $('body').removeClass('yamgFullScreen');
                                                
                                                // Fade out
                                                data.yamgContainer  .stop()
                                                                    .clearQueue()
                                                                    .animate(
	                                                                    {
	                                                                        opacity:    0
	                                                                    },
	                                                                    data.fadeOutYAMGDuration,
	                                                                    data.fadeOutGalleryEasing,
	                                                                    function()
	                                                                    {
		                                                                    // Remove container from DOM
	                                                                        data.yamgContainer.remove();                                                
	                                                                    }
	                                                                );
                                                
                                                
                                                return this;
                                            },
        
        destroy:                            function()
                                            {
                                                return this.each(function()
                                                {
                                                    var $this = $(this);
                                                    var data = $this.data('yamg');
                                                    
                                                    // Remove data
                                                    $this.removeData('yamg');
                                                });
                                            }
    };

    
    var eventHandlers = 
    {
        yamgContainerMouseMove:             function(e)
                                            {
                                                // Get the data object
                                                var data = e.data;
                                                
                                                if (data.hudInactivityTimeout == undefined
                                                    || data.hudInactivityTimeout == null)
                                                {
                                                    // Show hud
                                                    methods.showHud.apply(data.target);
                                                }
                                                
                                                // Clear timer
                                                clearTimeout(data.hudInactivityTimeout);
                                                
                                                // Set timer
                                                data.hudInactivityTimeout = setTimeout(function()
                                                {
                                                    // Clear timeout
                                                    clearTimeout(data.hudInactivityTimeout);
                                                    data.hudInactivityTimeout = null;
                                                    
                                                    // Hide hud
                                                    methods.hideHud.apply(data.target);
                                                }, data.hudInactivityFadeOutTimeout);
                                                
                                            },
                                            
        yamgContainerMouseLeave:            function(e)
                                            {
                                                // Get the data object
                                                var data = e.data;
                                                
                                                // Clear timer
                                                clearTimeout(data.hudInactivityTimeout);
                                                data.hudInactivityTimeout = null;
                                                
                                                // Hide hud
                                                methods.hideHud.apply(data.target);
                                            },
                                            
        windowResize:                       function(e)
                                            {
                                                // Get the data object
                                                var data = e.data;
												
												if (data.activeMediaSet == null)
												{
													return false;
												}
												
												// Size container
										        methods.calculateYamgContainerSize.apply(data.target);
										        
                                                // Reposition controls
                                                methods.positionControls.apply(data.target);
                                                
                                                // Calculate and set item dimensions
                                                methods.setMediaItemSizeAndOffset.apply(data.target);
                                                
                                                // Toggle media strip navigation
                                                methods.toggleMediaStripNavigation.apply(data.target);
                                                
                                                // Scroll to thumbnail
                                                methods.mediaStripScrollToThumbnail.apply(data.target);
                                            },
        
        mediaSetThumbnailClicked:           function(e)
                                            {
                                                // Get the data object
                                                var mediaSet = e.data.data;
                                                var data = e.data.instanceData;
                                                
                                                data.activeMediaSet = mediaSet;
                                                
                                                methods.displayGallery.apply(e.data.instanceData.target);
                                            },
                                            
        fadeItemMouseEnterLeave:            function(e)
                                            {
                                                $(this).stop();
                                                $(this).clearQueue();
                                                
                                                $(this).fadeTo(e.data.duration, e.data.targetOpacity);
                                            },
                                            
        mediaItemNavPreviousClick:          function(e)
                                            {
                                                // Get the data objects and instance of yamg
                                                var data = e.data;
                                                var mediaSet = data.activeMediaSet;
                                                
                                                if (mediaSet.currentlyDisplayedItem > 0)
                                                {
                                                    methods.gotoMediaItem.apply(data.target, [mediaSet.currentlyDisplayedItem - 1]);
                                                }
                                            },
                                            
        mediaItemNavNextClick:              function(e)
                                            {
                                                // Get the data objects and instance of yamg
                                                var data = e.data;
                                                var mediaSet = data.activeMediaSet;
                                                
                                                if (mediaSet.currentlyDisplayedItem < mediaSet.mediaItemArray.length - 1)
                                                {
                                                    methods.gotoMediaItem.apply(data.target, [mediaSet.currentlyDisplayedItem + 1]);
                                                }
                                            },
                                            
        mediaStripTabClick:                 function(e)
                                            {
                                                // Get the data object
                                                var data = e.data;
                                                
                                                // Toggle Media Strip
                                                methods.toggleMediaStrip.apply(data.target);
                                            },
                                            
        mediaStripNavigationClick:          function(e)
                                            {
                                                // Get the data object
                                                var direction = e.data.data.direction;
                                                var data = e.data.instanceData;
                                                
                                                // Scrool the media strip
                                                methods.scrollMediaStrip.apply(data.target, [direction]);
                                            },
                                            
        controlZoomClick:                   function(e)
                                            {
                                                // Get the data object
                                                var data = e.data;
                                                
                                                // Toggle zoom mode
                                                methods.toggleZoomMode.apply(data.target);
                                            },
                                            
        controlExitClick:                   function(e)
                                            {
                                                // Get the data object
                                                var data = e.data;
                                                
                                                // Exit gallery
                                                methods.exitGallery.apply(data.target);
                                            },
                                            
        windowKeyUp:		                function(e)
                                            {
                                                // Get the data object
                                                var data = e.data;
                                                var mediaSet = data.activeMediaSet;
                                                
                                                switch(e.keyCode)
                                                {
                                                	// ESC
                                                	case 27:
														// Exit gallery
														methods.exitGallery.apply(data.target);
                                                	
                                                		break;
                                                	
                                                	// Left arrow
                                                	case 37:
                                                		if (mediaSet.currentlyDisplayedItem > 0)
														{
															methods.gotoMediaItem.apply(data.target, [mediaSet.currentlyDisplayedItem - 1]);
														}
														
                                                		break;
                                                	
                                                	// Up arrow
                                                	case 38:
														methods.toggleMediaStrip.apply(data.target, [true]);
                                                	
                                                		break;
                                                	
                                                	// Right arrow
                                                	case 39:
														if (mediaSet.currentlyDisplayedItem < mediaSet.mediaItemArray.length - 1)
														{
															methods.gotoMediaItem.apply(data.target, [mediaSet.currentlyDisplayedItem + 1]);
														}
														
                                                		break;
                                                	
                                                	// Down arrow
                                                	case 40:
														methods.toggleMediaStrip.apply(data.target, [false]);
                                                	
                                                		break;
                                                }
                                            },
                                            
		yamgContainerTouchStart:			function(e)
											{
                                                // Get the data object
                                                var data = e.data;
                                                
                                                // Set startingpoint
                                                data.iOsStartTouchPosition = {
                                                	x:	e.originalEvent.targetTouches[0].pageX,
                                                	y:	e.originalEvent.targetTouches[0].pageY
                                                }
                                                
                                                // Exit gesture check
                                                if (e.originalEvent.touches.length == data.iOsNumberOfFingersExitGesture)
                                                {
	                                                // Exit gallery
	                                                methods.exitGallery.apply(data.target);
	                                            }
											},
                                            
		yamgContainerTouchMove:				function(e)
											{
                                                // Get the data object
                                                var data = e.data;
                                                
                                                // Set startingpoint
                                                data.iOsCurrentTouchPosition = {
                                                	x:	e.originalEvent.targetTouches[0].pageX,
                                                	y:	e.originalEvent.targetTouches[0].pageY
                                                }
                                                
												// Prevent default behaviour
												return false;
											},
                                            
		yamgContainerTouchEnd:				function(e)
											{
                                                // Get the data object
                                                var data = e.data;
                                                var mediaSet = data.activeMediaSet;

                                                // Gesture prevented this event ?
												if (new Date().getTime() - data.iOsLastGestureTime < data.iOsGestureTouchEndTimeout)
												{
													return false;
												}
                                                
                                                if (data.iOsCurrentTouchPosition != null
                                                	&& data.iOsStartTouchPosition != null)
                                                {
	                                                // Calculate delta's
	                                                var deltaX = data.iOsCurrentTouchPosition.x - data.iOsStartTouchPosition.x;
	                                                var deltaY = data.iOsCurrentTouchPosition.y - data.iOsStartTouchPosition.y;
	
	                                                if (deltaX < 0
	                                                	&& deltaX < data.iOsMoveThreshold * -1)
	                                            	{
	                                            		// Next image
		                                                if (mediaSet.currentlyDisplayedItem < mediaSet.mediaItemArray.length - 1)
		                                                {
		                                                    methods.gotoMediaItem.apply(data.target, [mediaSet.currentlyDisplayedItem + 1]);
		                                                }
	                                            	}
	                                            	else if (deltaX > 0
	                                                		&& deltaX > data.iOsMoveThreshold)
	                                            	{
	                                            		// Previous image
	                                            		if (mediaSet.currentlyDisplayedItem > 0)
		                                                {
		                                                    methods.gotoMediaItem.apply(data.target, [mediaSet.currentlyDisplayedItem - 1]);
		                                                }
	                                            	}
	                                                else if ((deltaY < 0 && deltaY < data.iOsMoveThreshold * -1)
	                                                		|| (deltaY > 0 && deltaY > data.iOsMoveThreshold))
	                                            	{
		                                                // Toggle Media Strip
		                                                methods.toggleMediaStrip.apply(data.target);
	                                            	}
	                                                                                                
	                                                // Reset
	                                                data.iOsStartTouchPosition = null;
	                                                data.iOsCurrentTouchPosition = null;
												}
												
                                                return false;
											},
											
		yamgContainerOnGestureChange:		function(e)
											{
												// Prevent default behaviour
												return false;
											},
											
		yamgContainerOnGestureEnd:			function(e)
											{
                                                // Get the data object
                                                var data = e.data;
                                                
												if ((e.originalEvent.scale > 1 && data.currentZoomMode == ZoomModes.FitOnScreen)
													|| (e.originalEvent.scale < 1 && data.currentZoomMode == ZoomModes.FullScreen))
												{
													// Toggle zoom mode
	                                                methods.toggleZoomMode.apply(data.target);
	                                                
	                                                // Prevent touch end event
	                                                data.iOsLastGestureTime = new Date().getTime();
												}
												
												// Prevent default behaviour
												return false;
											}
    }
    
    $.fn.yamg = function(method)
    {
        if (methods[method])
        {
            return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
        }
        else if (typeof method === 'object' || ! method)
        {
            return methods.init.apply(this, arguments);
        }
        else
        {
            $.error('Method ' +  method + ' does not exist on jQuery.yamg');
        }
    };

})(jQuery);
