(function () {
    jQuery.extend(jQuery, {modalWindow: function (data, options) {
        var object = this;
        var remover = 0;

        object.options = $.extend({
            header: false,
            footer: false,

            opacity: 1,
            overlay: false,
            movable: false,

            windowId: 'modal-window',
            windowIdHeader: 'modal-window-header',
            windowIdClose: 'modal-window-close',
            windowIdContent: 'modal-window-content',
            windowIdFooter: 'modal-window-footer',
            windowIdOverlay: 'modal-overlay'
        }, options);

        object.getPageHeight = function getPageHeight () {
            var windowHeight;

            if (window.innerHeight) {
                windowHeight = window.innerHeight;
            } else if (document.documentElement && document.documentElement.clientHeight) {
                windowHeight = document.documentElement.clientHeight;
            } else if (document.body) {
                windowHeight = document.body.clientHeight;
            }

            return windowHeight;
        };

        object.getPageScroll = function getPageScroll () {
            var xScroll, yScroll;

            if (self.pageYOffset) {
                yScroll = self.pageYOffset;
                xScroll = self.pageXOffset;
            } else if (document.documentElement && document.documentElement.scrollTop) {
                yScroll = document.documentElement.scrollTop;
                xScroll = document.documentElement.scrollLeft;
            } else if (document.body) {
                yScroll = document.body.scrollTop;
                xScroll = document.body.scrollLeft;
            }

            return [xScroll, yScroll];
        };

        object.setOverlay = function setOverlay () {
            if (true === object.options.overlay) {
                object.windowOverlay = $('<div id="' + object.options.windowIdOverlay + '" />');

                $(object.windowOverlay).animate({opacity: object.options.opacity}, 1, function () {
                    $('body').append(object.windowOverlay);

                    object.windowOverlayWidth = $(object.windowOverlay).width();
                    object.windowOverlayHeight = $(object.windowOverlay).height();

                    if (object.pageHeight > object.windowOverlayHeight) {
                        $(object.windowOverlay).height(object.pageHeight);

                        object.windowOverlayHeight = $(object.windowOverlay).height();
                    }
                });
            }
        };

        object.setWindow = function setWindow () {
            object.windowContainer = $('<div id="' + object.options.windowId + '" />');
            object.windowClose = $('<div id="' + object.options.windowIdClose + '" />');
            object.windowHeader = $('<div id="' + object.options.windowIdHeader + '" />');
            object.windowContent = $('<div id="' + object.options.windowIdContent + '" />');
            object.windowFooter = $('<div id="' + object.options.windowIdFooter + '" />');

            $(object.windowHeader).append(object.windowClose);

            if (true === object.options.header) {
                $(object.windowHeader).append(data.header);
                $(object.windowContainer).append(object.windowHeader);
            }

            $(object.windowContent).append(('string' === typeof data ? data : data.content));
            $(object.windowContainer).append(object.windowContent);

            if (true === object.options.footer) {
                $(object.windowFooter).append(data.footer);
                $(object.windowContainer).append(object.windowFooter);
            }

            $('body').append(object.windowContainer);

            $(object.windowContent).append(data);
        };

        object.setWindowCloseEvent = function setWindowCloseEvent () {
            $(document).bind('modal-window.close', function () {
                $(document).unbind('keydown');
                $(object.windowOverlay).unbind('click');

                $(object.windowOverlay).remove();
                $(object.windowContainer).remove();
            });

            $(object.windowClose).click(function(e) {
                $(document).trigger('modal-window.close');
            });

            $(object.windowOverlay).click(function(e) {
                $(document).trigger('modal-window.close');
            });

            $(document).keydown(function(e) {
                if (27 === e.keyCode) {
                    $(document).trigger('modal-window.close');
                }
            });
        };

        object.setWindowToCenter = function setWindowToCenter () {
            object.windowContainerWidth = $(object.windowContainer).outerWidth();
            object.windowContainerHeight = $(object.windowContainer).outerHeight();

            $(object.windowContainer).hide().css({
                top: (object.pageScroll + (object.pageHeight - object.windowContainerHeight) / 2),
                left: (($(document).width() - object.windowContainerWidth) / 2)
            }).fadeIn();

            $(window).resize(function () {
                object.pageHeight = object.getPageHeight();
                object.pageScroll = object.getPageScroll()[1];

                object.setWindowToCenter();
            });
        };

        object.makeWindowMovable = function makeWindowMovable () {
            if (true === object.options.header && true === object.options.movable) {
                $(object.windowHeader).css({cursor: 'move'});

                $(object.windowHeader).bind('mousedown', function (eDown) {
                    var windowContainerTop = $(object.windowContainer).offset().top;
                    var windowContainerLeft = $(object.windowContainer).offset().left;

                    $(object.windowContainer).bind('mousemove', function (eMove) {
                        eMove.preventDefault();

                        newPositionY = windowContainerTop + (eMove.pageY - eDown.pageY);
                        newPositionX = windowContainerLeft + (eMove.pageX - eDown.pageX);

                        if (0 > newPositionX) {
                            newPositionX = 0;
                        } else if (object.windowOverlayWidth - object.windowContainerWidth < newPositionX) {
                            newPositionX = object.windowOverlayWidth - object.windowContainerWidth;
                        }

                        if (0 > newPositionY) {
                            newPositionY = 0;
                        } else if (object.windowOverlayHeight - object.windowContainerHeight < newPositionY) {
                            newPositionY = object.windowOverlayHeight - object.windowContainerHeight;
                        }

                        $(object.windowContainer).css({top: newPositionY, left: newPositionX});
                    });
                }).mouseup(function () {
                    $(object.windowContainer).unbind('mousemove');
                });
            }
        };

        $(document).trigger('modal-window.close');

        object.pageHeight = object.getPageHeight();
        object.pageScroll = object.getPageScroll()[1];

        object.setOverlay();

        object.setWindow();
        object.setWindowToCenter();
        object.setWindowCloseEvent();

        object.makeWindowMovable();

        return object;
    }});
})();
