﻿/*
MiMo
The Midway Modal window manager.
v. 1.1.0
Jared Carlow
2009.09.17

Focused on being totally lightweight, inspired by Greybox Redux: 
http://jquery.com/demo/grey/

It's easy to use. If you want a link to open in a MiMo box instead of going to a
new page, just give the link the class which you will base your MiMo initializer on.
For example, if I have a link like this:
<a href="http://www.example.com" class="mimoLink">Some link text</a>

Then MiMo can be called thus (when page is DOM ready):
jQuery(function(){
    jQuery('.mimoLink').mimo();
}); 

That's it. If JavaScript isn't firing - no harm done. The link will go to the page
normally. If JavaScript is availabe, a semi-transparent curtain overlay will cover the page
and the href source of the link will open in an iFrame centered on the page. Centering
will persist through resizes and scrolls. Clicking anywhere outside the MiMo window on the
page (curtain) will close the MiMo window, as will clicking on the close control.

*/

(function($){
    // Private
    var mimoH = 0;
    var mimoW = 0;
    var opts = {};

    $.fn.mimo = function(options){
        // Update options if any are provided
        opts = $.extend({}, $.fn.mimo.defaults, options);
        
        return this.each(function (){
            if ($(this).is('a'))
            {
                // Attach click behavior
                $(this).click(function (){
                    var href = $(this).attr("href");
                    loadMimo(href);
                    return false;
                });
            }
        });
    };
    
    $.fn.mimoDirect = function(href, options)
    {
        opts = $.extend({},$.fn.mimo.defaults, options);
        if (undefined != href && '' != href)
        {
            loadMimo(href);
            return false;
        }
        return true;
    };
    
    // Set MiMo windows height with consideration that it needs to be at least
    // edgeThreshold px smaller in both directions than the window to preserve click off window
    // to close space
    function setHeightWidth(){
        mimoH = Math.min(opts.height, $(window).height() - opts.edgeThreshold);
        mimoW = Math.min(opts.width, $(window).width() - opts.edgeThreshold);
    };
    
    // Determine position relative to window size and MiMo size
    function calculatePosition(){
        // [Re]calculate height and width of MiMo
        setHeightWidth();
        // Center accordingly
        $('#' + opts.classPrefix + 'ContentWindowFrame').css({
            'height': mimoH,
            'width': mimoW,
            'position': 'absolute',
            'top': Math.floor((($(window).height() - mimoH)/2) + $(document).scrollTop()) + 'px',
            'left': Math.floor(($(window).width() - mimoW)/2) + 'px',
            'z-index': '999999'
        });
        $('#' + opts.classPrefix + 'Content').css({
            'height':$('#' + opts.classPrefix + 'ContentWindowFrame').height() - $('#' + opts.classPrefix + 'CloseControl').height(),
            'width':$('#' + opts.classPrefix + 'ContentWindowFrame').width()
        });
    };
    
    // Create HTML for new window and curtain overlay
    function loadMimo(href){
        addOverlay();
        addMimoWindow(href);
    };
    
    // Overlay curtain
    function addOverlay(){
        // Create overlay if it doesn't exist yet
        if ($('#'+ opts.classPrefix + 'CurtainOverlay').length < 1)
        {
            $(document.body).append('<div id="'+ opts.classPrefix + 'CurtainOverlay"></div>');
            // Add click event
            $('#'+ opts.classPrefix + 'CurtainOverlay').click(clearMimo);
        }
        
        // Set styles - useful when resizing too (ergo the above check if overlay exists)
        $('#'+ opts.classPrefix + 'CurtainOverlay').css({
            'position': "absolute",
            'top':0,
            'left': 0,
            'height': $(document).height(),
            'width': $(window).width(),
            'background': opts.baseBgColor, 
            'opacity': opts.bgOpacity, 
            'moz-opacity': opts.bgOpacity, 
            'filter': 'alpha(opacity='+ (100 * opts.bgOpacity) +')',
            'z-index': '999999'
        });
    };
    
    function addMimoWindow(href)
    {
        // Set up container with close control
        $(document.body).append('<div id="'+ opts.classPrefix + 'ContentWindowFrame"><div id="'+ opts.classPrefix + 'CloseControl"><span>Close</span></div></div>');
        
        // Add close control behavior
        $('#' + opts.classPrefix + 'CloseControl').click(clearMimo);
        $('#' + opts.classPrefix + 'CloseControl').css({'cursor':'pointer'});
        $(window).resize(function (){
            if ($('#'+ opts.classPrefix + 'ContentWindowFrame').length > 0)
            {
                calculatePosition();
                addOverlay();
            }
        });
        $(window).scroll(function (){
            if ($('#'+ opts.classPrefix + 'ContentWindowFrame').length > 0)
            {
                calculatePosition();
                addOverlay();
            }
        });
        // Add IFrame with content
        $('#' + opts.classPrefix + 'ContentWindowFrame').append('<iframe id="' + opts.classPrefix + 'Content" src="' + href + '"></iframe>');
        // Size appropriately
        calculatePosition();
    };
    
    function clearMimo(){
        // Clear event handlers
        $('#'+ opts.classPrefix + 'CurtainOverlay').unbind();
        $('#' + opts.classPrefix + 'CloseControl').unbind();
        
        // Remove elements
        $('#' + opts.classPrefix + 'CurtainOverlay').remove();
        $('#' + opts.classPrefix + 'ContentWindowFrame').remove();
    };
    
    // Defaults
    $.fn.mimo.defaults = {
        baseBgColor: "#000",
        bgOpacity: .75,
        classPrefix: "mimo_",
        height: 450,
        width: 500,
        edgeThreshold: 20
    };
})(jQuery);