﻿/*
    JQuery plugin to extend/re-purpose jGrowl plugin, adding some new
    classes to enable styling of a dabs themed notification.
    
    Also adds support for a singletonMode where a series of 
    notifications can be shown in order and 1 per page request
    controlled by an incremental cookie value.
*/

// minified version of the jGrowl plugin code:

(function($){$.jGrowl=function(m,o){if($('#jGrowl').size()==0)$('<div id="jGrowl"></div>').addClass($.jGrowl.defaults.position).appendTo('body');$('#jGrowl').jGrowl(m,o);};$.fn.jGrowl=function(m,o){if($.isFunction(this.each)){var args=arguments;return this.each(function(){var self=this;if($(this).data('jGrowl.instance')==undefined){$(this).data('jGrowl.instance',$.extend(new $.fn.jGrowl(),{notifications:[],element:null,interval:null}));$(this).data('jGrowl.instance').startup(this);}
if($.isFunction($(this).data('jGrowl.instance')[m])){$(this).data('jGrowl.instance')[m].apply($(this).data('jGrowl.instance'),$.makeArray(args).slice(1));}else{$(this).data('jGrowl.instance').create(m,o);}});};};$.extend($.fn.jGrowl.prototype,{defaults:{pool:0,header:'',group:'',sticky:false,position:'top-right',glue:'after',theme:'default',corners:'10px',check:250,life:3000,speed:'normal',easing:'swing',closer:true,closeTemplate:'&times;',closerTemplate:'<div>[ close all ]</div>',log:function(e,m,o){},beforeOpen:function(e,m,o){},open:function(e,m,o){},beforeClose:function(e,m,o){},close:function(e,m,o){},animateOpen:{opacity:'show'},animateClose:{opacity:'hide'}},notifications:[],element:null,interval:null,create:function(message,o){var o=$.extend({},this.defaults,o);this.notifications[this.notifications.length]={message:message,options:o};o.log.apply(this.element,[this.element,message,o]);},render:function(notification){var self=this;var message=notification.message;var o=notification.options;var notification=$('<div class="jGrowl-notification'+((o.group!=undefined&&o.group!='')?' '+o.group:'')+'"><div class="close">'+o.closeTemplate+'</div><div class="header">'+o.header+'</div><div class="message">'+message+'</div></div>').data("jGrowl",o).addClass(o.theme).children('div.close').bind("click.jGrowl",function(){$(this).parent().trigger('jGrowl.close');}).parent();(o.glue=='after')?$('div.jGrowl-notification:last',this.element).after(notification):$('div.jGrowl-notification:first',this.element).before(notification);$(notification).bind("mouseover.jGrowl",function(){$(this).data("jGrowl").pause=true;}).bind("mouseout.jGrowl",function(){$(this).data("jGrowl").pause=false;}).bind('jGrowl.beforeOpen',function(){o.beforeOpen.apply(self.element,[self.element,message,o]);}).bind('jGrowl.open',function(){o.open.apply(self.element,[self.element,message,o]);}).bind('jGrowl.beforeClose',function(){o.beforeClose.apply(self.element,[self.element,message,o]);}).bind('jGrowl.close',function(){$(this).data('jGrowl').pause=true;$(this).trigger('jGrowl.beforeClose').animate(o.animateClose,o.speed,o.easing,function(){$(this).remove();o.close.apply(self.element,[self.element,message,o]);});}).trigger('jGrowl.beforeOpen').animate(o.animateOpen,o.speed,o.easing,function(){$(this).data("jGrowl").created=new Date();}).trigger('jGrowl.open');if($.fn.corner!=undefined)$(notification).corner(o.corners);if($('div.jGrowl-notification:parent',this.element).size()>1&&$('div.jGrowl-closer',this.element).size()==0&&this.defaults.closer!=false){$(this.defaults.closerTemplate).addClass('jGrowl-closer').addClass(this.defaults.theme).appendTo(this.element).animate(this.defaults.animateOpen,this.defaults.speed,this.defaults.easing).bind("click.jGrowl",function(){$(this).siblings().children('div.close').trigger("click.jGrowl");if($.isFunction(self.defaults.closer))self.defaults.closer.apply($(this).parent()[0],[$(this).parent()[0]]);});};},update:function(){$(this.element).find('div.jGrowl-notification:parent').each(function(){if($(this).data("jGrowl")!=undefined&&$(this).data("jGrowl").created!=undefined&&($(this).data("jGrowl").created.getTime()+$(this).data("jGrowl").life)<(new Date()).getTime()&&$(this).data("jGrowl").sticky!=true&&($(this).data("jGrowl").pause==undefined||$(this).data("jGrowl").pause!=true)){$(this).trigger('jGrowl.close');}});if(this.notifications.length>0&&(this.defaults.pool==0||$(this.element).find('div.jGrowl-notification:parent').size()<this.defaults.pool)){this.render(this.notifications.shift());}
if($(this.element).find('div.jGrowl-notification:parent').size()<2){$(this.element).find('div.jGrowl-closer').animate(this.defaults.animateClose,this.defaults.speed,this.defaults.easing,function(){$(this).remove();});};},startup:function(e){this.element=$(e).addClass('jGrowl').append('<div class="jGrowl-notification"></div>');this.interval=setInterval(function(){$(e).data('jGrowl.instance').update();},this.defaults.check);if($.browser.msie&&parseInt($.browser.version)<7&&!window["XMLHttpRequest"])$(this.element).addClass('ie6');},shutdown:function(){$(this.element).removeClass('jGrowl').find('div.jGrowl-notification').remove();clearInterval(this.interval);}});$.jGrowl.defaults=$.fn.jGrowl.prototype.defaults;})(jQuery);

