// Overlay box
// David Michon / Stephen Band
//
// Depends on the html:
// <div id="shade">
//     semi-opaque layer
// </div>
// <div id="loading">
//     loading message or background image
// </div>
// <div id="overlay">
//     <div>
//         <div class="content">
//             html content of overlay box inserted here
//         </div>
//     </div>
// </div>

// called with:
// $("element").overlay({url: 'self', successCallback: function});
 
(function($) {

$.fn.overlay = function(options) {
     
    // Options
    var options = $.extend({
        shade: $("#screen_layer"),
        overlay: $("#overlay_layer"),
        content: $("#overlay_layer div.content"),
        loading: $("#loading"),
        openDur: 400,
        closeDur: 600,
        closeClass: ".close, .cancel",
        css: false
    }, options);
     
    return this.each(function() {
        
        // VAR
        
        var obj = $(this);
        var is_loaded = false;
    
        // FUNCTIONS
        
        // Get contents of url
        function get_content(url, param, callback) {
            $.get(url, param, callback, 'html');
        }
         
        // Fill the box div
        function set_content(html) {
            if (typeof(html)==="string")        {options.content.html(html);}
            else if (typeof(html)==="object")   {options.content.empty().prepend(html);}
            showOverlay();
            is_loaded = true;
            bind_submit_event();
        }

        // Makes forms in the box validate on submit
        function bind_submit_event() {
            options.content.find('form').bind('submit', function() {
                $(this).ajaxSubmit({
                    success : is_form_valid
                });
                return false;
            });
        }

        // Validate form         
        function is_form_valid(html) {
            if (($('.errorlist',$(html)).length + $('.form-error-header',$(html)).length) > 0) {
                set_content(html);
            } else {
                if (options.successCallback) {
                    options.successCallback();
                }
                hideOverlay();
            }
        }

        // Show and hide overlay
        function showShade() {
            options.shade
                .animate({opacity: "show"}, options.openDur*2, function(){
                    if (!is_loaded) {
                        options.loading
                            .animate({opacity: 'show'}, 400);
                    };
                })
                .bind("click", hideOverlay);            
        }
        
        function showOverlay() {
            if (options.css) {
                options.overlay
                    .children()
                    .css(options.css);
            }
            options.loading
                .animate({opacity: 'hide'}, 200);
            options.overlay
                .animate({opacity: 'show'}, options.openDur)
                .bind('click', function(e) {
                    // Interrogate event to see if it really comes from the overlay, not the overlay box
                    // FIND A BETTER WAY TO TEST EQUALITY
                    if (jQuery(e.target).attr("id") == "overlay_layer") hideOverlay();
                })
                .find(options.closeClass)
                .bind('click', hideOverlay);
        }
        
        function hideOverlay() {
            options.loading
                .stop(true)
                .animate({opacity: 'hide'}, 200);
            options.shade
                .stop(true)
                .animate({opacity: 'hide'}, options.closeDur*0.75)
                .unbind('click');
            options.overlay
                //.stop(true)
                .animate({opacity: 'hide'}, options.closeDur, function(){ options.content.html(""); })
                .unbind('click');
        }
        
        // RUN
        
        obj.click(function() {
            
            is_loaded = false;
            
            
            if (options.html || options.elem) {
                set_content(options.html || options.elem);                
            }
            else if (options.html===false) {
                set_content(false);
            }
            else {
                // Gets the url of the <a> tag, or uses the url passed in options
                if (options.url == 'self') {
                    var url = $(this).attr('href');
                } else {
                    var url = options.url;
                }
                
                // Gets the content at that url          
                get_content(url, {}, set_content);
            }                
            
            // Start the shade layer
            showShade();

            return false;
        });
    });
};

})(jQuery);
