(function (paw, utils) {
    function PawPopup(id, settings) {
        var self = this;
        this.isFullScreen = false;
        this.id = id;
        this.settings = paw.lang.append({
            destroyOnClose: true,
            markupDef: undefined,
            Component: undefined,
            styleClass: undefined,
            title: undefined,
            bind: undefined,
            popupActions: undefined,
            draggable: true,
            type: "modal",
            maximizable: true,
            popupIconActions: [],
            $content: undefined,
            contentStyleClass: undefined
        }, settings || {});

        if(this.settings.maximizable){
            this.settings.popupIconActions.push({
                icon: 'paw-popup-size-control fa fa-expand-alt',
                onSelected: function(action, e){
                    e.stopPropagation();
                    e.stopImmediatePropagation();
                    
                    if(self.isFullScreen){
                        self.$popup.removeClass('paw-popup-fullscreen');
                        action.$$elt.removeClass('fa-compress-alt').addClass('fa-expand-alt');
                        self.isFullScreen = false;
                        self.resize();
                        self.$popup.removeAttr('data-drag-lock');
                        return;
                    }
                    self.$popup.addClass('paw-popup-fullscreen');
                    action.$$elt.removeClass('fa-expand-alt').addClass('fa-compress-alt');
                    self.isFullScreen = true;
                    self.$popup.attr('data-drag-lock', 'true');
                    self.resize();
                }
            });
        }

        this.$popup = null;
        this.component = null;
        this.isOpened = false;

        this.onEscKey = function (e) {
            if (e.key === 'Escape') {
                self.hide();
            }
        };

        this.onResize = function(e){
            self.resize(e);
        };

        this.resizeDebouncer = utils.async.debouncer(function(e){
            if(utils.value.isSet(this.component) && utils.value.isFunction(self.component.onResized)){
                self.component.onResized(e);
            }
            if(utils.value.isFunction(this.settings.onResized)){
                this.settings.onResized(e);
            }
        });
        this.isInit = false;
    }

    PawPopup.prototype.show = function () {
        var self = this;

        if(this.isOpened){
            return;
        }
        $().customModal({
            id: this.id,
            destroyOnClose: this.settings.destroyOnClose,
            showCloseButton: true,
            type: this.settings.type,
            title: this.settings.title,
            content: '<div class="paw-popup-content"></div>',
            closeOtherModals: false,
            buttons: this.settings.actions,
            draggable: this.settings.draggable,
            onClose: function () {
                if(utils.value.isFunction(self.settings.onClose)){
                    self.settings.onClose();
                }
                if (self.settings.destroyOnClose) {
                    self.destroy();
                    self.isInit = false;
                }
                self.isOpened = false;
            }
        });
        if(this.isInit){
            this.isOpened = true;
            return;
        }

        this.$popup = $('#' + this.id);

        this.$popup.addClass('paw-popup');
        if (utils.value.isSet(this.settings.styleClass)) {
            this.$popup.addClass(this.settings.styleClass);
        }        

        if(utils.value.isSet(this.settings.popupIconActions)){
            var $iconTray = this.$popup.find('.custom-modal-icon-tray');
            utils.iterable.iterate(this.settings.popupIconActions, function(action){
                var $action = $('<span class="paw-popup-icon-action custom-modal-icon ' + action.icon + '" title="' + (action.title || '') + '"></span>');
                $iconTray.prepend($action);
                action.$$elt = $action;
                if(utils.value.isFunction(action.onSelected)){
                    $action.on('click', function(e){
                        action.onSelected(action, e);
                    });
                }                
            });
        }

        var $holder = this.$popup.find('.paw-popup-content');

        if(utils.value.isSet(this.settings.contentStyleClass)){
            $holder.addClass(this.settings.contentStyleClass);
        }

        if(utils.value.isFunction(this.settings.markupDef)){
            $holder.html(this.settings.markupDef(this.settings.bind).join('\n'));
        }
        else if(utils.value.isSet(this.settings.Component)){
            this.component = new this.settings.Component($holder, this);
            if(utils.value.isSet(this.settings.bind)){
                utils.iterable.iterate(this.settings.bind, function(v, k){
                    self.component[k] = v;
                });
            }
            if(utils.value.isFunction(this.component.onBinded)){
                this.component.onBinded();
            }

            if(utils.value.isFunction(this.component.markupDef)){
                $holder.html(this.component.markupDef().join('\n'));
            }

            if (utils.value.isFunction(this.component.init)) {
                this.component.init();
            }
        }
        else if(utils.value.isSet(this.settings.$content)){
            $holder.append(this.settings.$content);
            if(this.settings.$content.hasClass('hidden')){
                this.settings.$content.removeClass('hidden');
            }
        }

        $(document).on('keyup', this.onEscKey);
        $(window).on('resize', this.onResize);

        this.isOpened = true;
        this.isInit = true;
    };

    PawPopup.prototype.hide = function () {
        this.$popup.customModal('close');
    };

    PawPopup.prototype.destroy = function () {
        if (utils.value.isSet(this.component) && utils.value.isFunction(this.component.destroy)) {
            this.component.destroy();
        }

        if(utils.value.isSet(this.$popup)){
            this.$popup.find('.custom-modal-icon-tray > .paw-popup-icon-action').off('click');
        }
        $(document).off('keyup', this.onEscKey);
        $(window).off('resize', this.onResize);
    };

    PawPopup.prototype.resize = function(e){
        if(utils.value.isSet(this.component) && utils.value.isFunction(this.component.onResize)){
            this.component.onResize(e);
        }
        if(utils.value.isFunction(this.settings.onResize)){
            this.settings.onResize(e);
        }
        this.resizeDebouncer(e);
    };

    paw.com.Popup = PawPopup;
})(paw, paw.utils);