$.fn.gallery = function() {

    var options = arguments[0] || {};
    jgallery = new JGallery(this, options);
};

/**
 * Creates the image gallery
 * @param target
 * @param options
 */
function JGallery(target, options)
{
    var src_and_caption_str = options['images'];

    if (src_and_caption_str === '')
    {
        return;
    }

    var fade_time = options['fade_time'] || 400;
    this.interval = options['interval'] || 8000;

    this.src_and_captions = src_and_caption_str.split(',');
    this.current_image_index = 0;

    var gallery_image = $('<div>').attr({'id' : 'gallery_image'});
    this.gallery_target = $('<div>').attr({'id' : 'gallery_target'});

    this.gallery_caption = $('<div>').attr({'id' : 'gallery_caption'});
    this.gallery_text = $('<div>').addClass('text');
    var gallery_bg = $('<div>').addClass('bg');
    this.gallery_caption.append(this.gallery_text, gallery_bg);

    gallery_image.append(this.gallery_target, this.gallery_caption);

    var gallery_thumbs = $('<ul>').attr({'id' : 'gallery_thumbs'});
    var spacer = $('<div>').addClass('spacer');
	var image_count = 0;
	
    for ( var i in this.src_and_captions )
    {
        gallery_thumbs.append( this.makeLink(i, this.src_and_captions[i]) );
		image_count++;
    }

    $(target).empty().append(gallery_image, gallery_thumbs, spacer);

    // Load image
    this.loadImage(this.src_and_captions[0], 0);

    // Start the slideshow
    if (! options['manual_only'] && image_count > 1)
    {
        this.startSlideshow();
    }
}

/**
 * Creates an image gallery image link
 * @param index
 * @param image
 */
JGallery.prototype.makeLink = function(index, src_and_caption)
{
    var _this = this;
    var li = $('<li>');
    var a = $('<a>').attr({href : src_and_caption,
                           id : "gallery_image_button_" + (index)}).addClass("gallery_image_button").text(++index);

    a.bind('click', function() {
        var src_and_caption = $(this).attr('href');
        _this.loadImage(src_and_caption);
        return false;
    });

    return li.html(a);
}

/**
 * Loads an image
 * @param index
 * @param image
 */
JGallery.prototype.loadImage = function(src_and_caption, index)
{
    var tmp = src_and_caption.split('|');
    var src = tmp[0].replace(/ /g, '%20');
    var caption_text = tmp[1];
    var _this = this;
    
    var gallery_target = this.gallery_target;
    var fade_time = this.fade_time;

    this.gallery_caption.show();

    $(gallery_target).fadeOut(fade_time, function() {

        var img = new Image();
        $(img).bind('load', function() {

            $(gallery_target).css( {'background-image' : 'url(' + $(this).attr('src') + ')'} ).fadeIn(fade_time, function() {
                _this.gallery_caption.slideDown(fade_time);
            });
            _this.setCaption(caption_text);

            // Mark button as the current choice
            $(".gallery_image_button").removeClass("current");
            $("#gallery_image_button_" + index).addClass("current");

        }).attr({'src' : '/' + src});
    });
}

JGallery.prototype.loadNextImage = function()
{
    this.current_image_index++;
    
    if (this.current_image_index >=  this.src_and_captions.length)
    {
        this.current_image_index = 0;
    }

    this.loadImage(this.src_and_captions[this.current_image_index], this.current_image_index);
}

JGallery.prototype.startSlideshow = function()
{
    setInterval( bind(this.loadNextImage, this), this.interval );
}

function bind(func, object)
{
    return function()
    {
        return func.apply(object, arguments);
    };
}


/**
 * Set the caption
 * @param index
 * @param image
 */
JGallery.prototype.setCaption = function(caption_text)
{
    this.gallery_text.text(caption_text);
}