// dabs specific extension/wrapper
$.fn.jGrowlDabsWrapper = function(m, o) {
    return this.each(function() {

        /*
        This function handles the animating of notifications that are positioned outside #pagewrapper
        moving them within the bounds of #pagewrapper when the browser window is narrow
        and back to thier original positions when space allows.
        */
        reposition = function(e, m, o) {
            $(e).find('div.jGrowl-notification:last').each(function() {
                pwWidth = $('#pagewrapper').width();
                pwOffsetLeft = parseInt($('#pagewrapper').offset().left);
                initialLeftVal = $(this).data('initialLeftVal');
                initialRightVal = $(this).data('initialRightVal');

                // only notifications with negative left or right values risk being clipped on resize
                if ((initialLeftVal < 0) || (initialRightVal < 0)) {
                    if (initialLeftVal <= 0) {
                        if ($(this).offset().left < 0) {
                            $(this).animate({ left: 0 }, 500, 'swing', function() {
                                updateTip(e, m, o, "right");
                            });
                        } else if ((pwOffsetLeft + initialLeftVal > 0) && (initialLeftVal + 'px' != $(this).css("left"))) {
                            $(this).animate({ left: initialLeftVal }, 500, 'swing', function() {
                                updateTip(e, m, o, "left");
                            });
                        }
                    } else {
                        var contentWidth = $(this).offset().left + $(this).width();
                        var initialContentWidth = pwOffsetLeft + initialLeftVal + $(this).width();
                        if (contentWidth > $(window).width()) {
                            $(this).animate({ right: 0 }, 500, 'swing', function() {
                                updateTip(e, m, o, "left");
                            });
                        } else if ((initialContentWidth < $(window).width()) && (initialRightVal + 'px' != $(this).css("right"))) {
                            $(this).animate({ right: initialRightVal }, 500, 'swing', function() {
                                updateTip(e, m, o, "right");
                            });
                        }
                    }
                }
            });
        }

        updateTip = function(e, m, o, d) {
            $(e).find('div.jGrowl-notification:last').each(function() {
                initialLeftVal = $(this).data('initialLeftVal');
                initialRightVal = $(this).data('initialRightVal');

                switch (d) {
                    case "left":
                        switch (o.tipPosition) {
                            case "topLeft":
                                $(this).removeClass("topLeft").addClass("topCentre");
                                o.tipPosition = "topCentre";
                                break;

                            case "topCentre":
                                $(this).removeClass("topCentre").addClass("topRight");
                                o.tipPosition = "topRight";
                                break;

                            case "bottomLeft":
                                $(this).removeClass("bottomLeft").addClass("bottomCentre");
                                o.tipPosition = "bottomCentre";
                                break;

                            case "bottomCentre":
                                $(this).removeClass("bottomCentre").addClass("bottomRight");
                                o.tipPosition = "bottomRight";
                                break;

                        }
                        break;

                    case "right":
                        switch (o.tipPosition) {

                            case "topCentre":
                                $(this).removeClass("topCentre").addClass("topLeft");
                                o.tipPosition = "topLeft";
                                break;

                            case "topRight":
                                $(this).removeClass("topRight").addClass("topCentre");
                                o.tipPosition = "topCentre";
                                break;

                            case "bottomCentre":
                                $(this).removeClass("bottomCentre").addClass("bottomLeft");
                                o.tipPosition = "bottomLeft";
                                break;

                            case "topRight":
                                $(this).removeClass("bottomRight").addClass("bottomCentre");
                                o.tipPosition = "bottomCentre";
                                break;

                        }
                        break;

                }


            });
        }

        // after opening the notification, store the original left/right values as defined in CSS
        // useful for getting a notification back to its original location
        captureInitialOffsets = function(e, m, o) {
            $(e).find('div.jGrowl-notification:last').each(function() {
                initialLeftVal = parseInt($(this).css("left").replace(/px/, ''));
                initialRightVal = parseInt($(this).css("right").replace(/px/, ''));

                if (isNaN(initialLeftVal))
                    initialLeftVal = 0;

                if (isNaN(initialRightVal))
                    initialRightVal = 0;

                $(this).data('initialLeftVal', initialLeftVal);
                $(this).data('initialRightVal', initialRightVal);
            });
            reposition(e, m, o);
        }
        
        // Customise the jGrowl markup so we can apply dabs style bubble graphics (using css)
        beforeOpen = function(e, m, o) {
            $(e).find('div.jGrowl-notification:last')
                .wrapInner('<div class="jGrowl-body"></div>')
                .prepend('<div class="jGrowl-header"></div>')
                .wrapInner('<div class="' + o.theme + '"></div>')
                .addClass(o.tipPosition);

            $(window).resize(function() {
                if (typeof (timeoutId) !== 'undefined')
                    clearTimeout(timeoutId);
                timeoutId = setTimeout(function() { reposition(e, m, o) }, 1000);
            });
        }

        /*
        alter the default setting which shows a "close all" box when more than 1 notification is shown
        this needs to be done this way because of a bug in the underlying plugin that ignores this setting
        when supplied as an option.
        */
        $.jGrowl.defaults.closer = false;

        // attach the functions defined above and set default options
        o.beforeOpen = beforeOpen;
        o.open = captureInitialOffsets;
        if (o.theme == undefined)
            o.theme = "default";
        o.closeTemplate = '<img src="/images/theme/dabs_com_v3/en/jgrowl/themes/' + o.theme + '/close-window.gif" alt="close" />';

        // display the notification(s)
        if (!o.singletonMode) // display growl notification normally
            $(this).jGrowl(m, o);
        else // operating in singleton mode, check cookie values etc. to find out whether this notification should be shown
        {
            if (typeof (singletonModeGrowlDisplayed) == 'undefined')
                singletonModeGrowlDisplayed = false;

            // if cookie exists and matches the supplied singletonIndex, show notification and update cookie
            if ((o.singletonIndex == parseFloat($.cookie('DabsjGrowlNotificationLevel'))) && (!singletonModeGrowlDisplayed)) {
                singletonModeGrowlDisplayed = true;
                $.cookie('DabsjGrowlNotificationLevel', o.singletonIndex + 1, { path: '/', expires: 100 });
                $(this).jGrowl(m, o);
            }

            // if index is zero and no cookie exists, show notification and set cookie
            if ((o.singletonIndex == 0) && (!$.cookie('DabsjGrowlNotificationLevel'))) {
                singletonModeGrowlDisplayed = true;
                $.cookie('DabsjGrowlNotificationLevel', o.singletonIndex + 1, { path: '/', expires: 100 });
                $(this).jGrowl(m, o);
            }


        }
    });
}




