/**
 * this class uses jQuery
 *
 * fades through all child elements
 *
 * $Id: show.js,v 1.4 2009/07/16 21:49:16 gschwart Exp $
 */
function Show (els, options)
{
    var self = this;

    // initialize counters
    self.show_index = 0;
    self.box_index  = 0;

    // separate Show boxes into objects
    self.boxes = new Array();
    $(els).each(function (i, box_el) {
        self.boxes.push(new Box(self, box_el));
    });

    // handle options
    self.options = options || {};
    var default_options = {
        animation_length       : 1000,
        animation_pause_length : 1000,
        initial_delay          : 1000
    };
    for( var opt in default_options )
    {
        if( typeof(self.options[opt]) == "undefined" )
        {
            self.options[opt] = default_options[opt];
        }
    }

    self.get_next_show_element = function ()
    {
        var result = self.show_elements[self.show_index];

        self.show_index++;
        if( self.show_index == self.show_elements.length )
        {
            self.show_index = 0;
        }

        return result;
    }

    self.get_next_box = function ()
    {
        var result = self.boxes[self.box_index];

        self.box_index++;
        if( self.box_index == self.boxes.length )
        {
            self.box_index = 0;
        }

        return result;
    }

    /**
     * find a box, and fade out whatever is there while fading in the next show_element
     */
    self.show = function ()
    {
        var box = self.get_next_box();

        box.show(
            self.get_next_show_element(),
            function () {
                setTimeout(
                    function() {
                        self.show();
                    },
                    self.options.animation_pause_length
                );
            }
        )
    }

    $(window).load(function() {
        // use the first show_element in the first box for width/height
        self.item_height = $(self.boxes[0].el).children().eq(0).outerHeight(true);
        self.item_width  = $(self.boxes[0].el).children().eq(0).outerWidth(true);

        // extract all show_elements from all Shows
        // set some css options for Shows and show_elements
        // remove all show_elements from the DOM
        self.show_elements = new Array();
        $(self.boxes).each(function () {
            $(this.el).children().each(function(i, show_element) {
                $(show_element).css({
                    position : 'absolute',
                    left     : 0,
                    top      : 0,
                    opacity  : 0
                });

                self.show_elements.push(show_element);
                $(show_element).remove();
            });

            $(this.el).css({
                'position' : 'relative',
                'overflow' : 'hidden',
                'width'    : self.item_width,
                'height'   : self.item_height
            });
        });

        // initialize each Show with a show_element
        $(self.boxes).each(function (i, box) {
            box.show_without_animation(self.get_next_show_element());
        });

        // start Show
        setTimeout(
            function() {
                self.show();
            },
            self.options.initial_delay
        );
    });
}

/**
 * Show - the Show that this Box is a part of
 * el   - the DOM element which this Box represents
 */
function Box (Show, el)
{
    var self = this;

    self.parent = Show;
    self.el     = el;

    self.showing = null;
    self.fading  = null;

    // hide all but first show_element
    $(self.el).children().each(function(i, show_element) {
        if (i > 0)
        {
            $(show_element).hide();
        }
    });

    self.show = function (el, callback)
    {
        if( self.showing )
        {
            self.fading = self.showing;

            $(self.fading).animate(
                {opacity: 0},
                self.parent.options.animation_length,
                'linear',
                function ()
                {
                    $(self.fading).remove();
                }
            );
        }

        self.showing = el;
        $(self.el).append(self.showing);
        $(self.showing).show();

        $(self.showing).animate(
            {opacity: 1},
            self.parent.options.animation_length,
            'linear',
            callback
        );
    }

    self.show_without_animation = function (el)
    {
        if( self.showing )
        {
            self.fading = self.showing;
            $(self.fading).css({ opacity : 0 });
            $(self.fading).remove();
        }

        self.showing = el;
        $(self.el).append(self.showing);
        $(self.showing).show();
        $(self.showing).css({ opacity : 1 });
    }
}


/*
 * $Log: show.js,v $
 * Revision 1.4  2009/07/16 21:49:16  gschwart
 * added multiple "viewport" functionality... lets the slideshow show in multiple areas
 *
 * also divided some logic up for the sake of Common Sense (the pamphlet)
 *
 * Revision 1.3  2009/05/28 22:10:25  gschwart
 * you guys all suck
 *
 * Revision 1.2  2009/05/28 22:08:59  gschwart
 * added log stuff
 *
 */

