﻿/*
* jQuery Notify UI Widget 1.4
* Copyright (c) 2010 Eric Hynds
*
* http://www.erichynds.com/jquery/a-jquery-ui-growl-ubuntu-notification-widget/
*
* Depends:
*   - jQuery 1.4
*   - jQuery UI 1.8 widget factory
*
* Dual licensed under the MIT and GPL licenses:
*   http://www.opensource.org/licenses/mit-license.php
*   http://www.gnu.org/licenses/gpl.html
*
*/
(function ($) {

    $.widget("ech.notify", {
        options: {
            speed: 500,
            expires: 5000,
            stack: 'below',
            custom: false,
            queue: false
        },
        _create: function () {
            var self = this;
            this.templates = {};
            this.keys = [];

            // build and save templates
            this.element.addClass("ui-notify").children().addClass("ui-notify-message ui-notify-message-style").each(function (i) {
                var key = this.id || i;
                self.keys.push(key);
                self.templates[key] = $(this).removeAttr("id").wrap("<div></div>").parent().html(); // because $(this).andSelf().html() no workie
            }).end().empty().show();
        },
        create: function (template, msg, opts) {
            if (typeof template === "object") {
                opts = msg;
                msg = template;
                template = null;
            }

            var tpl = this.templates[template || this.keys[0]];

            // remove default styling class if rolling w/ custom classes
            if (opts && opts.custom) {
                tpl = $(tpl).removeClass("ui-notify-message-style").wrap("<div></div>").parent().html();
            }

            this.openNotifications = this.openNotifications || 0;

            // return a new notification instance
            return new $.ech.notify.instance(this)._create(msg, $.extend({}, this.options, opts), tpl);
        }
    });

    // instance constructor
    $.extend($.ech.notify, {
        instance: function (widget) {
            this.parent = widget;
            this.isOpen = false;
        }
    });

    // instance methods
    $.extend($.ech.notify.instance.prototype, {
        _create: function (params, options, template) {
            this.options = options;

            var self = this,

            // build html template
			html = template.replace(/#(?:\{|%7B)(.*?)(?:\}|%7D)/g, function ($1, $2) {
			    return ($2 in params) ? params[$2] : '';
			}),

            // the actual message
			m = (this.element = $(html)),

            // close link
			closelink = m.find(".ui-notify-close");

            // clickable?
            if (typeof this.options.click === "function") {
                m.addClass("ui-notify-click").bind("click", function (e) {
                    self._trigger("click", e, self);
                });
            }

            // show close link?
            if (closelink.length) {
                closelink.bind("click", function () {
                    self.close();
                    return false;
                });
            }

            this.parent.element.queue('notify', function () {
                self.open();

                // auto expire?
                if (typeof options.expires === "number") {
                    window.setTimeout(function () {
                        self.close();
                    }, options.expires);
                }

            });

            if (!this.options.queue || this.parent.openNotifications <= this.options.queue - 1) this.parent.element.dequeue('notify');

            return this;
        },
        close: function () {
            var self = this, speed = this.options.speed;

            this.element.fadeTo(speed, 0).slideUp(speed, function () {
                self._trigger("close");
                self.isOpen = false;
                self.element.remove();
                self.parent.openNotifications -= 1;
                self.parent.element.dequeue('notify');
            });

            return this;
        },
        open: function () {
            if (this.isOpen || this._trigger("beforeopen") === false) {
                return this;
            }

            var self = this;

            this.parent.openNotifications += 1;

            this.element[this.options.stack === 'above' ? 'prependTo' : 'appendTo'](this.parent.element).css({ display: "none", opacity: "" }).fadeIn(this.options.speed, function () {
                self._trigger("open");
                self.isOpen = true;
            });

            return this;
        },
        widget: function () {
            return this.element;
        },
        _trigger: function (type, e, instance) {
            return this.parent._trigger.call(this, type, e, instance);
        }
    });

})(jQuery);

