﻿$(document).ready(function () {
    "use strict";

    $.fn.modalWindow = function (in_options) {

        var KEYCODE_ESC = 27,
            modal_window,
            modal_content,
            modal_close,
            modal_background,
            w = $(window),
            height = 0,
            width = 0,
            oldWidth = 0,
            oldHeight = 0,
            defaults = {
                id: 'modal-window',
                easing: '',
                html: '',
                url: '',
                js: '',
                data: '',
                theme: 'normal',
                openX: '0',
                openY: '0',
                onBeforeOpen: function () { },
                onOpen: function () { },
                onClose: function () { }
            },

            options = $.extend(defaults, in_options),


            calcPos = function (width, height) {

                var top = Math.max((w.height() - height) / 2, 0) + w.scrollTop(),
                    left = Math.max((w.width() - width) / 2, 0),
                    pos = {};

                if (top < 30) { top = 30; }


                pos.top = top;
                pos.left = left;

                return pos;
            },
            closewindow = function () {
                if (modal_window.data('open')) {
                    modal_window.removeClass(options.theme).data('open', false);

                    modal_close.remove();
                    modal_window.remove();
                    modal_background.remove();

                    options.onClose.call(modal_window[0]);
                }
            },
            createWindow = function () {
                if (modal_window !== undefined) {
                    modal_window.remove();
                }

                if (modal_close !== undefined) {
                    modal_close.remove();
                }

                modal_window = ($('#' + options.id).length) ? $('#' + options.id) : $('<div />')
		            .attr('id', options.id)
                    .addClass("modal-window")
                    .addClass(options.theme)
                    .css({
                        position: 'absolute',
                        display: 'none'
                    })
		            .data('open', false)
		            .appendTo('body');

                modal_content = ($('#' + options.id + '-content').length) ? $('#' + options.id + '-content') : $('<div />')
			        .attr('id', options.id + '-content')
                    .addClass("modal-window-content")
			        .appendTo(modal_window)
                    .css({ opacity: 0 });

                modal_close = ($('#' + options.id + '-close').length) ? $('#' + options.id + '-close') : $('<a />')
			        .attr('id', options.id + '-close')
                    .addClass("modal-window-close")
                    .css({
                        position: 'absolute',
                        display: 'none'
                    })
			        .prependTo('body')
                    .unbind('click').bind('click', function (e) {
                        closewindow();
                    });
            },

            createBackground = function () {
                modal_background = ($('#' + options.id + '-background').length) ? $('#' + options.id + '-background') : $('<div />')
			        .attr('id', options.id + '-background')
                    .css({
                        opacity: 0.5,
                        top: 0,
                        left: 0,
                        position: 'absolute',
                        width: $(document).width(),
                        height: $(document).height(),
                        display: 'none'
                    })
                    .addClass("modal-window-background")
			        .appendTo('body')
                    .unbind('click').bind('click', function (e) {
                        closewindow();
                    });
            },
            openwindow = function () {
                options.onBeforeOpen.call(modal_window[0]);

                if (width == 0)
                    width = modal_window.outerWidth();

                if (height == 0)
                    height = modal_window.outerHeight();

                var top = calcPos(width, height).top,
                    left = calcPos(width, height).left,
                    easing = options.easing,
                    animation = {},
                    oldTop,
                    oldLeft;

                if (oldWidth !== 0 && oldHeight !== 0) {
                    oldTop = Math.max((w.height() - oldHeight) / 2, 0) + w.scrollTop();
                    oldLeft = Math.max((w.width() - oldWidth) / 2, 0);
                    modal_window.css({ 'left': oldLeft, 'top': oldTop, 'width': oldWidth, 'height': oldHeight });
                    easing = "";
                    animation = {
                        left: left,
                        top: top,
                        height: height,
                        width: width
                    };

                } else {

                    modal_window.css({ 'opacity': 0, 'left': left + 50, 'top': top + 50, 'width': width - 100, 'height': height - 100 });
                    animation = {
                        opacity: 1,
                        left: left,
                        top: top,
                        height: height,
                        width: width
                    };
                }

                modal_background.css("zIndex", 999).fadeIn("fast");
                modal_window.css("zIndex", 1000).show().animate(animation,
                    {
                        duration: 'fast',
                        easing: easing,
                        complete: function () {
                            modal_content.animate({ opacity: 1 });
                            
                            var top = parseInt(modal_window.css("top").replace("px", ""), 10) - (modal_close.height() / 2),
                                left = (parseInt(modal_window.css("left").replace("px", ""), 10) + modal_window.width()) - (modal_close.width() / 2),
                                closeTop = top + parseInt(modal_close.css("top").replace("px", ""), 10),
                                closeLeft = left - parseInt(modal_close.css("right").replace("px", ""), 10);

                            modal_close.css("zIndex", 1001).css({
                                top: closeTop + "px",
                                left: closeLeft + "px"
                            }).fadeIn();

                            options.onOpen.call(modal_window[0]);
                        }
                    });

                modal_window.data('open', true);
            },
            loadData = function (opt) {


                if (opt.html !== '' && opt.html !== undefined) {
                    modal_content.html(options.html);
                    openwindow();
                } else if (opt.url !== '' && opt.url !== undefined) {

                    width = modal_window.outerWidth();
                    height = modal_window.outerHeight();

                    $.get(opt.url, opt.data, function (data) {
                        modal_content.html(data);
                        if (opt.js !== "" && opt.js !== undefined) {
                            $.getScript(opt.js, function () {
                                openwindow();
                            });
                        } else {
                            openwindow();
                        }
                    });

                } else {
                    openwindow();
                }
            },
            newcontent = function (opt) {
                width = 0;
                height = 0;

                oldWidth = modal_window.width();
                oldHeight = modal_window.height();

                createWindow();

                if (opt.id === undefined) {
                    modal_window.attr("id", "modal-window");
                } else {
                    modal_window.attr("id", opt.id);
                }

                loadData(opt);
            },

            addsize = function (i_width, i_height) {
                width = width + i_width;
                height = height + i_height;

                var top = calcPos(width, height).top,
                    left = calcPos(width, height).left;

                modal_window.css("zIndex", 1000).show().animate(
                    {
                        left: left,
                        top: top,
                        height: height,
                        width: width
                    },
                    {
                        duration: 'fast'
                        //easing: 'easeout'
                    }
                );
            },

            newsize = function (i_width, i_height) {
                width = i_width;
                height = i_height;

                var top = calcPos(width, height).top,
                    left = calcPos(width, height).left;

                modal_window.css("zIndex", 1000).show().animate(
                    {
                        left: left,
                        top: top,
                        height: height,
                        width: width
                    },
                    {
                        duration: 'fast'
                        //easing: 'easeout'
                    }
                );
            };



        createWindow();
        createBackground();

        loadData(options);

        $(document).keyup(function (e) {
            if (e.keyCode === KEYCODE_ESC) { closewindow(); }
        });

        return {
            closewindow: closewindow,
            addsize: addsize,
            newsize: newsize,
            newcontent: newcontent,
            width: width,
            height: height
        };
    };
});
