(function($) {

    $.window = {
        defaults: {
            id: null,
            url: null,
            loading: {type: 'window', loader: false},
            overlay: {},
            unblock: true,
            buttons: {},
            onBeforeOpen: function(window) {
                //console.debug('window.onBeforeOpen ', window, this);
                return true;
            },
            onOpen: function(window) {
                //console.debug('window.onOpen ', window, this);
                return true;
            },
            onBeforeClose: function(window) {
                //console.debug('window.onBeforeClose ', window, this);
                return true;
            },
            onClose: function(window) {
                //console.debug('window.onClose ', window, this);
                return true;
            },
            onOk: function(window, cmd) {
                return true;
            }
        }
    };

    $.fn.window = function(options) {
        return this.plugin('window.options', options, $.window.defaults, function(options) {

        });
    }

    $.fn.open = function(options) {
        return this.window(options).plugin('window.options', options, function(options) {
            var window = $(this);

            if (window.hasClass('window-open')) {
                return false;
            }

            if (!options.onBeforeOpen.bind(options)(window)) {
                return false;
            }

            $('.window-open').close(); // try to close all other windows

            //console.debug('window, already opened windows: ', $('.window-open'));

            if ($('.window-open').length > 0) { // if any window already opened, no new window will opened
                return false;
            }

            $.block(options.loading);

            function trigger() {
                var cmd = $(this).buttonval();
                var cb     = 'on' + cmd.charAt(0).toUpperCase() + cmd.substr(1);
                var func   = $(options).attr(cb);

                if ($(this).is(':reset')) {
                    $(window).close();
                    return;
                }

                if (typeof func == 'function') {
                    var result = func.bind(options)(window, cmd);

                    if (result) {
                        $(window).close();
                    }
                }
            }

            $('button', window).click(trigger);

            window.center(true)
                  .addClass('window-open')
                  .fadeIn('fast')
                  .trigger('windowOpen')
                  .one('windowClose', function() {
                      $('button', window).unbind('click', trigger);
                  });

            options.onOpen.bind(options)(window);
        });
    }

    $.fn.close = function(options) {
        var window = $(this);

        if (!window.hasClass('window')) {
            window = $(window).parents('.window');
        }

        window.window(options).plugin('window.options', options, function(options) {
            //console.debug('window.close', window);

            if (!options.onBeforeClose.bind(options)(window)) {
                return false;
            }

            $.unblock();

            window.removeClass('window-open')
                  .fadeOut('fast')
                  .trigger('windowClose');

            options.onClose.bind(options)(window);
        });
    }

})(jQuery);
