(function($){
    $.fn.bcGallery = function(options) {
        var opts = $.extend({}, $.fn.bcGallery.defaults, options);
        
        return this.each(function() { 
            
            // plugin setting
            var element = $(this);
            
            var o = opts;
            var $imageContainer = $(o.imageContainer);
            var $thumbs = $(o.thumbs);
            var thumbnailCarousel = o.thumbnailCarousel;
            var carouselMovement = o.carouselMovement;
            var step = o.step;
            var captions = o.captions;
            
            
            var totalPhotos = $thumbs.find('li').length;
            var cache = new Array();
            var timer, bigthumbs = false, started = false;
            
            // buttons
            var $showAllBtn = $(o.showAllBtn);
            var $showThumbsBtn = $(o.showThumbsBtn);
            var $slideShowBtn = $(o.slideShowBtn);
            var $stopSlideShowBtn = $(o.stopSlideShowBtn);
            
            var $galleryInfo = $(o.galleryInfo);
            var $closeInfoBtn = $(o.closeInfoBtn);
            var $showInfoBtn = $(o.showInfoBtn);
            
            var lastOpen, caption; 
            
            /**
              * initial operations when the plugin called
              * caches the gallery images, initialize the hover effect for thumbnails
             **/
            
            // cache the photos
            cacheGallery($thumbs.find('a.gal'));                       
            // thumbnail image view            
            thumbnailHovers($thumbs);
            
            /**
              * buttons and click actions
              *
             **/
            
            // click function for small thumbnails, just prevents the click event, new image will appear according to focus function
            $thumbs.find('a.gal').click(function(e){
               e.preventDefault();
            });
            
            // support for tab navigation
            $thumbs.find('a.gal').focus(function(e){
                hoverEffects($(this), $thumbs);
                showBigImage($(this).parent());                
            });                                                         
            
            // opens the info text
            $showInfoBtn.click(function(){                             
                showHideInfo();
            });
            
            // closes the info text
            $closeInfoBtn.click(function(){
                showHideInfo(); 
            });
            
            // show big thumbnails
            $showAllBtn.click(function(){
                bigthumbs = true;                
                lastOpen = $thumbs.find('li.current');
                
                
                toggleButtons($showThumbsBtn, $showAllBtn);
                showHideThumbnails();                
                showall();                    
            });
            
            // show small thumbnails
            $showThumbsBtn.click(function(){
                bigthumbs = false;
                
                toggleButtons($showAllBtn, $showThumbsBtn);
                showHideThumbnails();
                showBigImage(lastOpen);                
            });


            
            /**
              * action functions
             **/                                                 
            
            // inserts the big thumbnails
            function showall(){
                bigthumbs = true;
                
                var allThumbs = '<ul id="gallery" class="group-end">';
                
                $thumbs.find('li').each(function(){
                    
                    allThumbs += '<li class="big-thumb ' + $(this).attr('class') + '">' + $(this).html().replace('small_', 'medium_') + '</li>';
                });
                
                allThumbs += '</ul>';
                
                $imageContainer.html(allThumbs);
                
                thumbnailHovers($("#gallery")); 
               
            }
                       
            // toggle buttons
            function toggleButtons(show, hide){
                show.fadeIn().css({ display : 'block' });
                hide.fadeOut();
            } 
            
            function showHideThumbnails(){
                if(thumbnailCarousel == true){
                    $("#bcgal-carousel").slideToggle();
                }
                else{
                    $thumbs.slideToggle();
                }
            }
            
            // show hide info box for the gallery
            function showHideInfo(){
                $galleryInfo.slideToggle(500);
                $imageContainer.slideToggle(500);
                
                if($showInfoBtn.hasClass('clicked')){
                    $showInfoBtn.removeClass('clicked');
                }
                else{
                    $showInfoBtn.addClass('clicked');
                }
            }
            
            // cache images in the gallery
            function cacheGallery(images){
                var i = 0;
                
                images.each(function(){
                    var cacheImage = document.createElement('img');
                    $(this).attr('id', i);
                    cacheImage.src = $(this).attr('href');
                    cache.push(cacheImage);
                    i++;
                });               
            }
            
            // show the big version of clicked image
            function showBigImage(elem){
                
                var image = elem.find('a.gal').attr('href');
                
                if(captions == 'title'){
                    caption = elem.find('a.gal').attr('title');
                }
                
                else{
                    caption = elem.find(captions).html();
                }
                
                if($galleryInfo.is(':visible')){
                    $showInfoBtn.removeClass('clicked');
                    $galleryInfo.slideToggle(500);
                    $imageContainer.html('<div class="figure"><img src="' + image + '" /></div><p>' + caption + '</p>').hide().slideToggle(500);
                }
                
                else {
                    $imageContainer.html('<div class="figure"><img src="' + image + '" /></div><p>' + caption + '</p>').hide().fadeIn(500);
                }
            }
            
            function thumbnailHovers(elem){
                elem.find('li').not('li.current').find('a').css('opacity', '0.5');
                elem.find('li a').hover(
                    function(){
                        $(this).fadeTo('slow', 1);
                    },
                    function(){
                        if($(this).parent().hasClass('current')){
                            
                        }
                        else {
                            $(this).fadeTo('slow', 0.5);
                        } 
                    }
                );
            }
            
            function hoverEffects(elem, parent){
                var $parent = elem.parent();
                
                parent.find('li').removeClass('current').find('a').css('opacity', '0.5');
                $parent.addClass('current');
                elem.css('opacity', '1');
            } 
            
            /**
              * carousel options
             **/            
            if(thumbnailCarousel == true){
                      
                
                var stepLength, maxTop, maxLeft, thumbsDim, position = $thumbs.position(), first = true, last = false;
                
                if(carouselMovement == 'vertical'){
                    thumbsDim = $thumbs.height();
                    maxTop = $("#bcgal-thumbnails").height() - thumbsDim;
                          
                }
                
                if(carouselMovement == 'horizontal'){
                    thumbsDim = $thumbs.width();
                    maxLeft = $("#bcgal-thumbnails").width() - thumbsDim;
                } 
                
                function moveCarousel(type, step){                    
                    stepLength = Math.ceil((thumbsDim/totalPhotos) * step);
                
                    move(type);                  
                }
                
                function move(type){                
                    var nextPosition, prevPosition, movement;
                    
                    position = $thumbs.position();
                    
                    if(carouselMovement == 'vertical'){
                        nextPosition = position.top - stepLength;
                        if(nextPosition < maxTop){
                            nextPosition = maxTop - parseInt($thumbs.find('li').css('margin-bottom'));
                        }
                        
                        prevPosition = position.top + stepLength;
                        if(prevPosition > 0){
                            prevPosition = 0;
                        }
                    }
                    
                    if(carouselMovement == 'horizontal'){
                        nextPosition = position.left - stepLength;
                        if(nextPosition < maxLeft){
                            nextPosition = maxLeft - parseInt($thumbs.find('li').css('margin-right'));
                        }
                        
                        prevPosition = position.left + stepLength;
                        if(prevPosition > 0){
                            prevPosition = 0;
                        }
                    } 
                    
                    if(type == 'next'){
                        if(carouselMovement == 'vertical'){
                            $thumbs.animate({ 'top' : nextPosition });
                        }
                        if(carouselMovement == 'horizontal'){
                            $thumbs.animate({ 'left' : nextPosition });
                        }
                    } 
                    
                    if(type == 'prev'){
                        if(carouselMovement == 'vertical'){
                            $thumbs.animate({ 'top' : prevPosition });
                        }
                        if(carouselMovement == 'horizontal'){
                            $thumbs.animate({ 'left' : prevPosition });
                        }
                    }               
                    
                }
                
                // navigation buttons                
                $("a.next").click(function(e){
                    moveCarousel('next', step);    
                    return false;
                });
                
                $("a.prev").click(function(e){
                    moveCarousel('prev', step);    
                    return false;
                });
            }                                              
        });
    };
    
   	$.fn.bcGallery.defaults = {
   	    imageContainer: '#main_image',
   	    thumbs: '#gallery',
   	    thumbnailCarousel: true,
        carouselMovement: 'vertical',
        captions: 'title',
        step: 3,
        slideShowBtn: 'a.slideshow',
        stopSlideShowBtn: 'a.stop',
        slideShowDelay: 5000,
        showAllBtn: 'a.showall',
        showThumbsBtn: 'a.showthumbs',
        galleryInfo: '#info',
        showInfoBtn: 'a.info',
        closeInfoBtn: 'a.close'
	};
})(jQuery);

