/// <reference path="http://localhost/IndustrialDashboard/Scripts/IndustrialDashboard-debug.js" />
define([
  // Application.
  "app",

  "moment", 

  //templates-loader
  "js/templates-loader"

],

function (app, moment, T) {

    //replace all NetworkMonitor for the name of your view.
    var NetworkMonitor = { Models: {}, Views: {}, Collections: {} }

    //you can create more than one model, default model is called Model.
    NetworkMonitor.Models.Main = Backbone.Model.extend({
        defaults: {
            connected: true,
            slow: false,
            slowWarning: false,

            speed: null, //In kilo bits per second

            //options
            minAllowedSpeed: 1, //In bits
            warningSpeedLimit: 1, //In bits
            minTries: 2,
            tries: 0,

            auditQueue: null, 
        },
        initialize: function () {
            _.bindAll(this);
            this.bindEvents();
        },
        bindEvents: function () {
            this.listenTo(this, "change:speed", this.speedChange);
            this.listenTo(this, "change:tries", this.triesChange);

            this.listenTo(this, "change:slow", _.partial(this.audit, "slow"));
            this.listenTo(this, "change:connected", _.partial(this.audit, "connected"));
            this.listenTo(this, "change:slowWarning", _.partial(this.audit, "slowWarning"));
        },
        speedChange: function (t) {
            var speed = this.get("speed");
            var minSpeed = this.get("minAllowedSpeed"); 
            var warningSpeedLimit = this.get("warningSpeedLimit"); 

            if (speed <= 0) {
                this.set({
                    connected: false,
                    slow: false,
                    slowWarning: false,
                    tries: 0,
                });
            } else if (speed <= minSpeed) {
                if (!this.get("slow")){
                    this.set({
                        connected: true,
                        slow: false,
                        slowWarning: true,
                        tries: this.get("tries") + 1,
                    });
                }
            } else if (speed <= warningSpeedLimit) {
                this.set({
                    connected: true,
                    slow: false,
                    slowWarning: true,
                    tries: 0, 
                });
            } else {
                this.set({
                    connected: true,
                    slow: false,
                    slowWarning: false,
                    tries: 0,
                });
            }

            console.log(
                ("{ speed: [0] - connected: [1] - slow: [2] - tries: [3] }").replace("[0]", speed).replace("[1]", this.get("connected").toString()).
                replace("[2]", this.get("slow").toString()).replace("[3]", this.get("tries").toString())
            ); 
        },
        triesChange: function () {
            var tries = this.get("tries");

            if (tries == 5) {
                this.set("tries", 0, { silent: true });

                this.set({
                    slow: true,
                    slowWarning: false, 
                }); 
            }
        },
        audit: function(prop, model, value){
            try {
                var that = this; 
                var now = new moment(); 
                var speed = this.get("speed"); 
                var msg, event; 

                var msgs = {
                    "SLOWNETWORK": "Slow network connection: Speed [{0}] kbps.", 
                    "LOSTNETWORK": "Lost network connection."
                }; 

                if ((prop == "slow" && value == true) || (prop == "connected" && value == false)) {
                    switch (prop) {
                        case "slow":
                            event = "SLOWNETWORK";
                            msg = that.format(msgs[event], this.get("speed")); 
                            break;
                        case "connected":
                            event = "LOSTNETWORK";
                            msg = that.format(msgs[event]);
                            break;
                    }

                    app.models.serverAudit.add(
                        msg,
                        "IHBOX",
                        "INFO",
                        event,
                        null,
                        now.format("YYYY-MM-DD HH:mm:ss"),
                        app.models.user.get("timezoneCode"), 
                        true
                    ); 
                }
            }catch(error){ 
                console.log("Failed when trying to add item to audit queue. Exception: " + error.toString());
            }
        }, 
        format: function(str){
            try {
                _.each(_.rest(arguments), function (arg, i) {
                    try{
                        str = str.replace("{" + i.toString() + "}", arg.toString()); 
                    } catch (error) { }
                });     
            } catch (error) { }
            return str;
        }
    });

    //you can create more than one view, default view is called Main.
    NetworkMonitor.Views.Main = Backbone.View.extend({
        template: "network-monitor/network-monitor"
        , id: ""
        , title: ""
        , isCacheable: false
        , initialize: function () {
            this.options = {
                blinking: false,
                blinking_tout: null, 
            };

            _.bindAll(this);

            this.render();
            this.bindEvents(); 
        },
        render: function (container, viewParams) {
            this.props = {
                poster: $(".no-connection-poster"),
                configurationIcon: $(".configuration-icon"),
            }; 

            this.refresh();
        },
        close: function () {
            this.remove();
            this.unbind();
        },
        show: function () {
            this.$el.show();
        },
        hide: function () {
            this.$el.hide();
        },
        refresh: function () {
            var connected = this.model.get("connected");
            var slowWarning = this.model.get("slowWarning");
            var slow = this.model.get("slow");

            if (!connected || slow) {
                this.props.poster.removeClass("hide");
            } else {
                this.props.poster.addClass("hide");
            }

            if (slowWarning) {
                this.startWarningBlinking();
            } else {
                if (this.options.blinking) {
                    this.stopWarningBlinking(); 
                }
            }
        },
        startWarningBlinking: function () {
            if (this.options.blinking_tout != null){
                clearTimeout(this.options.blinking_tout);
                this.options.blinking_tout = null; 
            }

            this.options.blinking = true;

            $("#configuration_icon").popover({
                trigger: "hover",
                html: true,
                content: app.i18n.global.translate("slow_network_configuration_icon_notice").fetch(),
                placement: "bottom",
                container: "body",
            });

            this.warningBlink(); 
        },
        warningBlink: function (val, auto) {
            var icon = this.props.configurationIcon;
            var blinkingClass = "blinking-on"; 
            var validVal = _.isBoolean(val); 

            if ((!icon.hasClass(blinkingClass) && !validVal) || (validVal && val == true)) {
                icon.addClass(blinkingClass)
            } else {
                icon.removeClass(blinkingClass);
            }

            if (!_.isBoolean(auto) || (_.isBoolean(auto) && auto == true)) {
                if (this.options.blinking) {
                    this.options.blinking_tout = setTimeout(this.warningBlink, 1000);
                }
            }
        }, 
        stopWarningBlinking: function(){
            if (this.options.blinking_tout != null) {
                clearTimeout(this.options.blinking_tout);
                this.options.blinking_tout = null;
            }

            this.options.blinking = false;

            $("#configuration_icon").popover('destroy'); 

            this.warningBlink(false, false);
        }, 
        reRender: function (viewParams) {
        },
        bindEvents: function () {
            this.listenTo(this.model, "change:connected change:slow change:slowWarning", this.refresh);
        }, 
    });

    // Required, return the module for AMD compliance.
    return NetworkMonitor;

});
