(function($){
    var defaultOptions = {
        closeOnClick: true,
        modalProperties: {},
        curtainProperties: false,
        contentProperties: {},
        spacerProperties: {},
        modalContainer: "body"
    };

    $.modal = function(options) {
        $.extend(defaultOptions, options);
    };

    $.modalClose = function() {
        $(defaultOptions.modalContainer + " > div[_modal]").modalClose();
    };

    $.fn.modal = function(options) {
        if (!this.length) return;

        options = $.extend({}, defaultOptions, options);
        setOverflow("hidden");
        var content;
        if (options.contentProperties) {
            content = $("<div/>", options.contentProperties).append(this);
        } else {
            content = this;
        }
        content = $("<div/>", options.spacerProperties).append(content).css(spacerStyle);
        if (options.closeOnClick) content.bind("click", clickHandler);

        var modal = $("<div/>", options.modalProperties);
        modal.attr("_modal", "modal");
        if (options.curtainProperties) {
            var curtain = $("<div/>", options.curtainProperties).css(spacerStyle);
            if (options.closeOnClick) curtain.bind("click", clickHandler);
            modal.append(curtain);
        }
        modal.append(content).css(modalStyle);
        $(defaultOptions.modalContainer).append(modal);
        this.trigger("modalopen");
        return this;
    };

    $.fn.modalClose = function() {
        this.parents("div[_modal]").andSelf().remove();
        if (!$(defaultOptions.modalContainer + " > div[_modal]").length) setOverflow("auto");
        return this;
    };

    function setOverflow(value) {
        var html = $("html");
        var t = html.scrollTop();
        var l = html.scrollLeft();
        html.css("overflow", value).scrollTop(t).scrollLeft(l);
    }

    function clickHandler(e){
        if (e.target === this) {
            $(e.target).modalClose();
            return false;
        }
    }

    var modalStyle = {
        position: "fixed", top: 0, left: 0, right: 0, bottom: 0
    };

    var spacerStyle = {
        position: "absolute", top: 0, left: 0, width: "100%", height: "100%"
    };
})(jQuery);
