/* Format a gallery to use CSS based scrolling in the thumbnail window and perform
 * nice crossfading for the preview image display
 *
 * scroll_pane -> id or class of the div contining the thumbnails
 * preview_id  -> id of the container used to display the preview image.
 */
function wtGallery(scroll_pane, preview_id, img_title)
{
    this._crossfade = new CrossFade(preview_id);
    this._img_cache = new Object();

    $(scroll_pane).jScrollPane({
        showArrows:       true,
        horizontalGutter: 10,
        hideFocus:        true
    });

    $('.jspPane > a').each(function() {
        $(this).mouseover(function() {
            hash = $(this).attr('href').lastIndexOf('#');
            preview_crossfade.preload($(this).attr('href').substr(hash+1));
        });

        $(this).click(function(ev) {
            hash = $(this).attr('href').lastIndexOf('#');
            preview_crossfade.display($(this).attr('href').substr(hash+1));
            $(img_title).text($(this).attr('title'));
            ev.preventDefault();
            return false;
        });

    });
}

wtGallery.prototype.preload = function(image_uri)
{
    if (typeof(this._img_cache[image_uri]) == 'undefined')
    {
//        console.debug("Preloading " + image_uri);
        this._img_cache[image_uri] = new Image();
        this._img_cache[image_uri].src = image_uri;
    }
}

wtGallery.prototype.display = function(image_uri)
{
    this.preload(image_uri);

//    console.debug("Displaying " + image_uri);
    this._crossfade.change_to(this._img_cache[image_uri]);
}

/* This class allows the user to crossfade between images on demand
 *
 * container_id -> The id of the container to use for crossfading.
 */
function CrossFade(container_id)
{
    this._container_id = container_id;
    this._clone_id     = container_id + "_clone";
    this._cur_invis    = 1;

    // Clone the container and append the clone to the parent component of the original container.
    $(this._container_id).clone().attr("id", this._clone_id.substr(1)).appendTo($(this._container_id).parent());
    // Move the cloned container so that it is in exactly the same location as the original
    // and ensure it is initially hidden

//    console.debug("Container offset: " + p.top + ":" + leftPos);
    $(this._clone_id).addClass('preview_clone').width(
         $(this._container_id).width() );

    $(this._clone_id).position({
                         of: this._container_id,
                         my: "left top",
                         at: "left top",
                         offset: "0",
                         collision: "none"
                     });

    $(this._clone_id).fadeTo(0, 0);
}

// This changes the displayed image to the supplied content
CrossFade.prototype.change_to = function(new_content, speed)
{
    if (typeof(speed) == 'undefined')
        speed = 500;

    //
    // Switch the content of the invisible img
    //
    container_in_use = (this._cur_invis == 1 ? this._clone_id : this._container_id);
    $(container_in_use).empty().append(new_content);

    parent_height = $(container_in_use).parent().height();
    new_height = $(container_in_use).height();

//    console.debug("Using container '" + container_in_use + "' " + this._cur_invis + " to " + new_content.src);
    if (this._cur_invis == 1)  {
        fade_in  = $(this._clone_id);
        fade_out = $(this._container_id);
    } else {
        fade_out = $(this._clone_id);
        fade_in  = $(this._container_id);
    }
    this._cur_invis = 1 - this._cur_invis;

    // Resize the parent container height to be bigger if required, before doing
    // the fade between the containers.
    $(container_in_use).parent().animate({ height: (new_height > parent_height) ?
                                                      new_height : parent_height
                                         }, 'fast', function() {
        fade_out.fadeTo(speed, 0);
        fade_in.fadeTo(speed, 1, function() {
            if (new_height < parent_height)
            {
                // Resize the parent container height after the fade if it
                // is smaller.
                $(container_in_use).parent().animate({ height: new_height }, 'fast');
            }
        });
    });
}

/* Create a slideshow that automatically transitions between the images that are passed in
 *
 * container_id  -> The id of the container that will be duplicated and used for crossfading
 *                  between images.  This container should be wrapping in a div to avoid wierd
 *                  formatting problems
 * image_list    -> An array of URIs to images that will be used to crossfade between
 * fade_interval -> The time between transitions
 * fade_speed    -> The time to perform a transition
 */
function SlideShow(container_id, image_list, fade_interval, fade_speed)
{
    this._crossfade  = new CrossFade(container_id);
    this._image_uri  = image_list;
    this._image_obj  = [];
    this._fade_speed = fade_speed;

    this._cur_image = 0;

    this.preload_next_image();
    setInterval(display_next_image(this), fade_interval);
};

// Ref: http://jibbering.com/faq/notes/closures/#clSto
// Use function closures to pass references into a anonymous function.
function display_next_image(obj_ref)
{
    return (function ()
    {
//        console.debug("Loading image [" + obj_ref._cur_image + "] " + obj_ref._image_uri[obj_ref._cur_image]);

        obj_ref._crossfade.change_to(obj_ref._image_obj[obj_ref._cur_image], obj_ref._fade_speed);

        obj_ref._cur_image = (obj_ref._cur_image + 1) % obj_ref._image_uri.length;
        obj_ref.preload_next_image();
    });
}

SlideShow.prototype.preload_next_image = function ()
{
    if (typeof(this._image_obj[this._cur_image]) == 'undefined')
    {
//        console.debug("Preloading image [" + this._cur_image + "] " + this._image_uri[this._cur_image]);
        this._image_obj[this._cur_image] = new Image();
        this._image_obj[this._cur_image].src = this._image_uri[this._cur_image];
    }
}


