/// <reference path="http://localhost:65492/IndustrialDashboard/Scripts/IndustrialDashboard-debug.js" />
//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",

  "js/jqBootstrapValidation/jqBootstrapValidation",

  //"js/bootstrap-select/bootstrap-select",
],

function (app, T, Modal) {

    //replace all "AccountInformation" with your view's name.
    var AccountInformation = { Models: {}, Views: {}, Collections: {} }

    AccountInformation.Models.License = Backbone.Model.extend({
        defaults: {
            timestamp: null,
            tags: null,
            key: null, 
        }
    }); 

    AccountInformation.Collections.Licenses = Backbone.Collection.extend({
        model: AccountInformation.Models.License, 
    });

    AccountInformation.Models.AgentEnabled = Backbone.Model.extend({
        defaults: {
            name: null,
            status: false,
            timestamp: null, 
        }, 
    });

    AccountInformation.Collections.AgentsEnabled = Backbone.Collection.extend({
        model: AccountInformation.Models.AgentEnabled,
    }); 

    AccountInformation.Models.Main = Backbone.Model.extend({
        defaults: {
            procedure: '', 

            //account
            account_number: null,

            //user
            username: null, 
            name: null,
            lastname: null,
            country: null,
            timezone: null,

            //disk space
            db_total_space: null,
            db_total_space_string: null, 

            db_used_space: null,
            db_used_space_string: null, 

            db_available_space: null,
            db_available_space_string: null, 

            db_percent_used: null,

            //tags
            tags_used: null,
            tags_percent_used: null,
            tags_licensed: null,
            tags_configured: null,
            licensesCount: null,

            licenses: null,
            agentsEnabled: null, 
        },
        initialize: function () {
            this.attributes.licenses = new AccountInformation.Collections.Licenses();
            this.attributes.agentsEnabled = new AccountInformation.Collections.AgentsEnabled(); 
        },
        sizeToString: function (val, roundDigits) {
            try{
                var unit = ""; 
                var divider = 1;
                roundDigits = (roundDigits != null && roundDigits != undefined) ? roundDigits : 1; 

                if (val >= 1000000){ unit = "tb"; divider=1000000; }
                else if (val >= 1000){ unit = "gb"; divider=1000; }
                else if (val >= 1){ unit = "mb"; divider=1; }
                else{ unit = "bytes"; divider=1; }

                return (val / divider).toFixed(roundDigits).toString() + " " + unit; 
            }catch(Error){ }
        }
    });

    //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.
    AccountInformation.generateID = function (viewParams) {
        try {
            //if the viewparams change the view id, then evaluate the viewparams here
            //and return the appropiate id.
            return "account-information"; 
        } catch (Error) { }
    }

    AccountInformation.Views.Main = Backbone.View.extend({
        template: "account-information"
        , id: "account-information"
        , title: "Account Information"
        //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: false
        , initialize: function () {
            this.options.state = app.view_states.loading;
            this.options.onappend = (_.isFunction(this.options.onappend)) ? this.options.onappend : function () { }; 
            
            if (this.options.viewParams) {
            }

            var model = new AccountInformation.Models.Main({
                procedure: "dbo.procedureName"
            });

            this.options.MYREFERENCES = {
                autoRefresh: {
                    enabled: true
                    , toid: null
                }
                , bindingSpecialColumns: false
            };

            this.model = model;

            this.bindEvents();
            _.bindAll(this);
        },

        events: {
            "click .fileinput-button": "browseLicense",
            "change #license_fileinput": "licenseChanged",
            "click .btn-upload-license": "uploadLicense",
            "click .btn-cancel-upload-license": "cancelUploadLicense",
            "click .btn-edit-user-info": "editUserInfo_edit",
            "click .btn-save-user-info": "editUserInfo_save",
            "click .btn-cancel-edit-user-info": "editUserInfo_cancel",
            "click .btn-change-password": "changeUserPassword",
        }, 

        render: function (container) {
            var that = this;
            var thatContainer = (container != null && container != undefined) ? container : this.options.container;
            this.options.MYREFERENCES.subviews = {};
            //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/account-information/";

            T.render.call(this, this.template, function (tmp) {
                //getInternationalizationData
                if (!that.options.i18n) that.options.i18n = {};
                app.getI18NJed(that, that.template, function (i18nJED) {
                    //storing internationalization data
                    that.options.i18n[that.template] = i18nJED;
                    var automatic_timezone_label = that.options.i18n[that.template].translate("timezone_automatic_label").fetch(); 

                    //start: before the view is visible, but the template was already loaded (not instanced nor appended)
                    app.CallProcedure(app.DatabaseNames.System + ".FrontEnd.GetUserInfo", null, {
                        onSuccess: function (data) {

                            var data1 = (data != null && data != undefined && data.Table && data.Table[0]) ? data.Table[0] : {}; 
                            var licenses = (data != null && data != undefined && data.Table1 && data.Table1) ? data.Table1 : {};
                            var agentsEnabled = (data != null && data != undefined && data.Table2 && data.Table2) ? data.Table2 : {};

                            var licensesArr = _.map(licenses, function (t) {
                                return {
                                    timestamp: t["Timestamp"],
                                    tags: t["Tags"],
                                    key: t["Key"],
                                }; 
                            });

                            var agentsEnabledArr = _.map(agentsEnabled, function (t) {
                                return {
                                    name: t["Name"],
                                    status: t["Status"],
                                    timestamp: t["Timestamp"], 
                                }; 
                            });

                            that.model.set({
                                account_number: data1.AccountNumber,
                                username: data1.Username,
                                name: data1.Name,
                                lastname: data1.LastName,
                                country: data1.Country,
                                timezone: (data1.Timezone == null) ? automatic_timezone_label : data1.Timezone,
                                licensesCount: data1.LicensesCount
                            });

                            that.model.get("licenses").set(licensesArr);
                            that.model.get("agentsEnabled").set(agentsEnabledArr);

                            app.CallProcedure(app.DatabaseNames.IH + ".WEB.GetIHStats", null, {
                                onSuccess: function (data) {

                                    data = (data != null && data != undefined && data.Table && data.Table[0]) ? data.Table[0] : {};

                                    var ctx = {
                                        timezones: "",
                                        detected_timezone: null,
                                        sw_enabled: false,
                                        hw_enabled: false,
                                        sw_valid_text: "",
                                        hw_valid_text: "",
                                        sw_key: "",
                                        hw_key: "", 
                                    }; 

                                    var timezonesData = [];
                                    timezonesData.push("AUTO=" + automatic_timezone_label);

                                    var timezonesDict = {}; 
                                    Core.Json.CallProcedure(app.DatabaseNames.System + ".FrontEnd.GetTimezones", null, {
                                        onSuccess: function (data) {
                                            if (data.Table != null && data.Table != undefined) {
                                                for (var i in data.Table) {
                                                    var rowdata = data.Table[i];
                                                    timezonesDict[rowdata.Id.toString().trim()] = rowdata.Name.toString().trim();
                                                    var timezone = rowdata.Id.toString() + "=" + rowdata.Name.toString();
                                                    timezonesData.push(timezone); 
                                                }
                                            }
                                        }
                                        , Async: false
                                    }, app.ConnectionStrings.app);

                                    ctx.timezones = timezonesData.join(";;");
                                    if (app.models.user.get("timezoneIsAutomatic")) {
                                        ctx.detected_timezone = (timezonesDict[app.models.user.get("timezoneCode")]) ? timezonesDict[app.models.user.get("timezoneCode")] : null; 
                                    }

                                    that.model.set({
                                        //disk space
                                        db_total_space: data.DBTotalSpace,
                                        db_total_space_string: that.model.sizeToString(data.DBTotalSpace), 
                                        db_used_space: data.DBUsedSpace,
                                        db_used_space_string: that.model.sizeToString(data.DBUsedSpace), 
                                        db_available_space: data.DBAvailableSpace,
                                        db_available_space_string: that.model.sizeToString(data.DBAvailableSpace),
                                        db_percent_used_space: data.DBPercentUsed,

                                        //tags
                                        tags_used: data.TagsUsed,
                                        tags_percent_used: data.TagsPercentUsed,
                                        tags_licensed: data.TagsLicensed,
                                        tags_configured: data.TagsConfigured,
                                    }); 

                                    //loading the view and appeding it to the views's $el.
                                    var json = that.model.toJSON();
                                    json["licenses"] = that.model.get("licenses").toJSON();

                                    var sw = that.model.get("agentsEnabled").findWhere({ name: "SW" });
                                    var hw = that.model.get("agentsEnabled").findWhere({ name: "HW" });

                                    ctx.sw_enabled = sw.get("status");
                                    ctx.hw_enabled = hw.get("status");

                                    ctx.sw_valid_text = (sw.get("status") ?
                                                            (sw.get("timestamp")
                                                                ? app.translate(that, "agents_valid_until", [sw.get("timestamp")])
                                                                : app.translate(that, "agents_valid_forever")
                                                            ) : app.translate(that, "agents_expired_on", [sw.get("timestamp")]));

                                    ctx.hw_valid_text = (hw.get("status") ?
                                                            (hw.get("timestamp")
                                                                ? app.translate(that, "agents_valid_until", [hw.get("timestamp")])
                                                                : app.translate(that, "agents_valid_forever")
                                                            ) : app.translate(that, "agents_expired_on", [hw.get("timestamp")]));

                                    ctx.sw_key = sw.get("key");
                                    ctx.hw_key = hw.get("key");

                                    that.$el.html(tmp(_.extend(json, ctx)));

                                    that.append(thatContainer); 

                                    setTimeout(function () {
                                        that.$el.find("#circle-progress-tagsinuse").attr('data-progress', parseInt(that.model.get("tags_percent_used")));
                                        that.$el.find("#circle-progress-dbspace").attr('data-progress', parseInt(that.model.get("db_percent_used_space")));
                                    }, 500);

                                },
                                //Async: false
                            }, app.ConnectionStrings.app);
                        },
                        //Async: false
                    }
                    , app.ConnectionStrings.app);
                    //end:

                }, true, customPath);
            }, customPath, "main_template");
        }                

        , 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

                this.options.state = app.view_states.shown; 
                container.append(el);

                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;
            }
        }

        , editUserInfo_edit: function () {
            this.$el.find(".btn-edit-user-info").addClass("hide");
            this.$el.find(".btn-group-edit-section").removeClass("hide"); 

            this.startEdition(this.$el.find(".user-info-section")); 
        }

        , editUserInfo_save: function () {
            var that = this; 

            var data = this.getEditionData(this.$el.find(".user-info-section"));
            for (var i in data.data) data.data[i] = data.data[i].trim();
            for (var i in data.previous) data.previous[i] = data.previous[i].trim();

            var qps = {
                Name: { val: (data.data["name"] != data.previous["name"]) ? data.data["name"] : null , type: "VARCHAR" },
                LastName: { val: (data.data["lastname"] != data.previous["lastname"]) ? data.data["lastname"] : null, type: "VARCHAR" },
                Username: { val: (data.data["username"] != data.previous["username"]) ? data.data["username"] : null, type: "VARCHAR" },
                Timezone: { val: (data.data["timezone"] != data.previous["timezone"]) ? data.data["timezone"] : null, type: "VARCHAR" },
            };

            var QP = new QueryParameters();
            for (var i in qps)
                QP.Add(i, qps[i].type, qps[i].val);

            Core.Json.CallProcedure(app.DatabaseNames.System + ".FrontEnd.UpdateUserInfo", QP, {
                onSuccess: function (data) {
                    if (Core.Object.Eval(data, "Table.0") && data.Table[0].Status == 1) {
                        that.endEdition(that.$el.find(".user-info-section"));
                        that.render(); 
                    } else {
                        new Modal.Views.Main({
                            id: "users-save-changes-error-modal"
                            , title: "Error"
                            , message: "Hubo un error al intentar guardar los cambios. "
                            , allowCancel: false
                            , buttons_type: "OK"
                        }).show();
                    }
                },
                Async: false,
                Secured: true
            }, app.ConnectionStrings.app);

        }

        , editUserInfo_cancel: function () {
            this.$el.find(".btn-group-edit-section").addClass("hide");
            this.$el.find(".btn-edit-user-info").removeClass("hide");

            this.cancelEdition(this.$el.find(".user-info-section")); 
        }

        , startEdition: function (e) {
            var elems = $(e).find("[data-editable]");
            elems.each(function (i, elem) {
                var $elem = $(elem); 
                var datatype = $elem.data("editdatatype"); 

                $elem.addClass("hide hidden-for-edit"); 

                if (datatype == "text") {
                    var inputtext = $("<input style='margin:0;' type='text' data-editname='" + $elem.data("editname") + "' data-buildbyeditable='yes' />");
                    inputtext.val($elem.text());

                    $elem.after(inputtext);
                }

                if (datatype == "select") {
                    var inputselect = $("<select class='selectpicker' style='margin:0;' data-editname='" + $elem.data("editname") + "' data-buildbyeditable='yes' />");
                    var selectoptions = $elem.data("editselectoptions");
                    var selectoptionsvalues = {};
                    selectoptions = selectoptions.split(";;");

                    for (var inx in selectoptions){
                        selectoptionsvalues[selectoptions[inx].split("=")[0]] = selectoptions[inx].split("=")[1]; 
                    }

                    for (var key in selectoptionsvalues) {
                        var isSelected = false;
                        if (key.toUpperCase() == $elem.text().toUpperCase()
                            || selectoptionsvalues[key].toString().toUpperCase() == $elem.text().toUpperCase()) {
                            isSelected = true; 
                        }

                        var option = "<option" + ((isSelected) ? " selected='selected' " : "") + " value='" + key.toString() + "' >" + selectoptionsvalues[key].toString() + "</option>"; 
                        inputselect.append(option);
                    }

                    $elem.after(inputselect);

                    //inputselect.selectpicker({});
                }
            }); 
        }

        , getEditionData: function (e) {
            var elemsBuilt = $(e).find("[data-buildbyeditable]");
            var data = { data: {}, previous: {} };

            elemsBuilt.each(function (i, elem) {
                var $elem = $(elem);
                data.data[$elem.data("editname")] = $elem.val(); 
            });

            var elems = $(e).find("[data-editable]");
            elems.each(function (i, elem) {
                var $elem = $(elem);
                data.previous[$elem.data("editname")] = $elem.text(); 
            }); 

            return data; 
        }

        , endEdition: function (e, newdata) {
            var elemsBuilt = $(e).find("[data-buildbyeditable]");
            var elems = $(e).find("[data-editable]");

            elemsBuilt.remove();
            elems.removeClass("hide hidden-for-edit");
        }

        , cancelEdition: function (e) {
            var elemsBuilt = $(e).find("[data-buildbyeditable]").remove();
            var elems = $(e).find("[data-editable]");
            elems.removeClass("hide hidden-for-edit");
        }

        , changeUserPassword: function (e) {
            var that = this;

            var modal = new Modal.Views.Main({
                id: "change-user-password-modal"
                , title: this.options.i18n[this.template].translate("change_user_password_modal_title").fetch()
                , content: this.$el.find("#modal_change_password").html()
                , allowCancel: true
                , buttons_type: "CONTINUE-CANCEL"
                , okCloses: false
            });

            modal.on("shown", function () {
                this.$el.find(".form-change-password input").jqBootstrapValidation();
            }); 

            modal.on("continue", function () {

                //forcing form validation
                $(".form-change-password").submit(function (e) { e.preventDefault(); }); 
                $(".form-change-password").submit();

                //second check for validation.
                if ($(".form-change-password").jqBootstrapValidation("hasErrors")) {
                    return; 
                }

                var arrData = $(".form-change-password").serializeArray();
                var data = {}; 
                
                for (var i = 0; i < arrData.length; i++) data[arrData[i].name] = arrData[i].value; 

                app.models.user.stop_autofetch(); 
                if (SecurityLogin.Login(app.models.user.get("username"), data["currentpassword"])) {
                    
                    var QP = new QueryParameters();
                    QP.Add("Password", "VARCHAR", data["newpassword"]); 

                    Core.Json.CallProcedure(app.DatabaseNames.System + ".FrontEnd.UpdateUserInfo", QP, {
                        onSuccess: function (data) {
                            if (Core.Object.Eval(data, "Table.0") && data.Table[0].Status == 1) {
                                modal.close();
                                var password_changed = new Modal.Views.Main({
                                    id: "users-save-changes-success-modal"
                                    , title: that.options.i18n[that.template].translate("change_password_modal_success_security_measure_title").fetch()
                                    , message: that.options.i18n[that.template].translate("change_password_modal_success_security_measure").fetch()
                                    , allowCancel: false
                                    , buttons_type: "OK"
                                });

                                password_changed.on("continue", function () {
                                    app.router.logout();
                                }); 
                                
                                password_changed.show(); 
                            } else {
                                modal.close(); 
                                var password_change_failed = new Modal.Views.Main({
                                    id: "users-save-changes-error-modal"
                                    , title: that.options.i18n[that.template].translate("change_password_modal_commit_error_title").fetch()
                                    , message: that.options.i18n[that.template].translate("change_password_modal_commit_error").fetch()
                                    , allowCancel: false
                                    , buttons_type: "OK"
                                });

                                password_change_failed.on("continue", function () {
                                    app.router.logout();
                                });

                                password_change_failed.show(); 
                            }
                        },
                        Async: false,
                        Secured: true
                    }, app.ConnectionStrings.app);

                } else {
                    modal.close(); 

                    var logged_out_modal = new Modal.Views.Main({
                        id: "users-save-changes-error-modal"
                        , title: that.options.i18n[that.template].translate("change_password_modal_wrong_currentpassword_security_measure_title").fetch()
                        , message: that.options.i18n[that.template].translate("change_password_modal_wrong_currentpassword_security_measure").fetch()
                        , allowCancel: false
                        , buttons_type: "OK"
                    });

                    logged_out_modal.on("continue", function () {
                        app.router.logout();
                    });

                    logged_out_modal.show();
                }
            });

            modal.show(); 
        }

        , browseLicense: function () {
            try{
                this.$el.find("#license_fileinput").get(0).click();
            } catch (Error) {
            }
        }

        , licenseChanged: function () {
            var license_form = this.$el.find(".add-license-form");
            var review_license_form = this.$el.find(".review-license-form"); 

            var fileinput = this.$el.find("#license_fileinput").get(0);
            var files = fileinput.files;

            if (files.length > 0) {
                var file = files[0];
                var filename = file.name;

                this.$el.find(".input-license-filename").val(filename);

                license_form.addClass("hide");
                review_license_form.removeClass("hide"); 
            }
        }

        , cancelUploadLicense: function () {
            var license_form = this.$el.find(".add-license-form");
            var review_license_form = this.$el.find(".review-license-form");
            var license_upload_failed = this.$el.find(".license-upload-failed");
            var license_server_logs = this.$el.find(".license-server-logs"); 
            
            var fileinput = this.$el.find("#license_fileinput");
            fileinput.replaceWith(fileinput = fileinput.clone(true));

            review_license_form.addClass("hide"); 
            license_upload_failed.addClass("hide"); 
            license_server_logs.addClass("hide");
            this.$el.find(".license-upload-successful-message, .license-detected-on-server-message, .license-upgrade-process-started, " +
                ".license-upgrade-success-message, .license-upgrade-failed-message").addClass("hide"); 
            license_form.removeClass("hide");
        }

        , uploadLicense: function () {
            try {
                var review_license_form = this.$el.find(".review-license-form");
                var license_upload_progress = this.$el.find(".license-upload-progress"); 

                var that = this; 

                var fileinput = $("#license_fileinput").get(0);
                var files = fileinput.files; 
                var formData = new FormData();

                for (var i = 0; i < files.length; i++) {
                    var file = files[i];

                    // Add the file to the request.
                    formData.append('files[]', file, file.name);
                }

                if (formData) {
                    review_license_form.addClass("hide"); 
                    license_upload_progress.removeClass("hide"); 

                    $.ajax({
                        url: app.foldersRoot + "/app/custom-screens/IHConfiguration/account-information/upload-license.aspx",
                        type: 'POST',
                        // handle the progress report
                        xhr: function () {  // Custom XMLHttpRequest
                            var myXhr = $.ajaxSettings.xhr();
                            if (myXhr.upload) { // Check if upload property exists
                                myXhr.upload.addEventListener('progress', that.uploadLicenseProgressHandler, false); // For handling the progress of the upload
                            }
                            return myXhr;
                        },

                        // Form data
                        data: formData,

                        //Options to tell jQuery not to process data or worry about content-type.
                        cache: false,
                        contentType: false,
                        processData: false
                    })
                    .done(that.uploadLicenseComplete)
                    .fail(that.uploadLicenseFailed);
                }
            } catch (Error) {
            }
        }

        , uploadLicenseComplete: function (data) {
            try {
                var license_upload_progress = this.$el.find(".license-upload-progress");
                license_upload_progress.addClass("hide");
                if (data != null && data != undefined && data.status == "OK") {
                    var license_server_logs = this.$el.find(".license-server-logs"); 
                    license_server_logs.removeClass("hide"); 
                    this.$el.find(".license-upload-successful-message").removeClass("hide"); 

                    this.checkLicenseLogs(data["fileGUID"]); 
                } else {
                    this.uploadLicenseFailed(); 
                }
            } catch (Error) { }
        }

        , checkLicenseTOUT: null
        , checkLicenseLogs: function (guid, sinceDatetime) {
            var that = this; 

            var stages = {
                "upload-success": { message: "license-upload-successful-message" },
                "upgrade-detected": { message: "license-detected-on-server-message", keys: ["upgrade file", "detected"] },
                "upgrade-started": { message: "license-upgrade-process-started", keys: ["license upgrade process started"] },
                "upgrade-success": { message: "license-upgrade-success-message", keys: ["license upgraded succesfully"] },
                "upgrade-failed": { message: "license-upgrade-failed-message", keys: ["error", "is not defined"] }, 
            };
            
            function setStage(stageName) {
                for (var t in stages) {
                    $("." + stages[t].message).addClass("hide"); 
                }

                //if (stageName == null || stageName == undefined || !stages[stageName]) stageName = "upgrade-failed"; 

                if (stageName != null && stageName != undefined && stages[stageName])
                    $("." + stages[stageName].message).removeClass("hide"); 
            }

            if (sinceDatetime == null || sinceDatetime == undefined) {
                app.models.navBarClock.syncWithServer({ async: false });
                sinceDatetime = Core.DateTime.ToString(app.models.navBarClock.get("date"), "yyyy-mm-dd HH:MM:ss");
            }

            var QP = new QueryParameters(); 
            QP.Add("LicenseGUID", "VARCHAR", guid);
            QP.Add("Timezone", "CHAR", app.models.user.get("timezoneCode"));
            QP.Add("SinceDatetime", "DATETIME", sinceDatetime); 

            if (!this.checkLicenseTOUT) {
                this.checkLicenseTOUT = setTimeout(function () {
                    that.checkLicenseTOUT = null;
                    setStage("upgrade-failed"); 
                }, (1000 * 60));
            }

            Core.Json.CallProcedure(app.DatabaseNames.System + ".FrontEnd.GetLicenseLogs", QP, {
                onSuccess: function (data) {
                    if (data && data.Table) {
                        data = data.Table;
                        var foundStage = false; 
                        var stageName = null; 
                        for (var i = 0; i < data.length; i++) {
                            var rowdata = data[i]; 
                            for (var t in stages) {
                                var stageKeys = stages[t].keys;
                                for (var key in stageKeys) {
                                    if (rowdata.Description.toUpperCase().indexOf(stageKeys[key].toUpperCase()) != -1)
                                        foundStage = true; 
                                }
                                if (foundStage){
                                    stageName = t; 
                                    break; 
                                }
                            }
                            if (foundStage) break; 
                        }

                        if (stageName)
                            setTimeout(setStage(stageName), 1500);

                        if (stageName != "upgrade-success" && stageName != "upgrade-failed") {
                            if (that.checkLicenseTOUT != null)
                                setTimeout(that.checkLicenseLogs(guid, sinceDatetime), 1000);
                        } else {
                            if (that.checkLicenseTOUT != null) {
                                clearTimeout(that.checkLicenseTOUT);
                                that.checkLicenseTOUT = null;
                            }

                            if (stageName == "upgrade-success") {
                                setTimeout(that.render, 2000); 
                            }
                        }
                    }
                }
                , onFailure: function () {

                }
            }, app.ConnectionStrings.app); 
        }

        , uploadLicenseFailed: function (e) {
            try {
                var license_upload_progress = this.$el.find(".license-upload-progress");
                var license_upload_failed = this.$el.find(".license-upload-failed");

                license_upload_progress.addClass("hide");
                license_upload_failed.removeClass("show"); 
            } catch (Error) { }
        }

        , uploadLicenseProgressHandler: function (e) {
            var upload_progress_bar = this.$el.find(".license-upload-progress-bar");
            var loaded = e.loaded;
            var total = e.total;

            var percent = (loaded * 100) / total; 
            upload_progress_bar.css("width", percent + "%"); 
        }

        , refresh: function () {
            try {
                this.render(); 
            } catch (Error) { }
        }

        , 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
        }

        , bindViewScopedEvents: function () {

        }

        , unbindViewScopedEvents: function () {

        }

        , close: function () {
            this.options.state = app.view_states.closed;

            this.closeSubviews(); 
            this.remove();
            this.unbindViewScopedEvents();
            this.unbind();
        }

        , closeSubviews: function () {
            _.each(this.options.MYREFERENCES.subviews, function (sview) {
                sview.close();
            });
        }

        , show: function () {
            this.options.state = app.view_states.shown; 

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

        , showSubviews: function () {
            _.each(this.options.MYREFERENCES.subviews, function (sview) {
                sview.show();
            });
        }

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

            this.hideSubviews();

            this.$el.hide();
            this.unbind();
            this.stopListening();
        }

        , hideSubviews: function () {
            _.each(this.options.MYREFERENCES.subviews, function (sview) {
                sview.hide();
            });
        }

        , preRender: function () {
            app.models.subnavbar.set("dateControl", false);
            app.models.subnavbar.set("subnavbar", false);
        }

        , reRender: function () {
        }
    });

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

});

