(function( $ ){
    var isUserActive, lastActivityTime, lastNotificationsCheck;
    var inactivityTime = 30000; //time after which to mark user inactive in milliseconds
    var checkNotificationsInterval = 60000; //time in which to check for new notifications in milliseconds
    var notificationDisplayTime = 5000;
    var serverTimeDiff = 0;
    var lastAjaxCall = null;
    var checkNotificationsTimeout = null;
    var isDebugMode = false;
    if($('input#isDebugModeOn').val() == "1")
        isDebugMode = true;

    var methods = {
        init : function( options ) {
            return this.each(function(){
                $('body').bind('mousemove.notifications', methods.userPageActionPerformed);
                $('body').bind('scroll.notifications', methods.userPageActionPerformed);
                isUserActive = true;
                var d = new Date();
                lastActivityTime = d.getTime();

                serverTimeDiff = d.getTime() - (parseInt($('input#webServerTime').val())*1000);
                //alert("ServerTimeDiff: "+serverTimeDiff+" ::: "+((serverTimeDiff/1000)/60));
                if($('input#lastNotificationTime').val() == 0) {
                    methods["checkForNewNotifications"].apply(this, []);
                }
                else {
                    var timeDiff = d.getTime() - (parseInt($('input#lastNotificationTime').val())*1000)-serverTimeDiff;
                    //alert("timediff: "+timeDiff);
                    if(isDebugModeOn)
                        alert('page load wait '+(checkNotificationsInterval-timeDiff));
                    if(timeDiff > 0)
                        checkNotificationsTimeout = setTimeout(function() { methods["checkForNewNotifications"].apply(this, []); }, checkNotificationsInterval-timeDiff);
                    else
                        methods["checkForNewNotifications"].apply(this, []);
                }
            });
        },
        destroy : function( ) {
            return this.each(function(){

            })
        },
        displayNotification : function(sticky, message) {
            $.gritter.add({
                title: ' ',
                text: message,
                sticky: sticky,
                time: notificationDisplayTime
            });
        },
        isUserActive : function() {
            var d = new Date();
            if((d.getTime()-lastActivityTime) >= inactivityTime) {
                isUserActive = false;
                return false; //user has not moved mouse for 30 seconds, they are inactive
            }
            return true;
        },
        checkForNewNotifications : function() {
            if(methods["isUserActive"].apply(this, [])) {
                var d = new Date();
                if((d.getTime() - lastAjaxCall) > 50000 || lastAjaxCall == null) {
                    var url = $('input#getNotificationsUrl').val();
                    $.ajax({
                        url: url,
                        success: function(data) {
                            if(data.length > 0) {
                                var response = $.parseJSON(data);
                                var d = new Date();
                                lastAjaxCall = d.getTime();
                                var webServerTime = parseInt(response.serverTime);
                                serverTimeDiff = d.getTime() - webServerTime;
                                //alert("ServerTimeDiff: "+serverTimeDiff);

                                if(response.lastNotificationCheck) {
                                    var d = new Date();
                                    lastNotificationsCheck = d.getTime();
                                    var timeDiff = d.getTime() - parseInt(response.lastNotificationCheck);
                                    if(isDebugModeOn) {
                                        alert("Timeout: "+(checkNotificationsInterval-timeDiff-serverTimeDiff));
                                    }
                                    if(timeDiff > 0) {
                                        checkNotificationsTimeout = setTimeout(function() { methods["checkForNewNotifications"].apply(this, []); }, checkNotificationsInterval-timeDiff-serverTimeDiff);
                                    }
                                    //else
                                    //setTimeout(function() { methods["checkForNewNotifications"].apply(this, []); }, checkNotificationsInterval);
                                }
                                if(response.notifications) {
                                    for(var n=0; n < response.notifications.length; n++) {
                                        var messageText = response.notifications[n];
                                        methods["displayNotification"].apply(this, [false, messageText]);
                                    }
                                }
                            }
                        }
                    });
                }
            }
        },
        userPageActionPerformed : function() {
            isUserActive = methods["isUserActive"].apply(this, []);
            var d = new Date();
            lastActivityTime = d.getTime();
            if(!isUserActive) {
                isUserActive = true;
                if(typeof lastNotificationsCheck == 'undefined')
                    methods["checkForNewNotifications"].apply(this, []);
                else {
                    var timeDiff = d.getTime() - lastNotificationsCheck;
                    if(isDebugModeOn)
                        alert('user was inactive and now is not check for notifications: '+(timeDiff)+"  EVAL: "+(timeDiff >= checkNotificationsInterval)+"  EVAL2: "+(timeDiff > 0));
                    if(timeDiff >= checkNotificationsInterval)
                        methods["checkForNewNotifications"].apply(this, []);
                    else if (timeDiff > 0) {
                        var tmpInterval = checkNotificationsInterval - timeDiff;
                        clearTimeout(checkNotificationsTimeout);
                        checkNotificationsTimeout = setTimeout(function() { methods["checkForNewNotifications"].apply(this, []); }, tmpInterval);
                    }
                }
            }
            //$('span#lastActionDisplay').html("Last Updated: "+lastActivityTime+'<br/>'+isUserActive);
        }
    };

    $.fn.notifications = function( method ) {
        if ( methods[method] ) {
            return methods[method].apply( this, Array.prototype.slice.call( arguments, 1 ));
        } else if ( typeof method === 'object' || ! method ) {
            return methods.init.apply( this, arguments );
        } else {
            $.error( 'Method ' +  method + ' does not exist on jQuery.notifications' );
        }
    };
})( jQuery );
