/* $Id: overlay.js,v 1.6 2008/05/28 08:28:20 lsa Exp $ */

(function ($, options) {

var AJAXOverlay = $.createOverlay = function (options) {
    return new AJAXOverlay.prototype.init(options || {});
}

var genIdSeed = 0;

var globalOptions = {

    LAYER_CLASS_NAME: 'overlay-layer',

    LAYER_ID: 'overlay_layer',

    IFRAME_CLASS_NAME: 'overlay-iframe',

    IFRAME_ID: 'overlay_iframe',

    LAYER_CONTENT_CLASS_NAME: 'overlay-layer-content',

    AUTO_SHOW: true,

    HANDLE_RESIZE_WINDOW: false,

    genId: function (prefix) {
        return prefix + '_' + (++genIdSeed);
    }

}

$.extend(globalOptions, options || {});

AJAXOverlay.prototype = {

    target: null,

    layerId: null,

    iframeId: null,


    onCreate: null,

    onShow: null,

    onHide: null,

    onResize: null,

    onRemove: null,


    layer: null,

    iframe: null,


    init: function (options) {
        $.extend(this, globalOptions, options);

        this.target = $(this.target);
        if (this.target.length == 0) {
            this.target = $('body');
        }

        this.layer = $('<div></div>')
            .attr('id', this.layerId && (typeof this.index == 'undefined')
                ? this.layerId : this.genId(this.LAYER_ID))
            .addClass(this.LAYER_CLASS_NAME)
            .hide()
            .appendTo('body');

        if (this.LAYER_CONTENT_CLASS_NAME) {
            $('.' + this.LAYER_CONTENT_CLASS_NAME).clone().appendTo(this.layer);
        }

        if ($.browser.msie && ($.browser.version < 7)) {
            this.iframe = $('<iframe src="javascript:false;"></iframe>')
                .attr('id', this.iframeId && (typeof this.index == 'undefined')
                    ? this.iframeId : this.genId(this.IFRAME_ID))
                .css({ opacity: 0 })
                .addClass(this.IFRAME_CLASS_NAME)
                .hide()
                .appendTo('body');
        }


        this.layer.bind('create', { overlay: this }, this.createHandler);
        this.layer.bind('show', { overlay: this }, this.showHandler);
        this.layer.bind('hide', { overlay: this }, this.hideHandler);
        this.layer.bind('remove', { overlay: this }, this.removeHandler);

        if (this.HANDLE_RESIZE_WINDOW) {
            jQuery(window).bind('resize', { overlay: this }, this.resizeHandler);
        }

        this.layer.trigger('create');

        if (this.AUTO_SHOW) {
            this.layer.trigger('show');
        }
    },

    createHandler: function (event) {
        var overlay = event.data.overlay;

        if (jQuery.isFunction(overlay.onShow)) {
            overlay.onShow.call(overlay);
        }
    },

    showHandler: function (event) {
        var overlay = event.data.overlay;

        if (!overlay.layer.is(':visible')) {

            if (!jQuery.isFunction(overlay.onShow) || jQuery.isFunction(overlay.onShow) && overlay.onShow.call(overlay)) {
                overlay.recalcPosition.apply(overlay);
                if (overlay.iframe) {
                    overlay.iframe.show();
                }
                overlay.layer.show();
            }
        }
    },

    recalcPosition: function() {
        if (this.target && this.target.is(':visible')) {
            var css = {
                position: 'absolute',
                top: this.target.offset({ relativeTo: jQuery(document) }).top,
                left: this.target.offset({ relativeTo: jQuery(document) }).left,
                width: this.target.outerWidth({ margin: false }),
                height: this.target.outerHeight({ margin: false })
            }

            if (this.iframe) {
                this.iframe.css(css);
            }

            css.top -= parseInt(this.layer.css('margin-top'));
            css.left -= parseInt(this.layer.css('margin-left'));

            if (jQuery.browser.msie) {
                css.width -= (this.layer.outerWidth({ margin: false }) - this.layer.innerWidth());
                css.height -= (this.layer.outerHeight({ margin: false }) - this.layer.innerHeight());
            }

            this.layer.css(css);
        }
    },

    hideHandler: function (event) {
        var overlay = event.data.overlay;

        if (overlay.layer.is(':visible')) {

            if (!jQuery.isFunction(overlay.onHide) || jQuery.isFunction(overlay.onHide) && overlay.onHide.call(overlay)) {

                overlay.layer.hide();
                if (overlay.iframe) {
                    overlay.iframe.hide();
                }

            }
        }
    },

    resizeHandler: function (event) {
        var overlay = event.data.overlay;

        if (!jQuery.isFunction(overlay.onResize) || jQuery.isFunction(overlay.onResize) && overlay.onResize.call(overlay)) {
            if (overlay.layer.is(':visible')) {
                overlay.recalcPosition.call(overlay);
            }
        }
    },

    removeHandler: function (event) {
        var overlay = event.data.overlay;

        if (!jQuery.isFunction(overlay.onRemove) || jQuery.isFunction(overlay.onRemove) && overlay.onRemove.call(overlay)) {
            overlay.layer.trigger('hide');

            if (overlay.HANDLE_RESIZE_WINDOW) {
                jQuery(window).unbind('resize', overlay.resizeHandler);
            }

            if (overlay.iframe) {
                overlay.iframe.remove();
            }
            if (overlay.layer) {
                overlay.layer.remove();
            }
        }
    },

    show: function () {
        this.layer.trigger('show');
    },

    hide: function () {
        this.layer.trigger('hide');
    },

    remove: function () {
        this.layer.trigger('remove');
    }

}

AJAXOverlay.prototype.init.prototype = AJAXOverlay.prototype;

$.fn.extend({
    createOverlay: function (options) {
        var result = new Array();

        this.each( function (i, element) {
            result.push($.createOverlay($.extend({}, options, { target: this, index: i })));
        });

        $.extend(result, {
            remove: function() {
                var self = this;

                $j(self).each(function (i) {
                    this.remove();
                    self[i] = void(0);
                });

                self.length = 0;
            }
        });

        return result;
    }
});

})(jQuery, typeof GLOB_OVERLAY_PROPS != 'undefined' ? GLOB_OVERLAY_PROPS : {});
