/**
 * Moonbox: The lightbox that doesn't suck.
 * ----------------------------------------------------------------------------
 * copyright (c) 2007, Woody Gilk (http://moonbox.googlecode.com)
 *
 * 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 Moonbox nor the names of its 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($){
// Moonbox object
$.Moonbox = {
    loaded:   false, // i haz loaded?
    visible:  false, // i are hiding?
    settings: {},    // Moonbox settings
    box: { // Box object caches
        overlay: false,
        wrapper: false,
        image:   false,
        bottom:  false,
        caption: false
    },
    preload: { // Preload objects
        open: false,
        next: false,
        prev: false
    },
    anchors: {}, // Triggering anchors
    images:  [], // Current image set
    current: 0,  // Current image index
    step:    -1, // Effects step
    init: function(options){
        if ($.Moonbox.loaded == false){
            // Make sure that we have valid anchors
            if (($.Moonbox.anchors = $('a[@rel^=lightbox]')).length < 1) return false;
            // Extend defaults with user options
            $.Moonbox.settings = $.extend({
                initialWidth:   300,
                initialHeight:  150,
                resizeDuration: 200,
                resizeEasing:   'linear',
                animateCaption: true,
                showCounter:    true
            }, options || {});
            // Add lightbox overlay and wrapper into the DOM
            $('body').append(
                '<div id="moonBox_overlay"></div>' +
                '<div id="moonBox_wrapper">' +
                    '<div id="moonBox_loading"></div>' +
                    '<div id="moonBox_image">' +
                        '<a id="moonBox_prev" href="#mbPrev">Prev</a>' +
                        '<a id="moonBox_next" href="#mbNext">Next</a>' +
                    '</div>' +
                    '<div id="moonBox_bottom">' +
                        '<a id="moonBox_close" href="#mbClose">Close</a>' +
                        '<div id="moonBox_caption"></div>' +
                        '<div id="moonBox_number"></div>' +
                        '<div class="moonBox_clear"></div>' +
                    '</div>' +
                '</div>'
            );
            // Cache our two main objects so that we don't have to keep querying for them
            $.Moonbox.box.wrapper   = $('#moonBox_wrapper');
            $.Moonbox.box.overlay   = $('#moonBox_overlay');
            $.Moonbox.box.loading   = $('#moonBox_loading', $.Moonbox.box.wrapper);
            $.Moonbox.box.image     = $('#moonBox_image',   $.Moonbox.box.wrapper);
            $.Moonbox.box.bottom    = $('#moonBox_bottom',  $.Moonbox.box.wrapper);
            $.Moonbox.box.caption   = $('#moonBox_caption', $.Moonbox.box.bottom);
            $.Moonbox.box.number    = $('#moonBox_number',  $.Moonbox.box.bottom);
            $.Moonbox.box.closelink = $('#moonBox_close',   $.Moonbox.box.bottom);
            $.Moonbox.box.prevlink  = $('#moonBox_prev',    $.Moonbox.box.image);
            $.Moonbox.box.nextlink  = $('#moonBox_next',    $.Moonbox.box.image);
            // Set the default width and height on the wrapper
            $.Moonbox.box.wrapper.width($.Moonbox.settings.initialWidth);
            $.Moonbox.box.image.height($.Moonbox.settings.initialHeight);
            // Setup preloading images
            $.Moonbox.preload.open = $('<img>').css({position: 'absolute', top: '-2000em'}).appendTo('body');
            $.Moonbox.preload.next = $.Moonbox.preload.open.clone();
            $.Moonbox.preload.prev = $.Moonbox.preload.open.clone();
            // Bind window resizing and scrolling
            $(window).resize($.Moonbox.position).scroll($.Moonbox.position);
            // Set wrapper position
            $.Moonbox.box.wrapper.css('margin-left', -($.Moonbox.settings.initialWidth/2));
            // Make sure that IE will properly clear the things it needs to
            if ($.browser.msie) $('#moonBox_clear', $.Moonbox.box.bottom).css('zoom', 1);
            // Close Moonbox when clicking on overlay
            $.Moonbox.box.overlay.click($.Moonbox.close);
            // Bind previous, next, and close links
            $.Moonbox.box.nextlink.click($.Moonbox.next);
            $.Moonbox.box.prevlink.click($.Moonbox.prev)
            $.Moonbox.box.closelink.click($.Moonbox.close);
            // Bind hovering to previous and next links
            $('#moonBox_prev, #moonBox_next').css('opacity', 0).hover(function(){
                $(this).css('opacity', 1);
            }, function(){
                $(this).css('opacity', 0);
            });
            // Find all lightbox links and bind
            $.Moonbox.anchors.each(function(){
                $(this).click($.Moonbox.click);
            });
            // i iz loaded!
            $.Moonbox.loaded = true;
        }
    },
    show: function(url, title){
        // Display the given image
        $.Moonbox.images  = [[url, title]];
        $.Moonbox.current = 0;
        return $.Moonbox.open();
    },
    click: function(){
        if (!$.Moonbox.loaded) return false;
        // Not part of a set, just show the image
        if (this.rel.length == 8) return $.Moonbox.show(this.href, this.title);
        // The source of clicked link
        var clicked = this.href;
        // Prepare the image set
        $.Moonbox.images = [];
        $.Moonbox.anchors.filter('a[@rel="'+ this.rel +'"]').each(function(index){
            $.Moonbox.images.push([this.href, this.title]);
            if (clicked == this.href) $.Moonbox.current = index;
        });
        // Open that image!
        return $.Moonbox.open();
    },
    open: function(){
        // Make sure we have a valid set
        if ($.Moonbox.images.length < 1 || $.Moonbox.current > $.Moonbox.images.length) return false;
        // Prepare Moonbox
        $.Moonbox.position();
        $.Moonbox.setup(true);
        // Display that image!
        return $.Moonbox.change();
    },
    change: function(){
        $.Moonbox.step = 1;
        // Hide the current image
        $.Moonbox.box.image.css('opacity', 0);
        $.Moonbox.box.nextlink.css('display', 'none');
        $.Moonbox.box.prevlink.css('display', 'none');
        $.Moonbox.box.bottom.hide();
        // Show loading
        $.Moonbox.box.loading.show();
        // Setup preloading image
        $.Moonbox.preload.open.remove();
        $.Moonbox.preload.open = $('<img>').css({position: 'absolute', top: '-2000em'}).appendTo('body').load($.Moonbox.effects);
        // Start preloading
        $.Moonbox.preload.open.attr('src', $.Moonbox.images[$.Moonbox.current][0]);
        return false;
    },
    effects: function(){
        switch($.Moonbox.step){
            case 1:
                // Hide loading
                $.Moonbox.box.loading.hide();
                // Hide the image while showing it
                $.Moonbox.box.image.css('background-image', 'url('+ $.Moonbox.images[$.Moonbox.current][0] +')');
                // Animate width
                $.Moonbox.box.wrapper.animate({
                    width: $.Moonbox.preload.open.width(),
                    marginLeft: -($.Moonbox.preload.open.width()/2)
                }, $.Moonbox.settings.resizeDuration, $.Moonbox.settings.resizeEasing, $.Moonbox.effects);
                // Next step
                $.Moonbox.step++;
                // Set caption
                $.Moonbox.box.caption.html($.Moonbox.images[$.Moonbox.current][1] || '');
                $.Moonbox.box.number.html(($.Moonbox.settings.showCounter && ($.Moonbox.images.length > 1) ? 'Image '+ ($.Moonbox.current+1) +' of '+ $.Moonbox.images.length : ''));
                // Start next/prev preloading
                $.Moonbox.preload.next.src = (($.Moonbox.images.length - 1) != $.Moonbox.current)
                    ? $.Moonbox.images[$.Moonbox.current + 1] : '';
                $.Moonbox.preload.prev.src = ($.Moonbox.current)
                    ? $.Moonbox.images[$.Moonbox.current - 1] : '';
            break;
            case 2:
                // Animate height
                $.Moonbox.box.image.css('width', $.Moonbox.preload.open.width()).animate({
                    height: $.Moonbox.preload.open.height()
                }, $.Moonbox.settings.resizeDuration, $.Moonbox.settings.resizeEasing, $.Moonbox.effects);
                // Next step
                $.Moonbox.step++;
            break;
            case 3:
                // Display the image
                $.Moonbox.box.image.animate({
                    opacity: 1
                }, $.Moonbox.settings.resizeDuration, $.Moonbox.settings.resizeEasing, $.Moonbox.effects);
                // Next step
                $.Moonbox.step++;
                // Reset next/prev link heights
                $.Moonbox.box.nextlink.css('height', $.Moonbox.preload.open.height());
                $.Moonbox.box.prevlink.css('height', $.Moonbox.preload.open.height());
                // Show the bottom
                if ($.Moonbox.settings.animateCaption) $.Moonbox.box.bottom.slideDown($.Moonbox.settings.resizeDuration)
                else $.Moonbox.box.bottom.show();
            break;
            case 4:
                // Show prev/next buttons
                if ($.Moonbox.preload.next.src) $.Moonbox.box.nextlink.css('display', 'block');
                if ($.Moonbox.preload.prev.src) $.Moonbox.box.prevlink.css('display', 'block');
            break;
        }
    },
    next: function(){
        $.Moonbox.current++;
        return $.Moonbox.change();
    },
    prev: function(){
        $.Moonbox.current--;
        return $.Moonbox.change();
    },
    close: function(){
        if ($.Moonbox.loaded && $.Moonbox.step > -1){
            // Hide wrapper, then overlay
            $.Moonbox.box.wrapper.hide();
            $.Moonbox.box.overlay.fadeTo(500, 0, function(){
                $.Moonbox.box.overlay.css('display', 'none');
            });
            $.Moonbox.step = -1;
        }
        $.Moonbox.showMovieObjects(false);
        return false;
    },
    showMovieObjects: function(show){
        // Hide objects that could cause improper rendering
        ($.browser.msie ? $('object, select') : $('object, embed')).each(function(){
            var object = $(this)
            if (show) object.moon_visbility = object.css('visibility');
            object.css('visibility', (show ? 'hidden' : 'visible'));
        });
    },
    setup: function(open){
        // Hide objects that could cause improper rendering
        $.Moonbox.showMovieObjects(true);
        // Set the top of the wrapper
        $.Moonbox.box.wrapper.css('top', $(window).scrollTop() + ($(window).height() / 15));
        // Show Moonbox
        if ($.Moonbox.step == -1){
            // Show overlay, then wrapper
            $.Moonbox.box.overlay.css({'opacity': 0, 'display': 'block'}).fadeTo(500, 0.9, function(){
                $.Moonbox.box.wrapper.show();
            });
        }
        $.Moonbox.step = 0;
    },
    position: function(){
        // Reset the position of the overlay
        $.Moonbox.box.overlay.css({
            top:    $(window).scrollTop(),
            height: $(window).height(),
            width:  $(window).width()
        });
    }
};
// Initialize Moonbox!
$(document).ready($.Moonbox.init);
})(jQuery);
