/**
 * zdialog for jQuery
 * Zimride wrapper for jQuery.dialog()
 * serves as a near drop-in replacement for Facebox
 *
 * Usage
 * -----
 * Can be used as a click event or programmatically
 * For explanations of settings, see jQuery.dialog() documentation
 * http://docs.jquery.com/UI/Dialog
 *
 * Examples
 * --------
 *
 *  Click event, 1 popup on a page:
 *
 *  $(document).ready(function() {
 *    $('a.info').zdialog();
 *  });
 *
 *  <a href="#hiddenDiv" class="info">Info</a>
 *    Loads the contents of the element #hiddenDiv in the dialog with default options
 *
 *  <a href="page.html" class="info">Info</a>
 *    Loads the page.html page in the dialog with default options
 *
 *  <a href="page.png" class="info">Info</a>
 *    Loads page.png image in the dialog with default options
 *
 *  Click event, 2 different style popups on a page:
 *
 *  $(document).ready(function() {
 *    $('a.page').zdialog({
 *      buttons: [
 *          {text: "OK", className:"confirm", click: function() {
 *              //do something here
 *              }
 *          }]
 *    });
 *
 *    $('a.confirm').zdialog({
 *      buttons: [
 *          {text: "OK", className:"confirm", click: function() {
 *              //do something here
 *              }
 *          },
 *          {text: "Cancel", click: function() {
 *              $(this).dialog('close');
 *              }
 *          }]
 *    });
 *  });
 *
 *  <a href="page.html" class="page">Info</a>
 *    Loads the page.html page in the dialog with 1 button
 *
 *  <a href="confirm.html" class="confirm">Confirm</a>
 *    Loads the confirm.html page in the dialog with 2 buttons
 *
 *
 *  Programmatically
 *  $.zdialog({ajax: 'http://www.zimride.com/terms' });
 *    Loads the contents of http://www.zimride.com/terms in the dialog
 *
 *  $.zdialog({image: 'http://www.zimride.com/images/car.png' });
 *    Loads the image http://www.zimride.com/images/car.png in the dialog
 *
 *  $.zdialog({id: '#hiddenDiv' });
 *    Loads the element #hiddenDiv in the dialog
 *
 *  $.zdialog({html: '<p>Display Me!</p>'});
 *    Loads the entered HTML in the dialog
 *
 *  $.zdialog('<p>Display Me!</p>');
 *    Loads the entered HTML in the dialog
 *
 *
 *  Utility functions
 *  $.zdialog.closeAll()
 *    Closes all zdialog windows
 *    
 *  $.zdialog.loading()
 *    Creates a new dialog object with a loading image and returns the new object
 */

