//SCREEN-BOILERPLATE

//this boilerplate builds screens that are gonna be shown in the <div class='content'> tag of our main HTML.
//do not build app components with this boilerplate, only screens (reports)

define([
  // Application variable, always include it to have access to app methods.
  'app',

  //templates-loader: this loads templates async.
  'js/templates-loader',

  'modules/modal'

],

function (app, T, Modal) {

    function callNetworkConfigurationService(action, data, success, error) {
        data = (data != null) ? data : {};
        if (action != null && action != undefined) _.extend(data, { action: action });

        $.ajax(app.foldersRoot + '/app/custom-screens/IHConfiguration/system-network-configuration/api/network-configuration.aspx', {
            type: 'POST',
            data: data,
            //dataType: 'json',
            success: success,
            error: error
        });
    }

    //replace all 'SystemNetworkConfiguration' with your view's name.
    var SystemNetworkConfiguration = {
        Models: {},
        Views: {},
        ViewModes: {
            Normal: "NORMAL",
            InitConfig: "INIT_CONFIG",
        },
    }

    SystemNetworkConfiguration.Models.Main = Backbone.Model.extend({
        superClass: null,

        defaults: {
            currentSubviewId: null,
            prevSubviewId: null,
        },

        constructor: function () {
            this.superClass = SystemNetworkConfiguration.Models.Main.__super__;

            this.superClass.constructor.apply(this, arguments);
        },

        set: function (key, val, options)
        {
            if (key == null) return this;

            var attrs;
                
                // Handle both `'key', value` and `{key: value}` -style arguments.
            if (typeof key === 'object') {
                attrs = key;
                options = val;
            } else {
                (attrs = {})[key] = val;
            }

            if (!options)
                options = {};

            var currentSubviewIdCurrent = this.get('currentSubviewId'),
                currentSubviewIdNew = attrs.currentSubviewId,
                currentSubviewIdSet = (typeof attrs.currentSubviewId !== 'undefined');

            var currentSubviewIdChanging = ((currentSubviewIdSet == true) && (currentSubviewIdNew != currentSubviewIdCurrent));


            if (currentSubviewIdChanging == true)
                attrs.prevSubviewId = currentSubviewIdCurrent;


            this.superClass.set.call(this, attrs, options);
        },
    });

    //the generate id method is called everytime a view is going to be shown by the router and returns and id that
    //is used by the router to store in cache (if it is cacheable) and to know the current shown view.
    //this is useful in case your view is reusable, and displays different data depending on url parameters 
    //(such as a catalog view, or a report that doesnt change in terms of UI but it does change in terms of data)
    //so you can always use the same view on the router but the cache can tell which view is which by using differents ids.
    SystemNetworkConfiguration.generateID = function (viewParams) {
        try {
            //if the viewparams change the view id, then evaluate the viewparams here
            //and return the appropiate id.
            return 'system-network-configuration'; 
        } catch (Error) { console.error(Error); }
    }

    SystemNetworkConfiguration.Views.Main = Backbone.View.extend({
        template: 'system-network-configuration',
        id: 'system-network-configuration',
        title: '',
        //default not cacheable, change this if you want the view to be cacheable
        // if the view is set as cacheable should also have a refresh method to reset the view without erasing the DOM.
        events: {
            'click .configuration-tabs a': 'configuration_tabs_click',
        },
        isCacheable: true,
        container: null,
        mode: SystemNetworkConfiguration.ViewModes.Normal,

        initialize: function () {
            //ATTENTION!!!!!!!!!!
            //All properties which values must not be shared between instances of this object must be defined here (on the
            // initialize function).

            this.options.state = app.view_states.loading;
            this.options.onappend = (_.isFunction(this.options.onappend)) ? this.options.onappend : function () { };

            this.container = this.options.container;

            if (this.options.mode)
                this.mode = this.options.mode;

            this.subviews = {
                ethernet: {
                    status: null,
                    config: null,
                },
                wifi: {
                    status: null,
                    config: null,
                },
            };

            this.model = new SystemNetworkConfiguration.Models.Main();

            this.bindEvents();

            _.bindAll(this);
        },

        append: function (container, el) {
            el = (el != null && el != undefined) ? el : this.$el;

            if (this.options.state == app.view_states.loading
                || this.options.state == app.view_states.shown) {
                //appending view to the main container and set state to shown

                container.append(el);

                this.options.state = app.view_states.shown;

                this.options.onappend(this);
            }

            if (this.options.state == app.view_states.hidden) {
                //append and remain hidden
                container.append(el);
            }

            if (this.options.state == app.view_states.closed) {
                //return without appending.
                return;
            }
        },
        bindEvents: function () {
            //this function should be in every view that uses listenTo anywhere
            //all the model bindings or view-model binding should be here, to manage
            //the show/hide view easily
            this.listenTo(this.model, 'change:currentSubviewId', this.model_change_currentSubviewId);
        },
        close: function () {
            this.options.state = app.view_states.closed;

            for (var subViewName in this.subviews) {
                this.subviews[subViewName].config.close();
                this.subviews[subViewName].status.close();
            }

            this.remove();
            this.unbind();
        },
        hide: function () {
            this.options.state = app.view_states.hidden;

            this.$el.hide();
            this.unbind();
            this.stopListening();
        },
        preRender: function () {
            app.models.subnavbar.set('dateControl', false);
            app.models.subnavbar.set('subnavbar', false);
        },
        render: function (container, viewParams) {
            var that = this;

            if (container != null && container != undefined) this.container = container;

            if (!viewParams) viewParams = {};

            //the screens have a custompath, so it has to be specified in the customPath variable that is
            //then sent to the template loader.
            var customPath = '/app/custom-screens/IHConfiguration/system-network-configuration/';

            T.render.call(
                this,
                this.template,
                function (tmp) {
                    //start: before the view is visible, but the template was already loaded (not instanced nor appended)
                    //end:

                    if (!that.options.i18n) that.options.i18n = {};

                    app.getI18NJed(
                        that,
                        that.template,
                        function (i18nJED) {
                            //storing internationalization data
                            that.options.i18n[that.template] = i18nJED;

                            //loading the view and appeding it to the views's $el.
                            that.$el.html(tmp({}));

                            //start: the view was already loaded an is on a div element, but not appended to the main container
                            //here you can perform anything you want DOM related, by getting the dom element via that.$el.find('#id')
                            //or this.$('#id')

                            that.subviews.ethernet.status = new SystemNetworkConfiguration.Views.NetworkCardStatus({
                                container: $(that.$el.find('#ethernet_status_container')[0]),
                                mode: that.mode,
                                i18n: i18nJED,
                                //Name must match with the network card name.
                                name: 'ETHERNET',
                                template: 'ethernet_status_template',

                                onappend: that.subview_append,
                            });
                            that.subviews.ethernet.status.render();

                            that.subviews.ethernet.config = new SystemNetworkConfiguration.Views.NetworkCardConfiguration({
                                container: $(that.$el.find('#ethernet_config_container')[0]),
                                mode: that.mode,
                                i18n: i18nJED,
                                //Name must match with the network card name.
                                name: 'ETHERNET',
                                template: 'network_config_template',

                                onappend: that.subview_append,
                            });
                            that.subviews.ethernet.config.render();


                            that.subviews.wifi.status = new SystemNetworkConfiguration.Views.NetworkCardStatus({
                                container: $(that.$el.find('#wifi_status_container')[0]),
                                mode: that.mode,
                                i18n: i18nJED,
                                //Name must match with the network card name.
                                name: 'WIFI',
                                template: 'wifi_status_template',

                                onappend: that.subview_append,
                            });
                            that.subviews.wifi.status.render();

                            that.subviews.wifi.config = new SystemNetworkConfiguration.Views.NetworkCardConfiguration({
                                container: $(that.$el.find('#wifi_config_container')[0]),
                                mode: that.mode,
                                i18n: i18nJED,
                                //Name must match with the network card name.
                                name: 'WIFI',
                                template: 'network_config_template',
                                pre_configureNetwork: that.pre_configureNetwork_wifi, 

                                onappend: that.subview_append,
                            });
                            that.subviews.wifi.config.render();

                            //end

                            that.model.set('currentSubviewId', 'ethernet');
                        },
                        true,
                        customPath
                    );
                },
                customPath,
                'main_template'
            );
        },
        show: function () {
            this.options.state = app.view_states.shown;

            this.bindEvents();
            this.$el.show();
        },

        configuration_tabs_click: function (e) {
            try
            {
                var target = $(e.target);
                var tabId = target.data('tab-id');

                this.model.set('currentSubviewId', tabId);
            }
            catch (Error) { console.error(Error); }
        },
        model_change_currentSubviewId: function (model, newSubViewId)
        {
            try
            {
                var prevSubViewId = model.get('prevSubviewId');

                var prevSubView = this.subviews[prevSubViewId],
                    newSubView = this.subviews[newSubViewId];

                this.$el.find('[data-tab-id="' + prevSubViewId + '"][data-toggle="tab"]').parent().removeClass('active');
                this.$el.find('.tab-content').find('[data-tab-id="' + prevSubViewId + '"]').removeClass('active');

                if (prevSubView) {
                    prevSubView.status.hide();
                    prevSubView.config.hide();
                }

                if (newSubView) {
                    newSubView.status.show();
                    newSubView.config.show();
                }

            
                this.$el.find('[data-tab-id="' + newSubViewId + '"][data-toggle="tab"]').parent().addClass('active');
                this.$el.find('.tab-content').find('[data-tab-id="' + newSubViewId + '"]').addClass('active');
            }
            catch (Error) { console.error(Error); }
        },
        subview_append: function () {
            try
            {
                console.log('subview append called');
                console.log('wifi status view state: ' + this.subviews.wifi.status.options.state);
                console.log('wifi config view state: ' + this.subviews.wifi.config.options.state);
                console.log('ethernet status view state: ' + this.subviews.ethernet.status.options.state);
                console.log('ethernet config view state: ' + this.subviews.ethernet.config.options.state);

                var showState = app.view_states.shown;

                if ((this.subviews.wifi.status.options.state == showState)
                    && (this.subviews.wifi.config.options.state == showState)
                    && (this.subviews.ethernet.status.options.state == showState)
                    && (this.subviews.ethernet.config.options.state == showState))
                {
                    //appending view to the main container
                    this.append(this.container, this.$el);
                }
            }
            catch (Error) { console.error(Error); }
        },
        pre_configureNetwork_wifi: function () {

            var that = this;

            var modal = new Modal.Views.Main({
                id: "apply-wifi-network-card-changes-modal"
                , title: this.options.i18n[this.template].translate("apply_wifi_changes_modal_title").fetch()
                , message: this.options.i18n[this.template].translate("apply_wifi_changes_modal_msg").fetch()
                , allowCancel: true
                , buttons_type: "CONTINUE-CANCEL"
            });

            modal.on("continue", function () {
                that.subviews.wifi.config.configureNetwork(); 
                //var loading_modal = new Modal.Views.Main({
                //    id: "loading-modal"
                //    , title: ""
                //    , message: that.options.i18n[that.template].translate("starting_reset_to_factory_defaults_process").fetch()
                //    , allowCancel: false
                //    , buttons_type: ""
                //});

                //loading_modal.on("shown", function () {
                //    setTimeout(function () {
                //        $.ajax({
                //            url: app.foldersRoot + "/app/custom-screens/IHConfiguration/reset-to-factory-defaults/api/factory-defaults-api.aspx",
                //            type: 'POST',
                //            // Form data
                //            data: {
                //                action: "RESET_TO_FACTORY_DEFAULTS",
                //            },
                //            dataType: "json"
                //        })
                //        .done(function (e) {
                //            app.router.logout();
                //        });
                //    }, 1500);
                //});

                //loading_modal.show();
            });

            modal.show();

            return false; 
        }, 
    });

    SystemNetworkConfiguration.Models.NetworkCardStatus = Backbone.Model.extend({
        defaults: {
            currentSSID: null,
            detectedSSIDs: [],
            detectedSSIDsCount: 0,
            name: null,
            password: null,
            status: null,
        },
        fetch: function (e) {
            var that = this;

            callNetworkConfigurationService(
                'GET_NETWORK_STATUS',
                {
                    name: this.get('name'),
                },
                function (resp) {
                    try
                    {
                        if ((resp != null) && (resp.Success == true) && (resp.Data != null)) {
                            var data = resp.Data;

                            that.set({
                                currentSSID: data['CurrentSSID'],
                                detectedSSIDs: data['SSIDs'],
                                detectedSSIDsCount: (data['SSIDs']) ? data['SSIDs'].length : 0,
                                status: data['Status'].toString().toUpperCase(),
                            });
                        }
                        else
                        {
                            app.serverResponseToConsole(resp, true);
                        }
                    }
                    catch (Error) { console.error(Error); }
                }
            )
        },
    });

    SystemNetworkConfiguration.Views.NetworkCardStatus = Backbone.View.extend({
        template: 'system-network-configuration',
        id: 'system-network-configuration-wifi-settings',
        title: '',
        events: {
            'change #ap_password, #ap_name': 'editField_change',
            'click #connect_btn': 'connectBtn_click',
            'click #disconnect_btn': 'disconnectBtn_click',
            'change #chkbox_show_password': 'showPassword_change', 
        },
        //default not cacheable, change this if you want the view to be cacheable
        // if the view is set as cacheable should also have a refresh method to reset the view without erasing the DOM.
        isCacheable: true,
        container: null,
        i18n: null,
        loadingPoster: null,
        mode: SystemNetworkConfiguration.ViewModes.Normal,

        initialize: function () {
            this.options.state = app.view_states.loading;
            this.options.onappend = (_.isFunction(this.options.onappend)) ? this.options.onappend : function () { };

            this.container = this.options.container;

            if (this.options.mode)
                this.mode = this.options.mode;

            this.options.MYREFERENCES = {
                autoRefresh: {
                    enabled: null
                    , toid: null
                    , every: ((this.mode == SystemNetworkConfiguration.ViewModes.InitConfig) ? 10 : 10)
                }
            };

            this.model = new SystemNetworkConfiguration.Models.NetworkCardStatus(
            {
                name: this.options.name,
            });
            this.model.fetch();

            this.i18n = this.options.i18n;

            this.bindEvents();

            _.bindAll(this);
        },

        append: function (container, el) {
            el = (el != null && el != undefined) ? el : this.$el;

            if (this.options.state == app.view_states.loading || this.options.state == app.view_states.shown) {
                //appending view to the main container and set state to shown

                container.append(el);

                this.options.state = app.view_states.shown;

                this.options.onappend(this);
            }

            if (this.options.state == app.view_states.hidden) {
                //append and remain hidden
                container.append(el);
            }

            if (this.options.state == app.view_states.closed) {
                //return without appending.
                return;
            }
        },
        bindEvents: function () {
            //this function should be in every view that uses listenTo anywhere
            //all the model bindings or view-model binding should be here, to manage
            //the show/hide view easily
            this.listenTo(this.model, 'change:status', this.model_change);
            this.listenTo(this.model, 'change:currentSSID', this.model_change);
            this.listenTo(this.model, 'change:detectedSSIDsCount', this.model_change);
        },
        
        close: function () {
            this.options.state = app.view_states.closed;

            this.stopAutoRefresh();

            this.remove();
            this.unbind();
        },
        connectToWifi: function () {
            var that = this;

            var params = {
                ap_name: this.model.get('currentSSID'),
                ap_password: this.model.get('password'),
            }; 

            try{
                console.log("Current AP Name: " + params.ap_name);
                console.log("Current APs Found:");
                var detectedssids = this.model.get('detectedSSIDs'); 
                for (var i = 0; i < detectedssids.length; i++) {
                    console.log("AP Name: " + detectedssids[i].Name);
                }

                console.log("Combo selected index: " + this.$el.find('#ap_name')[0].selectedIndex);
                console.log("Combo selected value: " + this.$el.find('#ap_name').val());
            } catch (Error) {
            }

            if (_.isString(params.ap_name) && params.ap_name.trim() != '') {
                this.$el.find('.main-section').addClass('hide');

                this.loadingPoster
                    .addClass('connecting')
                    .removeClass('hide');

                callNetworkConfigurationService(
                    'CONNECT_TO_ACCESSPOINT',
                    params,
                    function (resp) {
                        try {
                            if ((resp == null) || (resp.Success == false)) {
                                var msg;

                                if (resp == null)
                                    msg = 'response_error_no_response';
                                else if (resp.Success == false)
                                    msg = resp.Message;
                                else
                                    msg = 'response_error_no_response';

                                app.views.topMessages.showMessage(
                                    that.i18n.translate(msg).fetch()
                                );
                            }
                        }
                        catch (Error) { console.error(Error); }

                        try {
                            that.startAutoRefresh();
                        }
                        catch (Error) { console.error(Error); }
                    },
                    function (resp) {
                        try {
                            that.startAutoRefresh();
                        }
                        catch (Error) { console.error(Error); }
                    }
                );
            } else {
                app.views.topMessages.showMessage(
                    that.i18n.translate('error_connecting_wifi_try_again').fetch()
                );
            }
        },
        disconnectFromWifi: function () {
            var that = this;

            this.$el.find('.main-section').addClass('hide');

            this.loadingPoster
                .addClass('disconnecting')
                .removeClass('hide');

            callNetworkConfigurationService(
                'DISCONNECT_WIFI',
                null,
                function (resp) {
                    try {
                        that.refresh();
                    }
                    catch (Error) { console.error(Error); }
                },
                function (resp) {
                    try {
                        that.refresh();
                    }
                    catch (Error) { console.error(Error); }
                }
            );
        },
        hide: function () {
            this.options.state = app.view_states.hidden;

            this.$el.hide();
            this.unbind();
            this.stopListening();
        },
        preRender: function () {
            app.models.subnavbar.set('dateControl', false);
            app.models.subnavbar.set('subnavbar', false);
        },
        refresh: function () {
            //console.log('autorefresh: ' + new Date().toString()); 
            if (this.options.MYREFERENCES.autoRefresh.toid != null) {
                clearTimeout(this.options.MYREFERENCES.autoRefresh.toid);
                this.options.MYREFERENCES.autoRefresh.toid = null;
            }

            this._refresh();

            if (this.options.MYREFERENCES.autoRefresh.enabled == true) {
                this.options.MYREFERENCES.autoRefresh.toid = setTimeout(this.refresh, this.options.MYREFERENCES.autoRefresh.every * 1000);
            }
        },
        _refresh: function () {
            try {
                this.model.fetch();
            } catch (Error) { console.error(Error); }
        },
        render: function (container, viewParams) {
            var that = this;

            if (container != null && container != undefined) this.container = container;

            if (!viewParams) viewParams = {};

            //the screens have a custompath, so it has to be specified in the customPath variable that is
            //then sent to the template loader.
            var customPath = '/app/custom-screens/IHConfiguration/system-network-configuration/';

            T.render.call(
                this,
                this.template,
                function (tmp) {
                    //start: before the view is visible, but the template was already loaded (not instanced nor appended)
                    //end:

                    //loading the view and appeding it to the views's $el.
                    var templateData = that.model.toJSON();
                    templateData.mode = that.mode;

                    that.$el.html(tmp(templateData));

                    //start: the view was already loaded an is on a div element, but not appended to the main container
                    //here you can perform anything you want DOM related, by getting the dom element via that.$el.find('#id')
                    //or this.$('#id')

                    that.loadingPoster = $(that.$el.find('.loading-poster')[0]);

                    //end

                    //appending view to the main container
                    that.append(that.container, that.$el);


                    that.startAutoRefresh();
                },
                customPath,
                this.options.template
            );
        },
        show: function () {
            this.options.state = app.view_states.shown;

            this.bindEvents();
            this.$el.show();
        },
        startAutoRefresh: function () {
            try {
                if (this.options.MYREFERENCES.autoRefresh.enabled !== true) {
                    if (this.options.MYREFERENCES.autoRefresh.toid != null) {
                        clearTimeout(this.options.MYREFERENCES.autoRefresh.toid);
                        this.options.MYREFERENCES.autoRefresh.toid = null;
                    }

                    this.options.MYREFERENCES.autoRefresh.enabled = true;

                    //use a timeout to execute the first refresh to return the handle to the start function caller.
                    //So when the caller finish it will do the first refresh.
                    this.options.MYREFERENCES.autoRefresh.toid = setTimeout(this.refresh, 1);
                }
            } catch (Error) { console.error(Error); }
        },
        stopAutoRefresh: function () {
            if (this.options.MYREFERENCES.autoRefresh.toid != null) {
                clearTimeout(this.options.MYREFERENCES.autoRefresh.toid);
                this.options.MYREFERENCES.autoRefresh.toid = null;
            }
            this.options.MYREFERENCES.autoRefresh.enabled = false;
        },

        connectBtn_click: function (e) {
            try {
                e.preventDefault();

                this.connectToWifi();
            }
            catch (Error) { console.error(Error); }
        },
        disconnectBtn_click: function (e)
        {
            try {
                this.disconnectFromWifi();
            }
            catch (Error) { console.error(Error); }
        },
        editField_change: function (e)
        {
            try
            {
                this.stopAutoRefresh();

                var target = $(e.target);
                var selected_ap = target.val();
                console.log("Current SSID combo: " + selected_ap); 

                this.model.set(target.attr('name'), target.val(), { silent: true });
            }
            catch (Error) { console.error(Error); }
        },
        showPassword_change: function(e){
            try {
                var target = $(e.target);
                var checked = target.is(":checked");
                this.$el.find("#ap_password").attr("type", ((checked) ? "text" : "password")); 
            } catch (Error) { console.error(Error); }
        },
        model_change: function (model) {
            try
            {
                if (this.options.MYREFERENCES.autoRefresh.enabled)
                    this.render();
            }
            catch (Error) { console.error(Error); }
        },
    });

    SystemNetworkConfiguration.Models.NetworkCardConfiguration = Backbone.Model.extend({
        superClass: null,
        defaults: {
            dhcpEnabled: null,
            defaultGateway: null,
            ip4Address: null,
            isDnsServerAutomatic: null,
            name: null,
            preferredDns: null,
            subnetMask: null,
        },

        edited: false,

        constructor: function ()
        {
            this.superClass = SystemNetworkConfiguration.Models.NetworkCardConfiguration.__super__;

            this.superClass.constructor.apply(this, arguments);
        },        

        fetch: function ()
        {
            var that = this;

            callNetworkConfigurationService(
                'GET_NETWORK_INFO',
                {
                    name: this.get('name'),
                },
                function (resp)
                {
                    if ((resp != null) && (resp.Success == true) && (resp.Data != null)) {
                        if ((that.edited == false) && (that.get('dhcpEnabled') !== false)) {
                            that.setData(resp.Data);
                        }
                    }
                    else {
                        app.serverResponseToConsole(resp, true);
                    }
                }
            );
        },
        //get: function (attr) {
        //    var retVal;

        //    if (attr)
        //    {
        //        var attrFixed = $.trim(attr).toUpperCase();

        //        switch (attrFixed)
        //        {
        //            case "ISDNSSERVERAUTOMATIC":
        //                retVal = !(this.get('preferredDns'));
        //                break;
        //            default:
        //                retVal = this.superClass.get.call(this, attr);
        //                break;
        //        }
        //    }
        //    else
        //    {
        //        retVal = this.superClass.get.call(this, attr);
        //    }

        //    return retVal;
        //},
        set: function (key, val, options)
        {
            if (key == null) return this;

            var attrs;
                
            // Handle both `'key', value` and `{key: value}` -style arguments.
            if (typeof key === 'object') {
                attrs = key;
                options = val;
            } else {
                (attrs = {})[key] = val;
            }

            if (!options)
                options = {};

            var defaultGatewayCurrent = this.get('defaultGateway'),
                defaultGatewayNew = attrs.defaultGateway,
                defaultGatewaySet = (typeof attrs.defaultGateway !== 'undefined'),
                dhcpEnabledCurrent = this.get('dhcpEnabled'),
                dhcpEnabledNew = attrs.dhcpEnabled,
                dhcpEnabledSet = (typeof attrs.dhcpEnabled !== 'undefined'),
                isDnsServerAutoCurrent = this.get('isDnsServerAutomatic'),
                isDnsServerAutoNew = attrs.isDnsServerAutomatic,
                isDnsServerAutoSet = (typeof attrs.isDnsServerAutomatic !== 'undefined')
                preferredDnsCurrent = this.get('preferredDns'),
                preferredDnsNew = attrs.preferredDns,
                preferredDnsSet = (typeof attrs.preferredDns !== 'undefined');

                var defaultGatewayChanging = ((defaultGatewaySet == true) && (defaultGatewayNew != defaultGatewayCurrent)),
                    dhcpEnabledChanging = ((dhcpEnabledSet == true) && (dhcpEnabledNew != dhcpEnabledCurrent)),
                    isDnsServerAutoChanging = ((isDnsServerAutoSet == true) && (isDnsServerAutoNew != isDnsServerAutoCurrent)),
                    preferredDnsChanging = ((preferredDnsSet == true) && (preferredDnsNew != preferredDnsCurrent));

            if (options.fullSet !== true) {
                this.edited = true;

                if (dhcpEnabledChanging == true) {
                    if (dhcpEnabledNew == false) {
                        attrs.isDnsServerAutomatic = false;

                        if (defaultGatewaySet == false)
                            attrs.preferredDns = defaultGatewayCurrent;
                        else
                            attrs.preferredDns = defaultGatewayNew;
                    }
                    else {
                        attrs.isDnsServerAutomatic = true;
                        attrs.preferredDns = null;
                    }
                }

                if (isDnsServerAutoChanging == true) {
                    if (isDnsServerAutoNew == true) {
                        attrs.preferredDns = null;
                    }
                    else {
                        if (defaultGatewaySet == false)
                            attrs.preferredDns = defaultGatewayCurrent;
                        else
                            attrs.preferredDns = defaultGatewayNew;
                    }
                }

                if (preferredDnsChanging == true)
                {
                    if (preferredDnsNew)
                        attrs.isDnsServerAutomatic = false;
                    else
                        attrs.isDnsServerAutomatic = true;
                }
            }
            else
            {
                this.edited = false;
            }

            this.superClass.set.call(this, attrs, options);
        },

        setData: function (data) {
            try
            {
                var attrs = {
                    dhcpEnabled: data.DhcpEnabled,
                    defaultGateway: data.DefaultGateway,
                    ip4Address: data.Ip4Address,
                    subnetMask: data.Subnetmask,
                };

                if (this.get('isDnsServerAutomatic') !== false) {
                    attrs.isDnsServerAutomatic = data.IsDnsServerAutomatic;
                    attrs.preferredDns = data.PreferredDns;
                }

                this.set(attrs, { fullSet: true, });
            }
            catch (Error) { console.error(Error); }
        },
    });

    SystemNetworkConfiguration.Views.NetworkCardConfiguration = Backbone.View.extend({
        template: 'system-network-configuration',
        id: 'system-network-configuration-network-card-configuration',
        title: '',
        events: {
            'click #configure_network_btn': 'configureNetworkBtn_click',
            //'click #connection_method_dhcp': 'connectionDhcpRadio_click',
            //'click #connection_method_static': 'connectionStaticRadio_click',
            'click #dhcp_auto': 'connectionDhcpRadio_click',
            'click #dhcp_static': 'connectionStaticRadio_click',
            //'click #dns_server_auto': 'dnsServerAutoRadio_click',
            //'click #dns_server_static': 'dnsServerStaticRadio_click',
            'click #dsn_server_auto': 'dnsServerAutoRadio_click',
            'click #dsn_server_static': 'dnsServerStaticRadio_click',
            
            //'change input[type="text"]': 'textbox_change',
            'change input[type="text"]:not(#preferred_dns)': 'textbox_change',
            'change #preferred_dns': 'preferredDnsTbx_change',
            //'keydown input:not(#preferred_dns)': 'textbox_keydown',
        },
        //default not cacheable, change this if you want the view to be cacheable
        // if the view is set as cacheable should also have a refresh method to reset the view without erasing the DOM.
        isCacheable: true,
        container: null,
        //dhcpEnabledEdited: false,
        i18n: null,
        mode: SystemNetworkConfiguration.ViewModes.Normal,
        saveBtn: null,

        initialize: function () {
            this.options.state = app.view_states.loading;
            this.options.onappend = (_.isFunction(this.options.onappend)) ? this.options.onappend : function () { };
            this.options.pre_configureNetwork = (_.isFunction(this.options.pre_configureNetwork)) ? this.options.pre_configureNetwork : function () { return true; };

            this.container = this.options.container;

            this.model = new SystemNetworkConfiguration.Models.NetworkCardConfiguration(
                {
                    name: this.options.name,
                },
                {
                    fullSet: true,
                    silent: true,
                }
            );

            if (this.options.mode)
                this.mode = this.options.mode;

            this.options.MYREFERENCES = {
                autoRefresh: {
                    enabled: null
                    , toid: null
                    , every: ((this.mode == SystemNetworkConfiguration.ViewModes.InitConfig) ? 10 : 10)
                },
            };
            this.editFields = {};

            this.i18n = this.options.i18n;

            this.bindEvents();

            _.bindAll(this);
        },

        append: function (container, el) {
            el = (el != null && el != undefined) ? el : this.$el;

            if (this.options.state == app.view_states.loading
                || this.options.state == app.view_states.shown) {
                //appending view to the main container and set state to shown

                container.append(el);

                this.options.state = app.view_states.shown;

                this.options.onappend(this);
            }

            if (this.options.state == app.view_states.hidden) {
                //append and remain hidden
                container.append(el);
            }

            if (this.options.state == app.view_states.closed) {
                //return without appending.
                return;
            }
        },
        bindEvents: function () {
            //this function should be in every view that uses listenTo anywhere
            //all the model bindings or view-model binding should be here, to manage
            //the show/hide view easily
            this.listenTo(this.model, 'change', this.model_change);
            this.listenTo(this.model, 'change:dhcpEnabled', this.model_change_dhcpEnabled);
            this.listenTo(this.model, 'change:isDnsServerAutomatic', this.model_change_isDnsServerAutomatic);
            //this.listenTo(this.model, 'change:preferredDns', this.model_change_preferredDns);
        },
        close: function () {
            this.options.state = app.view_states.closed;

            this.stopAutoRefresh();

            this.remove();
            this.unbind();
        },
        hide: function () {
            this.options.state = app.view_states.hidden;

            this.$el.hide();

            this.unbind();

            this.stopListening();
        },
        preRender: function () {
            app.models.subnavbar.set('dateControl', false);
            app.models.subnavbar.set('subnavbar', false);
        },
        refresh: function () {
            //console.log('autorefresh: ' + new Date().toString()); 
            if (this.options.MYREFERENCES.autoRefresh.toid != null) {
                clearTimeout(this.options.MYREFERENCES.autoRefresh.toid);
                this.options.MYREFERENCES.autoRefresh.toid = null;
            }

            this._refresh();

            if (this.options.MYREFERENCES.autoRefresh.enabled == true) {
                this.options.MYREFERENCES.autoRefresh.toid = setTimeout(this.refresh, this.options.MYREFERENCES.autoRefresh.every * 1000);
            }
        },
        _refresh: function () {
            try {
                this.model.fetch();
            } catch (Error) { console.error(Error); }
        },
        render: function (container, viewParams) {
            var that = this;

            if (container != null && container != undefined) this.container = container;

            if (!viewParams) viewParams = {};

            //the screens have a custompath, so it has to be specified in the customPath variable that is
            //then sent to the template loader.
            var customPath = '/app/custom-screens/IHConfiguration/system-network-configuration/';

            T.render.call(
                this,
                this.template,
                function (tmp) {
                    //start: before the view is visible, but the template was already loaded (not instanced nor appended)
                    //end:

                    //loading the view and appeding it to the views's $el.
                    var templateData = that.model.toJSON();
                    templateData.mode = that.mode;

                    that.$el.html(tmp(templateData));

                    //start: the view was already loaded an is on a div element, but not appended to the main container
                    //here you can perform anything you want DOM related, by getting the dom element via that.$el.find('#id')
                    //or this.$('#id')

                    //end

                    //var internalId = that.model.get('internalId');

                    that.editFields.dhcpStaticFields = that.$el.find('#dhcp_static_fields');
                    that.editFields.preferredDnsFields = that.$el.find('#preferred_dns_fields');

                    that.editFields.connDhcpRadio = that.$el.find('#dhcp_auto');
                    that.editFields.connStaticLabel = that.$el.find('#dhcp_static_label');
                    that.editFields.connStaticRadio = that.$el.find('#dhcp_static');
                    that.editFields.defaultGatewayLabel = that.$el.find('#default_gateway_label');
                    that.editFields.defaultGatewayTbx = that.$el.find('#default_gateway');
                    that.editFields.dnsModeAutoLabel = that.$el.find('#dsn_server_auto_label');
                    that.editFields.dnsModeAutoRadio = that.$el.find('#dsn_server_auto');
                    that.editFields.dnsModeStaticLabel = that.$el.find('#dsn_server_static_label');
                    that.editFields.dnsModeStaticRadio = that.$el.find('#dsn_server_static');
                    that.editFields.ipAddressLabel = that.$el.find('#ip_address_label');
                    that.editFields.ipAddressTbx = that.$el.find('#ip_address');
                    that.editFields.preferredDsnLabel = that.$el.find('#preferred_dns_label');
                    that.editFields.preferredDsnTbx = that.$el.find('#preferred_dns');
                    that.editFields.subnetMaskLabel = that.$el.find('#subnet_mask_label');
                    that.editFields.subnetMaskTbx = that.$el.find('#subnet_mask');

                    that.saveBtn = that.$el.find('#configure_network_btn');


                    //appending view to the main container
                    that.append(that.container, that.$el);

                    that.startAutoRefresh();
                },
                customPath,
                this.options.template
            );
        },
        show: function () {
            this.options.state = app.view_states.shown;

            this.bindEvents();

            this.$el.show();
        },
        startAutoRefresh: function () {
            try {
                if (this.options.MYREFERENCES.autoRefresh.enabled !== true) {
                    if (this.options.MYREFERENCES.autoRefresh.toid != null) {
                        clearTimeout(this.options.MYREFERENCES.autoRefresh.toid);
                        this.options.MYREFERENCES.autoRefresh.toid = null;
                    }

                    this.options.MYREFERENCES.autoRefresh.enabled = true;

                    //use a timeout to execute the first refresh to return the handle to the start function caller.
                    //So when the caller finish it will do the first refresh.
                    this.options.MYREFERENCES.autoRefresh.toid = setTimeout(this.refresh, 1);
                }
            } catch (Error) { console.error(Error); }
        },
        stopAutoRefresh: function () {
            if (this.options.MYREFERENCES.autoRefresh.toid != null) {
                clearTimeout(this.options.MYREFERENCES.autoRefresh.toid);
                this.options.MYREFERENCES.autoRefresh.toid = null;
            }
            this.options.MYREFERENCES.autoRefresh.enabled = false;
        },

        configureNetwork: function () {
            var that = this;

            this.dhcpEnabledEdited = false;

            this.saveBtn.prop('disabled', true);

            try
            {
                callNetworkConfigurationService(
                    'CONFIGURE_NETWORK',
                    { config: JSONEncode(this.model.toJSON()), },
                    function (resp) {
                        try{
                            if ((resp != null) && (resp.Success == true) && (resp.Data != null)) {
                                that.model.setData(resp.Data);

                                if (!resp.Message) {
                                    app.views.topMessages.showMessage(
                                        that.i18n.translate("response_ok_change_apply").fetch()
                                        //this.i18n.translate("Changes applied successfully.").fetch()
                                    );
                                }
                                else
                                {
                                    app.views.topMessages.showMessage(
                                        that.i18n.translate(resp.Message).fetch()
                                    );
                                }
                            }
                            else
                            {
                                if ((resp != null) && (resp.Message)) {
                                    app.views.topMessages.showMessage(
                                        that.i18n.translate(resp.Message).fetch()
                                    );
                                }
                            }
                        }
                        catch (Error) { console.error(Error); }

                        that.saveBtn.prop('disabled', false);
                    },
                    function (error) {
                        try
                        {
                            app.views.topMessages.showMessage(
                                that.i18n.translate("response_error_temporaly").fetch()
                            );
                        }
                        catch (Error) { console.error(Error); }

                        that.saveBtn.prop('disabled', false);
                    }
                );
            }
            catch (Error)
            { 
                console.error(Error);

                this.saveBtn.prop('disabled', false);
            }
        },
        //updateAutoRefreshEnabled: function () {
        //    if ((this.model.get('dhcpEnabled') == true) && (this.dhcpEnabledEdited != true))
        //        this.startAutoRefresh();
        //    else
        //        this.stopAutoRefresh();
        //},
        updateData: function ()
        {
            this.editFields.defaultGatewayTbx.val(this.model.get('defaultGateway'));
            this.editFields.ipAddressTbx.val(this.model.get('ip4Address'));
            this.editFields.subnetMaskTbx.val(this.model.get('subnetMask'));

            if (this.model.get('dhcpEnabled') == false)
                this.editFields.connStaticRadio.prop('checked', true);
            else
                this.editFields.connDhcpRadio.prop('checked', true);

            if (this.model.get('isDnsServerAutomatic') == false) {
                this.editFields.dnsModeStaticRadio.prop('checked', true);
                this.editFields.dnsModeAutoRadio.prop('checked', false);
            }
            else {
                this.editFields.dnsModeStaticRadio.prop('checked', false);
                this.editFields.dnsModeAutoRadio.prop('checked', true);
            }

            this.editFields.preferredDsnTbx.val(this.model.get('preferredDns'));
        },
        updateEditionMode: function ()
        {
            if (this.model.get('dhcpEnabled') == false)
            {
                this.editFields.defaultGatewayTbx.prop('disabled', false)
                this.editFields.ipAddressTbx.prop('disabled', false);
                this.editFields.subnetMaskTbx.prop('disabled', false);

                this.editFields.dhcpStaticFields.removeClass('control-disabled');
                

                this.editFields.dnsModeAutoRadio.prop('disabled', true);

                if (this.editFields.dnsModeAutoLabel.hasClass('control-disabled') == false)
                    this.editFields.dnsModeAutoLabel.addClass('control-disabled');
                
                if (this.editFields.dnsModeAutoRadio.hasClass('control-disabled') == false)
                    this.editFields.dnsModeAutoRadio.addClass('control-disabled');
                //this.editFields.dnsModeStaticRadio.prop('disabled', true);
            }
            else
            {
                this.editFields.defaultGatewayTbx.prop('disabled', true);
                this.editFields.ipAddressTbx.prop('disabled', true);
                this.editFields.subnetMaskTbx.prop('disabled', true);

                if (this.editFields.dhcpStaticFields.hasClass('control-disabled') == false)
                    this.editFields.dhcpStaticFields.addClass('control-disabled');


                this.editFields.dnsModeAutoLabel
                    .removeClass('control-disabled');
                this.editFields.dnsModeAutoRadio
                    .prop('disabled', false)
                    .removeClass('control-disabled');
                //this.editFields.dnsModeStaticRadio.prop('disabled', false);
            }

            if (this.model.get('isDnsServerAutomatic') == true) {
                this.editFields.preferredDsnTbx.prop('disabled', true);

                if (this.editFields.preferredDnsFields.hasClass('control-disabled') == false)
                    this.editFields.preferredDnsFields.addClass('control-disabled');
            }
            else {
                this.editFields.preferredDsnTbx.prop('disabled', false);

                this.editFields.preferredDnsFields.removeClass('control-disabled');
            }
        },

        trigger_edited: function() {
            this.trigger('edited', this);
        },

        configureNetworkBtn_click: function (e) {
            try
            {
                e.preventDefault();

                if (this.options.pre_configureNetwork.call(this) == true) {
                    this.configureNetwork();
                }
            }
            catch (Error) { console.error(Error); }
        },
        connectionDhcpRadio_click: function (e) {
            try
            {
                //this.dhcpEnabledEdited = true;

                this.model.set('dhcpEnabled', true);

                this.trigger_edited();
            }
            catch (Error) { console.error(Error); }
        },
        connectionStaticRadio_click: function (e) {
            try
            {
                //this.dhcpEnabledEdited = true;

                this.model.set('dhcpEnabled', false);

                this.trigger_edited();
            }
            catch (Error) { console.error(Error); }
        },
        dnsServerAutoRadio_click: function (e) {
            try
            {
                this.model.set('isDnsServerAutomatic', true);

                this.trigger_edited();
            }
            catch (Error) { console.error(Error); }
        },
        dnsServerStaticRadio_click: function (e) {
            try
            {
                this.model.set('isDnsServerAutomatic', false);

                this.trigger_edited();
            }
            catch (Error) { console.error(Error); }
        },
        model_change: function (e) {
            try
            {
                this.updateData();
            }
            catch (Error) { console.error(Error); }
        },
        model_change_dhcpEnabled: function (model, dhcpEnabled) {
            try
            {
                this.updateEditionMode();

                //this.updateAutoRefreshEnabled();
            }
            catch (Error) { console.error(Error); }
        },
        model_change_isDnsServerAutomatic: function (e) {
            try
            {
                this.updateEditionMode();
            }
            catch (Error) { console.error(Error); }
        },
        //model_change_preferredDns: function (e) {
        //    try
        //    {
        //        this.updateEditionMode();
        //    }
        //    catch (Error) { console.error(Error); }
        //},
        textbox_change: function (e) {
            try
            {
                var target = $(e.target);

                //this.stopAutoRefresh();

                this.model.set(target.attr('name'), target.val());

                this.trigger_edited();
            }
            catch (Error) { console.error(Error); }
        },
        preferredDnsTbx_change: function (e) {
            try
            {
                var target = $(e.target);

                //this.stopAutoRefresh();

                this.model.set(target.attr('name'), target.val());

                this.trigger_edited();
            }
            catch (Error) { console.error(Error); }
        },
        //textbox_keydown: function (e) {
        //    var target = $(e.target);

        //    this.model.set(target.attr('name'), target.val(), { silent: true });
        //},
    });

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

});
