(function (a) {
    a.ttwNotificationCenter = function (c) {
        var o, b, C, h = this,
            B = {},
            F = {},
            r = {},
            g, w, u, E, p, t, q, e, s, f = 0;
        q = {
            bar: "bar",
            growl: "growl",
            modal: "modal",
            none: "none"
        };
        o = {
            notification: {
                type: "bar",
                autoHide: true,
                autoHideDelay: 3000
            },
            bar: {
                position: false,
                fullWidth: false
            },
            growl: {
                position: "bottom right"
            },
            modal: {
                position: false,
                buttons: {
                    Ok: function () {
                        a(this).dialog("close")
                    }
                }
            },
            notificationList: {
                showMenu: true,
                anchor: "bubble",
                offset: "0 24"
            },
            bubble: {
                useColors: true,
                colors: ["#f56c7e", "#fec151", "#7ad2f4"],
                showEmptyBubble: true
            },
            markDisplayedRead: true,
            showNotificationList: true,
            notificationListEmptyText: "لا يوجد اى شىء فى الوقت الحالى",
            defaultCategory: "general",
            anchor: "body",
            relativeImagePath: "images/notification",
            serverSideSave: false,
            serverSideGet: false,
            serverSideGetNew: false,
            serverSideDelete: false,
            serverSideGetNewInterval: 120000,
            serverSideHandler: "sampleHandler.php",
            serverSideSaveCommand: "save",
            serverSideGetCommand: "get",
            serverSideGetNewCommand: "get_new",
            serverSideDeleteCommand: "delete",
            createCallback: function (G) {},
            markReadCallback: function (G) {},
            deleteCallback: function (G) {},
            notificationCountIncrease: function (G) {},
            notificationClickCallback: function (G) {},
            closeCallback: function (G) {}
        };
        C = {
            tmp: '<div id="tmp"></div>',
            notification: '<div class="ttw-notification"><span class="icon"></span><span class="message"></span><span class="close"></span></div>',
            notificationIcon: '<img src="" alt="notification icon"/>',
            notificationDialog: '<div class="ttw-notification-modal-inner"></div>',
            notificationBubble: '<span class="notification-bubble" title="Notifications"></span>'
        };
        e = {
            notification: ".ttw-notification",
            notificationList: ".notification-list",
            notificationListItem: ".notification-list-item",
            notificationMessage: ".message",
            notificationClose: ".close",
            notificationListMenuItem: ".notification-list-menu-item",
            notificationListCloseButton: ".close-notification-list",
            notificationIcon: ".icon",
            notificationModal: ".modal",
            notificationModalOuter: ".ttw-modal-outer",
            notificationBar: ".bar",
            notificationBarOuter: ".ttw-bar-outer",
            notificationGrowlOuter: ""
        };
        t = [];

        function A() {
            b = a.extend(true, {}, o, c);
            i(b.defaultCategory);
            if (b.serverSideGetNew && b.serverSideHandler && (b.serverSideHandler != "")) {
                h.getNew();
                setInterval(function () {
                    h.getNew()
                }, b.serverSideGetNewInterval)
            }
        }
        function i(H, G) {
            t.push(H);
            B[H] = {};
            B[H].count = 0;
            B[H].readCount = 0;
            B[H].unreadCount = 0;
            B[H].read = {};
            B[H].unread = {};
            if (G && (H != b.defaultCategory)) {
                F[H] = G
            }
        }
        function z(H) {
            var G = H.category;
            if (!B[G]) {
                i(G)
            }
            B[G].count++;
            if (!H.read) {
                B[G].unreadCount++;
                B[G].unread[H.id] = H
            } else {
                B[G].readCount++;
                B[G].read[H.id] = H
            }
            if (y(G, H)) {
                F[G].updateBubble()
            }
        }
        function y(G, H) {
            return (typeof F[G] != "undefined") && (G != b.defaultCategory) && (!b.markDisplayedRead || (H.type == q.none))
        }
        function d(H) {
            var G = H.read ? "read" : "unread";
            delete B[H.category][G][H.id];
            delete H
        }
        function k(G) {
            return G && B[G]
        }
        function l(G) {
            return (a.inArray(G, ["read", "unread", "all"]) != -1)
        }
        function n(G) {
            return ((typeof G != "undefined") ? G : "") + new Date().getTime() + "-" + Math.floor(Math.random() * (100000 - 1 + 1)) + 1
        }
        function v(J, I) {
            if (!I) {
                I = "unread"
            }
            if (!(k(J) || J == "all")) {
                return false
            }
            if (!l(I)) {
                return false
            }
            if (J != "all" && I != "all") {
                return B[J][I]
            } else {
                if (J == "all" && I == "all") {
                    var K = {},
                        H = {};
                    for (var G = 0; G < t.length; G++) {
                        a.extend(H, B[J[G]].read, B[J[G]].unread);
                        a.extend(K, H)
                    }
                    return K
                } else {
                    if (J == "all" && I != "all") {
                        var K = {};
                        for (var G = 0; G < t.length; G++) {
                            a.extend(K, B[t[G]][I])
                        }
                        return K
                    } else {
                        if (J != "all" && I == "all") {
                            return a.extend({}, B[J].read, B[J].unread)
                        } else {
                            return false
                        }
                    }
                }
            }
        }
        function x(I, H) {
            try {
                if (I == "") {
                    return false
                }
                if (typeof H == "undefined") {
                    H = true
                }
                var G = a.parseJSON(I);
                if (G.status == "success") {
                    if (G.result != "empty" && typeof G.result != "string") {
                        a.each(G.result, function (K, L) {
                            h.createNotification(L, H)
                        });
                        m()
                    }
                } else {
                    j("Import Error", G)
                }
            } catch (J) {
                j("Import Error:", J)
            }
            return true
        }
        function m() {
            a.each(F, function (G, H) {
                H.updateBubble()
            })
        }
        function D(H) {
            var G = Array.prototype.slice.call(arguments, 1);
            if (a.isFunction(H)) {
                H.apply(this, G)
            }
        }
        function j() {
            if (window.console) {
                console.log(Array.prototype.slice.call(arguments))
            }
        }
        g = function (H, G) {
            this.category = H;
            this.$item = a(G);
            this.$bubble = {};
            this.notificationList = false;
            this.colors = b.bubble.colors;
            this.init()
        };
        g.prototype.init = function () {
            var G = this;
            this.createBubble();
            if (b.showNotificationList) {
                this.$bubble.bind("click", function () {
                    if (!G.notificationList) {
                        G.notificationList = new u({
                            category: G.category,
                            $anchor: (b.notificationList.anchor == "bubble") ? G.$bubble : G.$item
                        })
                    }
                })
            }
            r[this.category] = 0
        };
        g.prototype.createBubble = function () {
            this.$bubble = a(C.notificationBubble).html("0").appendTo(this.$item);
            if (b.bubble.useColors) {
                if (f >= this.colors.length) {
                    f = 0
                }
                this.$bubble.css("background-color", this.colors[f]);
                f++
            }
            if (b.bubble.showEmptyBubble) {
                this.$bubble.css("display", "inline")
            }
        };
        g.prototype.updateBubble = function () {
            var G = this,
                H = (B[this.category]) ? B[this.category].unreadCount : 0;
            this.$bubble.html(H);
            if (H <= 0 && !b.bubble.showEmptyBubble) {
                this.$bubble.stop().fadeOut("fast")
            }
            if (H > 0 && (r[this.category] == 0)) {
                this.$bubble.stop().fadeIn()
            }
            if (r[this.category] < H) {
                D(b.notificationCountIncrease, this)
            }
            r[this.category] = H
        };
        g.prototype.animate = function (G) {};
        u = function (H) {
            this.$wrapper = {};
            this.$list = false;
            this.type = "unread";
            this.markup = {
                notificationListWrapper: '<div class="notification-list-wrapper"></div>',
                notificationListMenu: '<ul class="notification-list-menu"><li id="unread-menu-item" class="notification-list-menu-item">Unread</li><li id="all-menu-item" class="notification-list-menu-item">All</li><li class="close-notification-list"></li></ul>',
                notificationListMenuItem: '<li class="notification-list-menu-item"></li>',
                notificationList: '<ul class="notification-list"></ul>',
                notificationListItem: '<li class="notification-list-item"></li>'
            };
            this.settings = a.extend(true, {}, b.notificationList, H);
            if (s) {
                var G = this;
                s.close(function () {
                    G.build()
                })
            } else {
                this.build()
            }
            return this
        };
        u.prototype.build = function () {
            var G;
            this.$wrapper = a(this.markup.notificationListWrapper);
            if (this.settings.showMenu) {
                G = a(this.markup.notificationListMenu);
                this.$wrapper.append(G)
            }
            this.populate();
            this.bindMenuActions();
            this.$wrapper.appendTo(b.anchor).position({
                my: "center top",
                at: "center bottom",
                of: this.settings.$anchor,
                offset: this.settings.offset
            });
            this.$wrapper.css("display", "block").animate({
                opacity: 1
            });
            s = this
        };
        u.prototype.populate = function () {
            var I, H = this,
                J, G;
            I = a(this.markup.notificationList).attr("data-type", H.type);
            J = v(this.settings.category, this.type);
            if (!a.isEmptyObject(J)) {
                a.each(J, function (K, L) {
                    G = L.settings.icon ? "show-icon" : "";
                    a(H.markup.notificationListItem).addClass(G).append(L.getHtml()).data({
                        id: L.id,
                        category: L.category,
                        notification: L
                    }).appendTo(I)
                })
            } else {
                a(H.markup.notificationListItem).addClass("empty-list").html(b.notificationListEmptyText).appendTo(I)
            }
            I.find(e.notificationListItem).bind("click", function () {
                D(b.notificationClickCallback, a(this).data("notification"))
            });
            if (this.$list) {
                this.$list.remove()
            }
            this.$list = I;
            this.$wrapper.append(this.$list)
        };
        u.prototype.bindMenuActions = function () {
            var H = this,
                G;
            this.$wrapper.find(e.notificationListMenuItem).bind("click", function () {
                H.type = a(this).attr("id").split("-")[0];
                H.populate()
            });
            this.$wrapper.delegate(".close", "click", function () {
                var I = a(this);
                I.parents(e.notificationListItem).animate({
                    opacity: 0
                }, 400, function () {
                    var K = a(this),
                        J = K.data();
                    if (B && B[J.category] && B[J.category][H.type]) {
                        if (B[J.category][H.type][J.id]) {
                            G = B[J.category][H.type][J.id].markRead();
                            F[J.category].updateBubble()
                        }
                    }
                    K.remove();
                    D(b.markReadCallback, G)
                })
            });
            this.$wrapper.find(e.notificationListCloseButton).bind("click", function () {
                H.close()
            })
        };
        u.prototype.close = function (H) {
            var G = this;
            this.$wrapper.fadeOut(50, function () {
                G.$wrapper.remove();
                F[G.settings.category].notificationList = false;
                s = false;
                D(H)
            })
        };
        w = function (H) {
            this.id = "";
            this.message = {};
            this.category = "";
            this.anchor = "";
            this.wrapper = {};
            this.markup = {};
            this.$notification = false;
            this.hideTimeout = false;
            this.type = "";
            this.read = false;
            if (typeof H == "string") {
                this.settings = b.notification;
                this.settings.message = H
            }
            var G = H.type ? H.type : b.notification.type;
            if (G && b[G]) {
                H = a.extend({}, b[G], H)
            }
            this.settings = a.extend(true, {}, b.notification, H)
        };
        w.prototype.create = function () {
            if (this.settings.message) {
                this.id = this.settings.id || n("notification");
                this.message = this.settings.message;
                this.category = this.settings.category ? this.settings.category : b.defaultCategory;
                this.type = this.settings.type;
                this.data = this.settings.data;
                this.read = (typeof this.settings.read != "undefined") ? this.settings.read : this.read;
                return this
            } else {
                return false
            }
        };
        w.prototype.html = function () {
            this.$notification = a(C.notification);
            if (!this.settings.icon) {
                this.$notification.find(e.notificationIcon).remove()
            }
            this.$notification.attr("id", this.id);
            if (this.settings.notificationClass) {
                this.$notification.addClass(this.settings.notificationClass)
            }
            this.setValues()
        };
        w.prototype.getHtml = function () {
            if (!this.$notification) {
                this.html()
            }
            return this.$notification.clone()
        };
        w.prototype.setValues = function () {
            if (typeof this.settings.icon != "undefined") {
                this.$notification.addClass("show-icon").find(".icon").css("background", "transparent url(" + this.settings.icon + ") no-repeat center center scroll").html(C.notificationIcon).find("img").attr("src", this.settings.icon)
            }
            if (typeof this.message != "undefined") {
                this.$notification.find(".message").html(this.message)
            }
        };
        w.prototype.display = function () {
            if (!this.read) {
                if (!y(this.category, this)) {
                    this.markRead()
                }
                switch (this.settings.type) {
                case q.growl:
                    this.displayGrowl();
                    break;
                case q.modal:
                    this.displayModal();
                    break;
                case q.bar:
                    this.displayBar();
                    break;
                default:
                    break
                }
            }
        };
        w.prototype.setAutoHide = function (I, H) {
            var G = this;
            if (b.autoHide || (b.autoHide !== false && this.settings.autoHide !== false)) {
                this.hideTimeout = setTimeout(function () {
                    G.close(I, H)
                }, G.settings.autoHideDelay)
            }
        };
        w.prototype.close = function (G, H) {
            if (typeof B[this.category][this.id] != undefined) {
                if (this.hideTimeout != false) {
                    clearTimeout(this.hideTimeout)
                }
                if (!(G instanceof jQuery)) {
                    G = a(G)
                }
                G.fadeOut(function () {
                    G.remove();
                    if (H) {
                        H.remove()
                    }
                });
                D(b.closeCallback, this)
            }
        };
        w.prototype.markRead = function () {
            this.read = true;
            B[this.category].readCount++;
            B[this.category].read[this.id] = this;
            B[this.category].unreadCount--;
            delete B[this.category].unread[this.id];
            this.save();
            return this
        };
        w.prototype.save = function () {
            var G = this;
            if (b.serverSideSave && b.serverSideHandler && (b.serverSideHandler != "")) {
                a.ajax({
                    url: b.serverSideHandler,
                    data: {
                        command: b.serverSideSaveCommand,
                        id: G.id,
                        message: G.message,
                        category: G.category,
                        type: G.type,
                        read: G.read,
                        data: G.data
                    },
                    error: function (H, J, I) {
                        j("Save Error: " + J + ", " + I)
                    }
                })
            }
        };
        w.prototype.destroy = function () {
            var G = this;
            d(this);
            if (b.serverSideSave && b.serverSideHandler && (b.serverSideHandler != "")) {
                a.ajax({
                    url: b.serverSideHandler,
                    data: {
                        command: b.serverSideDeleteCommand,
                        id: G.id
                    },
                    error: function (H, J, I) {
                        j("Save Error: " + J + ", " + I)
                    },
                    success: function () {
                        D(b.deleteCallback, G)
                    }
                })
            } else {
                D(b.deleteCallback, G)
            }
        };
        w.prototype.displayGrowl = function () {
            var G = this,
                H;
            this.markup = {
                notification: '<div class="growl-notification"><div class="icon"></div><div class="message"></div><span class="close"></span></div>',
                wrapper: '<div class="ttw-notification-center-wrapper growl-wrapper"></div>'
            };
            if (!E) {
                this.initGrowl()
            } else {
                this.wrapper = E
            }
            H = a(this.getHtml());
            H.find(e.notificationClose).click(function () {
                G.close(H)
            });
            H.addClass(this.type).appendTo(this.wrapper).slideDown(300, function () {
                H.animate({
                    opacity: 1
                }, function () {
                    G.setAutoHide(H)
                })
            });
            return this
        };
        w.prototype.initGrowl = function () {
            var G, H = {};
            G = this.settings.position.split(" ");
            H[G[0]] = 0;
            H[G[1]] = 0;
            this.wrapper = E = a(this.markup.wrapper).css(H).appendTo(b.anchor);
            p = a(C.tmp).appendTo(b.body)
        };
        w.prototype.displayModal = function () {
            var K, I, G, L, M, H, J = this;
            L = a(this.getHtml()).addClass(e.notificationModal.substr(1));
            K = e.notificationModalOuter.substr(1);
            if (this.settings.notificationClass) {
                K += (" " + this.settings.notificationClass)
            }
            if (this.settings.icon) {
                K += " show-icon"
            }
            if (!this.settings.buttons) {
                this.settings.buttons = b.modal.buttons
            }
            M = a(window);
            G = this.settings.position || [((M.width() - 350) / 2), M.height() * 0.15];
            I = {
                dialogClass: K,
                resizable: false,
                title: this.settings.title,
                width: "350",
                position: G,
                modal: true,
                buttons: this.settings.buttons
            };
            I = a.extend(true, {}, I, this.settings.dialog);
            L.dialog(I);
            H = L.parents(e.notificationModalOuter);
            this.setAutoHide(H, L)
        };
        w.prototype.displayBar = function () {
            var L, K, J, I = this,
                H, G, M;
            L = a(this.getHtml()).addClass(e.notificationBar.substr(1));
            L.find(e.notificationClose).click(function () {
                I.close(H)
            });
            K = e.notificationBarOuter.substr(1);
            if (this.settings.icon) {
                K += " show-icon"
            }
            if (this.settings.buttons) {
                K += " show-buttons"
            }
            if (this.settings.notificationClass) {
                K += " " + this.settings.notificationClass
            }
            M = a(window);
            G = this.settings.position || [((M.width() - 550) / 2), 6];
            J = {
                dialogClass: K,
                resizable: false,
                title: this.settings.title,
                width: "550",
                modal: false,
                buttons: this.settings.buttons,
                position: G
            };
            if (this.settings.buttons) {
                J.buttons = this.settings.buttons
            }
            J = a.extend(true, {}, J, this.settings.dialog);
            L.dialog(J);
            H = L.parent(e.notificationBarOuter);
            this.setAutoHide(H, L)
        };
        h.createNotification = function (I, G) {
            var H = new w(I);
            G = (typeof G != "undefined") ? G : true;
            if (H.create()) {
                z(H);
                if (G) {
                    H.display();
                    H.save();
                    D(b.createCallback, H)
                }
            }
            return H
        };
        h.initMenu = function (G) {
            a.each(G, function (J, H) {
                var I = new g(J, H);
                i(J, I)
            })
        };
        h.getNotifications = function (H, G) {
            return v(H, G)
        };
        h.importNotifications = function (H, G) {
            if (b.serverSideGet && b.serverSideHandler && (b.serverSideHandler != "")) {
                a.ajax({
                    url: b.serverSideHandler,
                    data: {
                        command: b.serverSideGetCommand,
                        category: H,
                        read_status: G
                    },
                    success: function (I) {
                        x(I, false)
                    },
                    error: function (I, K, J) {
                        j("Import Error:", I, K, J)
                    }
                })
            }
        };
        h.getNew = function () {
            if (b.serverSideGetNew && b.serverSideHandler && (b.serverSideHandler != "")) {
                a.ajax({
                    url: b.serverSideHandler,
                    data: {
                        command: b.serverSideGetNewCommand
                    },
                    success: function (G) {
                        x(G, true)
                    },
                    error: function (G, I, H) {
                        j("Import Error:", G, I, H)
                    }
                })
            }
        };
        h.deleteNotification = function (G) {
            G.destroy()
        };
        h.notifications = B;
        h.success = function (I, G, H) {
            return h.helper("success", I, G, H)
        };
        h.error = function (I, G, H) {
            return h.helper("error", I, G, H)
        };
        h.notice = function (I, G, H) {
            return h.helper("notice", I, G, H)
        };
        h.warning = function (I, G, H) {
            return h.helper("warning", I, G, H)
        };
        h.helper = function (L, I, G, H) {
            var K, J;
            if (!G) {
                G = b.notification.type
            }
            J = b.relativeImagePath || "";
            K = h.createNotification({
                message: I,
                type: G,
                category: H,
                title: L.charAt(0).toUpperCase() + L.slice(1),
                icon: J + L + ((G != q.bar) ? "_color" : "") + ".png",
                autoHide: false,
                notificationClass: L
            });
            return K
        };
        A();
        return h
    }
})(jQuery);