(function( $ ){

    $.fn.zdialog = function(settings) {
        var mySrc, dialogEle, event;
        
        if (!settings) {
            settings = {};
        }
        
        if (settings.id) {
            dialogEle = fillFromId(settings.id, settings);
        } else if (settings.ajax) {
            dialogEle = fillFromAjax(settings.ajax, settings);
        } else if (settings.image) {
            dialogEle = fillFromImage(settings.image, settings);
        } else if (settings.html) {
            dialogEle = fillFromHTML(settings.html, settings);
        } else if (this.attr('href')) {
            dialogEle = fillFromHref(this.attr('href'), settings);
        } else {
            // keep chaining working even with bad settings
            return this;
        }
        
        if ( !dialogEle ) {
            return this;
        }
        
        function clickHandler() { 
            var data = dialogEle.data('zdialog');
            $.extend(data, {caller: $(this)});
            dialogEle.data('zdialog', data);
            dialogEle.dialog('open');
            return false;
        }
        
        if (settings.eventNamespace) {
            event = 'click.' + settings.eventNamespace;
        } else {
            event = 'click';
        }
        
        return this.bind( event, settings, clickHandler );
    }

    $.zdialog = function(data) {
        if(!data) {
            return false;
        }
        
        var dialogEle, settings = {};
        
        if($.isPlainObject(data)) {
            settings = data;
        } 
        
        if (data.ajax) {
            dialogEle = fillFromAjax(data.ajax, settings);
        }
        else if (data.image) {
            dialogEle = fillFromImage(data.image, settings);
        }
        else if (data.id) {
            dialogEle = fillFromId(data.id, settings);
        }
        else if (data.html) {
            dialogEle = fillFromHTML(data.html, settings);
        }
        else {  
            dialogEle = fillFromHTML(data, settings);            
        }
        
        if (dialogEle) {
            dialogEle.dialog('open');
            return dialogEle;
        } else {
            return false;
        }
    }

    $.extend($.zdialog, {
        settings: {
            loadingImg: '/images/ajax-loader.gif',
            autoOpen: false,
            buttons: [],
            closeOnEscape: true,
            closeText: '×',
            dialogClass: '',
            hide: 'fade',
            modal: true,
            show: 'fade',
            width: 'auto'
        },
        closeAll: function() {
            $('.zdialog').dialog('close');
        },
        loading: function (settings) {
            var ele = fillFromLoadingImage(settings);
            ele.dialog('open');
            return ele;
        }
    });
    
    function init(obj, settings) {
        var mySettings = obj.data('zdialog');
        if( !mySettings || !mySettings.init ) {
            mySettings = {};

            $.extend(mySettings, $.zdialog.settings);
            if($.isPlainObject(settings)) { 
                $.extend(mySettings, settings);
            }

            obj.dialog(mySettings);

            var preload = new Image();
            preload.src = $.zdialog.settings.loadingImg;
            
            mySettings.init = true;
            obj.data('zdialog', mySettings);
        }   
    
        return true;
    }
    
    function fillFromLoadingImage(settings) {
        var dialogEle = $('<div class="zdialog"><img class="loading" src="'+$.zdialog.settings.loadingImg+'" /></div>');
        init(dialogEle, settings);
        return dialogEle;
    }

    function fillFromAjax(url, settings) {
        var dialogEle = $('<div class="zdialog"><img class="loading" src="'+$.zdialog.settings.loadingImg+'" /></div>');
        init(dialogEle, settings);
        $.get(url, function(data) {
            dialogEle.children('img.loading').hide();
            dialogEle.append($(data)); 
        });
        return dialogEle;
    }
    
    function fillFromImage(img, settings) {
        var image = new Image();
        var dialogEle = $('<div class="zdialog"><img class="loading" src="'+$.zdialog.settings.loadingImg+'" /></div>');
        init(dialogEle, settings);
        image.onload = function() {
            dialogEle.children('img.loading').hide();
            dialogEle.append($(image));
        };
        image.src = img;
        return dialogEle;
    }
    
    function fillFromId(id, settings) {
        if(!id.match(/^#/)) id='#'+id;
        var dialogEle = $('<div class="zdialog"></div>');
        init(dialogEle, settings);
        $(id).removeClass('hidden').appendTo(dialogEle);
        return dialogEle;
    }

    function fillFromHref(href, settings) {
        if (href == '#') {
            return false;
        } else if (href.match(/#/)) { 
            // id
            var url    = window.location.href.split('#')[0];
            var target = href.replace(url,'');
            return fillFromId(target, settings);
        } else if (href.match(/\.png|\.gif|\.jpe?g/i)) {
            // image
            return fillFromImage(href, settings);
        } else {
            // ajax
            return fillFromAjax(href, settings);
        }
    }
    
    function fillFromHTML(html, settings) {
        var dialogEle = $('<div class="zdialog" />');
        init(dialogEle, settings);
        dialogEle.append($(html));
        return dialogEle;
    }

    // Extend uiDialog to position 'fixed' regardless of window scrolling
    var _position = $.ui.dialog.prototype._position;
    $.ui.dialog.prototype._position = function() {
        _position.apply(this, arguments);
        if (this.options.position && this.options.position[1] && this.options.position[1].constructor == Number) {
            this.uiDialog.css({top: this.options.position[1]});
        }
    };
    
})( jQuery );
